summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Koutcher <thomas.koutcher@online.fr>2024-03-28 19:00:54 +0100
committerThomas Koutcher <thomas.koutcher@online.fr>2024-03-28 19:00:54 +0100
commita37ce5cfe1f256b81092dda365b1d66450e0929e (patch)
treed083eba7b2a7f78137c3f74c3ec953775a11d9bd
parente31441834c6eac3af4e2dc20c68626b3a77bdb54 (diff)
Fix parsing of `git ls-tree` for submodules
Closes #1282
-rw-r--r--NEWS.adoc1
-rw-r--r--src/draw.c11
-rw-r--r--src/tree.c51
3 files changed, 41 insertions, 22 deletions
diff --git a/NEWS.adoc b/NEWS.adoc
index 6a8b03c4..9fbc0461 100644
--- a/NEWS.adoc
+++ b/NEWS.adoc
@@ -33,6 +33,7 @@ Bug fixes:
- Fix status view lockup.
- Fix untracked changes and chunk staging behaviour in plain stage view.
- Reset state variables when selecting a commit with no reference.
+ - Fix parsing of `git ls-tree` for submodules. (#1282)
tig-2.5.8
---------
diff --git a/src/draw.c b/src/draw.c
index a9ded13e..c2befa47 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -276,11 +276,10 @@ draw_id(struct view *view, struct view_column *column, const char *id)
}
static bool
-draw_filename(struct view *view, struct view_column *column, const char *filename, mode_t mode)
+draw_filename(struct view *view, struct view_column *column, enum line_type type, const char *filename)
{
size_t width = filename ? utf8_width(filename) : 0;
bool trim = width >= column->width;
- enum line_type type = S_ISDIR(mode) ? LINE_DIRECTORY : LINE_FILE;
int column_width = column->width ? column->width : width;
if (column->opt.file_name.display == FILENAME_NO)
@@ -290,9 +289,9 @@ draw_filename(struct view *view, struct view_column *column, const char *filenam
}
static bool
-draw_file_size(struct view *view, struct view_column *column, unsigned long size, mode_t mode)
+draw_file_size(struct view *view, struct view_column *column, enum line_type type, unsigned long size)
{
- const char *str = S_ISDIR(mode) ? NULL : mkfilesize(size, column->opt.file_size.display);
+ const char *str = type == LINE_FILE ? mkfilesize(size, column->opt.file_size.display) : NULL;
if (!column->width || column->opt.file_size.display == FILE_SIZE_NO)
return false;
@@ -518,7 +517,7 @@ view_column_draw(struct view *view, struct line *line, unsigned int lineno)
continue;
case VIEW_COLUMN_FILE_SIZE:
- if (draw_file_size(view, column, column_data.file_size ? *column_data.file_size : 0, mode))
+ if (draw_file_size(view, column, line->type, column_data.file_size ? *column_data.file_size : 0))
return true;
continue;
@@ -529,7 +528,7 @@ view_column_draw(struct view *view, struct line *line, unsigned int lineno)
continue;
case VIEW_COLUMN_FILE_NAME:
- if (draw_filename(view, column, column_data.file_name, mode))
+ if (draw_filename(view, column, line->type, column_data.file_name))
return true;
continue;
diff --git a/src/tree.c b/src/tree.c
index 7dc894d9..e6c826f1 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -57,15 +57,6 @@ push_tree_stack_entry(struct view *view, const char *name, struct position *posi
* 100644 blob 95925677ca47beb0b8cce7c0e0011bcc3f61470f 213045 tig.c
*/
-#define SIZEOF_TREE_ATTR \
- STRING_SIZE("100644 blob f931e1d229c3e185caad4449bf5b66ed72462657\t")
-
-#define SIZEOF_TREE_MODE \
- STRING_SIZE("100644 ")
-
-#define TREE_ID_OFFSET \
- STRING_SIZE("100644 blob ")
-
#define tree_path_is_parent(path) (!strcmp("..", (path)))
struct tree_entry {
@@ -222,21 +213,50 @@ tree_read(struct view *view, struct buffer *buf, bool force_stop)
struct tree_entry *data;
struct line *entry, *line;
enum line_type type;
+ char *pos;
+ char *mode;
+ char *id;
char *path;
size_t size;
if (state->read_date || !buf)
return tree_read_date(view, buf, state);
- if (buf->size <= SIZEOF_TREE_ATTR)
- return false;
if (view->lines == 0 &&
!tree_entry(view, LINE_HEADER, view->env->directory, NULL, NULL, 0))
return false;
- size = parse_size(buf->data + SIZEOF_TREE_ATTR);
- path = strchr(buf->data + SIZEOF_TREE_ATTR, '\t');
- if (!path)
+ /* 100644 */
+ mode = buf->data;
+
+ /* blob */
+ pos = strchr(mode, ' ');
+ if (!pos || !*pos)
+ return false;
+ pos++;
+ if (!strncmp(pos, "blob", STRING_SIZE("blob")))
+ type = LINE_FILE;
+ else if (!strncmp(pos, "tree", STRING_SIZE("tree")))
+ type = LINE_DIRECTORY;
+ else
+ type = LINE_DEFAULT;
+
+ /* 95925677ca47beb0b8cce7c0e0011bcc3f61470f */
+ id = strchr(pos, ' ');
+ if (!id || !*id)
+ return false;
+ id++;
+
+ /* 213045 */
+ pos = strchr(id, ' ');
+ if (!pos || !*pos)
+ return false;
+ pos++;
+ size = parse_size(pos);
+
+ /* tig.c */
+ path = strchr(pos, '\t');
+ if (!path || !*path)
return false;
path++;
@@ -255,8 +275,7 @@ tree_read(struct view *view, struct buffer *buf, bool force_stop)
return false;
}
- type = buf->data[SIZEOF_TREE_MODE] == 't' ? LINE_DIRECTORY : LINE_FILE;
- entry = tree_entry(view, type, path, buf->data, buf->data + TREE_ID_OFFSET, size);
+ entry = tree_entry(view, type, path, mode, id, size);
if (!entry)
return false;
data = entry->data;