diff options
author | Edward Thomson <ethomson@github.com> | 2022-02-11 18:00:11 -0500 |
---|---|---|
committer | Edward Thomson <ethomson@github.com> | 2022-02-11 18:00:11 -0500 |
commit | 458547bd397473fd7664484510a075c18a7b55ab (patch) | |
tree | 0bafd5184e04a49a68149fc80eb66270f0935273 | |
parent | e651cb1463b971e67eeed0ae2a7c75fb8c547bcc (diff) | |
download | libgit2-458547bd397473fd7664484510a075c18a7b55ab.tar.gz |
diff: provide a flag for whether size is known
Much like we may produce diffs that do not have valid object IDs because
we don't know them (yet), we may also produce diffs that do not have
valid sizes. Previously, we used a `0` size to indicate unknown, but
this is obviously deficient since we could _know_ that a file is 0
bytes.
Create a new flag that indicates that we positively know the size of the
file.
-rw-r--r-- | include/git2/diff.h | 3 | ||||
-rw-r--r-- | src/diff_generate.c | 24 | ||||
-rw-r--r-- | src/diff_generate.h | 4 | ||||
-rw-r--r-- | src/diff_tform.c | 3 | ||||
-rw-r--r-- | src/oid.h | 3 |
5 files changed, 34 insertions, 3 deletions
diff --git a/include/git2/diff.h b/include/git2/diff.h index 9424ffd06..3839f0033 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -207,7 +207,8 @@ typedef enum { GIT_DIFF_FLAG_BINARY = (1u << 0), /**< file(s) treated as binary data */ GIT_DIFF_FLAG_NOT_BINARY = (1u << 1), /**< file(s) treated as text data */ GIT_DIFF_FLAG_VALID_ID = (1u << 2), /**< `id` value is known correct */ - GIT_DIFF_FLAG_EXISTS = (1u << 3) /**< file exists at this side of the delta */ + GIT_DIFF_FLAG_EXISTS = (1u << 3), /**< file exists at this side of the delta */ + GIT_DIFF_FLAG_VALID_SIZE = (1u << 4) /**< file size value is known correct */ } git_diff_flag_t; /** diff --git a/src/diff_generate.c b/src/diff_generate.c index dca16d51a..cfaefba66 100644 --- a/src/diff_generate.c +++ b/src/diff_generate.c @@ -117,6 +117,26 @@ static bool diff_pathspec_match( matched_pathspec, NULL); } +static void diff_delta__flag_known_size(git_diff_file *file) +{ + /* + * If we don't know the ID, that can only come from the workdir + * iterator, which means we *do* know the file size. This is a + * leaky abstraction, but alas. Otherwise, we test against the + * empty blob id. + */ + if (file->size || + !(file->flags & GIT_DIFF_FLAG_VALID_ID) || + git_oid_equal(&file->id, &git_oid__empty_blob_sha1)) + file->flags |= GIT_DIFF_FLAG_VALID_SIZE; +} + +static void diff_delta__flag_known_sizes(git_diff_delta *delta) +{ + diff_delta__flag_known_size(&delta->old_file); + diff_delta__flag_known_size(&delta->new_file); +} + static int diff_delta__from_one( git_diff_generated *diff, git_delta_t status, @@ -182,6 +202,8 @@ static int diff_delta__from_one( if (has_old || !git_oid_is_zero(&delta->new_file.id)) delta->new_file.flags |= GIT_DIFF_FLAG_VALID_ID; + diff_delta__flag_known_sizes(delta); + return diff_insert_delta(diff, delta, matched_pathspec); } @@ -244,6 +266,8 @@ static int diff_delta__from_two( delta->new_file.flags |= GIT_DIFF_FLAG_VALID_ID; } + diff_delta__flag_known_sizes(delta); + return diff_insert_delta(diff, delta, matched_pathspec); } diff --git a/src/diff_generate.h b/src/diff_generate.h index f39bf6b2a..b782f29c6 100644 --- a/src/diff_generate.h +++ b/src/diff_generate.h @@ -119,8 +119,10 @@ GIT_INLINE(int) git_diff_file__resolve_zero_size( git_odb_free(odb); - if (!error) + if (!error) { file->size = (git_object_size_t)len; + file->flags |= GIT_DIFF_FLAG_VALID_SIZE; + } return error; } diff --git a/src/diff_tform.c b/src/diff_tform.c index f9836d245..913d649b0 100644 --- a/src/diff_tform.c +++ b/src/diff_tform.c @@ -460,7 +460,8 @@ static int similarity_init( info->blob = NULL; git_str_init(&info->data, 0); - if (info->file->size > 0 || info->src == GIT_ITERATOR_WORKDIR) + if ((info->file->flags & GIT_DIFF_FLAG_VALID_SIZE) || + info->src == GIT_ITERATOR_WORKDIR) return 0; return git_diff_file__resolve_zero_size( @@ -11,6 +11,9 @@ #include "git2/oid.h" +static git_oid git_oid__empty_blob_sha1 = + {{ 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, + 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 }}; static git_oid git_oid__empty_tree_sha1 = {{ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }}; |