Skip to content

Commit a37ce5c

Browse files
committed
Fix parsing of git ls-tree for submodules
Closes #1282
1 parent e314418 commit a37ce5c

File tree

3 files changed

+41
-22
lines changed

3 files changed

+41
-22
lines changed

NEWS.adoc

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Bug fixes:
3333
- Fix status view lockup.
3434
- Fix untracked changes and chunk staging behaviour in plain stage view.
3535
- Reset state variables when selecting a commit with no reference.
36+
- Fix parsing of `git ls-tree` for submodules. (#1282)
3637

3738
tig-2.5.8
3839
---------

src/draw.c

+5-6
Original file line numberDiff line numberDiff line change
@@ -276,11 +276,10 @@ draw_id(struct view *view, struct view_column *column, const char *id)
276276
}
277277

278278
static bool
279-
draw_filename(struct view *view, struct view_column *column, const char *filename, mode_t mode)
279+
draw_filename(struct view *view, struct view_column *column, enum line_type type, const char *filename)
280280
{
281281
size_t width = filename ? utf8_width(filename) : 0;
282282
bool trim = width >= column->width;
283-
enum line_type type = S_ISDIR(mode) ? LINE_DIRECTORY : LINE_FILE;
284283
int column_width = column->width ? column->width : width;
285284

286285
if (column->opt.file_name.display == FILENAME_NO)
@@ -290,9 +289,9 @@ draw_filename(struct view *view, struct view_column *column, const char *filenam
290289
}
291290

292291
static bool
293-
draw_file_size(struct view *view, struct view_column *column, unsigned long size, mode_t mode)
292+
draw_file_size(struct view *view, struct view_column *column, enum line_type type, unsigned long size)
294293
{
295-
const char *str = S_ISDIR(mode) ? NULL : mkfilesize(size, column->opt.file_size.display);
294+
const char *str = type == LINE_FILE ? mkfilesize(size, column->opt.file_size.display) : NULL;
296295

297296
if (!column->width || column->opt.file_size.display == FILE_SIZE_NO)
298297
return false;
@@ -518,7 +517,7 @@ view_column_draw(struct view *view, struct line *line, unsigned int lineno)
518517
continue;
519518

520519
case VIEW_COLUMN_FILE_SIZE:
521-
if (draw_file_size(view, column, column_data.file_size ? *column_data.file_size : 0, mode))
520+
if (draw_file_size(view, column, line->type, column_data.file_size ? *column_data.file_size : 0))
522521
return true;
523522
continue;
524523

@@ -529,7 +528,7 @@ view_column_draw(struct view *view, struct line *line, unsigned int lineno)
529528
continue;
530529

531530
case VIEW_COLUMN_FILE_NAME:
532-
if (draw_filename(view, column, column_data.file_name, mode))
531+
if (draw_filename(view, column, line->type, column_data.file_name))
533532
return true;
534533
continue;
535534

src/tree.c

+35-16
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,6 @@ push_tree_stack_entry(struct view *view, const char *name, struct position *posi
5757
* 100644 blob 95925677ca47beb0b8cce7c0e0011bcc3f61470f 213045 tig.c
5858
*/
5959

60-
#define SIZEOF_TREE_ATTR \
61-
STRING_SIZE("100644 blob f931e1d229c3e185caad4449bf5b66ed72462657\t")
62-
63-
#define SIZEOF_TREE_MODE \
64-
STRING_SIZE("100644 ")
65-
66-
#define TREE_ID_OFFSET \
67-
STRING_SIZE("100644 blob ")
68-
6960
#define tree_path_is_parent(path) (!strcmp("..", (path)))
7061

7162
struct tree_entry {
@@ -222,21 +213,50 @@ tree_read(struct view *view, struct buffer *buf, bool force_stop)
222213
struct tree_entry *data;
223214
struct line *entry, *line;
224215
enum line_type type;
216+
char *pos;
217+
char *mode;
218+
char *id;
225219
char *path;
226220
size_t size;
227221

228222
if (state->read_date || !buf)
229223
return tree_read_date(view, buf, state);
230224

231-
if (buf->size <= SIZEOF_TREE_ATTR)
232-
return false;
233225
if (view->lines == 0 &&
234226
!tree_entry(view, LINE_HEADER, view->env->directory, NULL, NULL, 0))
235227
return false;
236228

237-
size = parse_size(buf->data + SIZEOF_TREE_ATTR);
238-
path = strchr(buf->data + SIZEOF_TREE_ATTR, '\t');
239-
if (!path)
229+
/* 100644 */
230+
mode = buf->data;
231+
232+
/* blob */
233+
pos = strchr(mode, ' ');
234+
if (!pos || !*pos)
235+
return false;
236+
pos++;
237+
if (!strncmp(pos, "blob", STRING_SIZE("blob")))
238+
type = LINE_FILE;
239+
else if (!strncmp(pos, "tree", STRING_SIZE("tree")))
240+
type = LINE_DIRECTORY;
241+
else
242+
type = LINE_DEFAULT;
243+
244+
/* 95925677ca47beb0b8cce7c0e0011bcc3f61470f */
245+
id = strchr(pos, ' ');
246+
if (!id || !*id)
247+
return false;
248+
id++;
249+
250+
/* 213045 */
251+
pos = strchr(id, ' ');
252+
if (!pos || !*pos)
253+
return false;
254+
pos++;
255+
size = parse_size(pos);
256+
257+
/* tig.c */
258+
path = strchr(pos, '\t');
259+
if (!path || !*path)
240260
return false;
241261
path++;
242262

@@ -255,8 +275,7 @@ tree_read(struct view *view, struct buffer *buf, bool force_stop)
255275
return false;
256276
}
257277

258-
type = buf->data[SIZEOF_TREE_MODE] == 't' ? LINE_DIRECTORY : LINE_FILE;
259-
entry = tree_entry(view, type, path, buf->data, buf->data + TREE_ID_OFFSET, size);
278+
entry = tree_entry(view, type, path, mode, id, size);
260279
if (!entry)
261280
return false;
262281
data = entry->data;

0 commit comments

Comments
 (0)