Skip to content

Commit 359240b

Browse files
Edward Thomsonethomson
authored andcommitted
diff: indicate when the file size is "valid"
When we know the file size (because we're producing it from a working directory iterator, or an index with an up-to-date cache) then set a flag indicating as such. This removes the ambiguity about a 0 file size, which could indicate that a file exists and is 0 bytes, or that we haven't read it yet.
1 parent e86e81c commit 359240b

File tree

7 files changed

+37
-7
lines changed

7 files changed

+37
-7
lines changed

include/git2/diff.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,8 @@ typedef enum {
207207
GIT_DIFF_FLAG_BINARY = (1u << 0), /**< file(s) treated as binary data */
208208
GIT_DIFF_FLAG_NOT_BINARY = (1u << 1), /**< file(s) treated as text data */
209209
GIT_DIFF_FLAG_VALID_ID = (1u << 2), /**< `id` value is known correct */
210-
GIT_DIFF_FLAG_EXISTS = (1u << 3) /**< file exists at this side of the delta */
210+
GIT_DIFF_FLAG_EXISTS = (1u << 3), /**< file exists at this side of the delta */
211+
GIT_DIFF_FLAG_VALID_SIZE = (1u << 4) /**< file size value is known correct */
211212
} git_diff_flag_t;
212213

213214
/**

src/diff_generate.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,26 @@ static bool diff_pathspec_match(
117117
matched_pathspec, NULL);
118118
}
119119

120+
static void diff_delta__flag_known_size(git_diff_file *file)
121+
{
122+
/*
123+
* If we don't know the ID, that can only come from the workdir
124+
* iterator, which means we *do* know the file size. This is a
125+
* leaky abstraction, but alas. Otherwise, we test against the
126+
* empty blob id.
127+
*/
128+
if (file->size ||
129+
!(file->flags & GIT_DIFF_FLAG_VALID_ID) ||
130+
git_oid_equal(&file->id, &git_oid__empty_blob_sha1))
131+
file->flags |= GIT_DIFF_FLAG_VALID_SIZE;
132+
}
133+
134+
static void diff_delta__flag_known_sizes(git_diff_delta *delta)
135+
{
136+
diff_delta__flag_known_size(&delta->old_file);
137+
diff_delta__flag_known_size(&delta->new_file);
138+
}
139+
120140
static int diff_delta__from_one(
121141
git_diff_generated *diff,
122142
git_delta_t status,
@@ -182,6 +202,8 @@ static int diff_delta__from_one(
182202
if (has_old || !git_oid_is_zero(&delta->new_file.id))
183203
delta->new_file.flags |= GIT_DIFF_FLAG_VALID_ID;
184204

205+
diff_delta__flag_known_sizes(delta);
206+
185207
return diff_insert_delta(diff, delta, matched_pathspec);
186208
}
187209

@@ -244,6 +266,8 @@ static int diff_delta__from_two(
244266
delta->new_file.flags |= GIT_DIFF_FLAG_VALID_ID;
245267
}
246268

269+
diff_delta__flag_known_sizes(delta);
270+
247271
return diff_insert_delta(diff, delta, matched_pathspec);
248272
}
249273

src/diff_generate.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,10 @@ GIT_INLINE(int) git_diff_file__resolve_zero_size(
119119

120120
git_odb_free(odb);
121121

122-
if (!error)
122+
if (!error) {
123123
file->size = (git_object_size_t)len;
124+
file->flags |= GIT_DIFF_FLAG_VALID_SIZE;
125+
}
124126

125127
return error;
126128
}

src/diff_tform.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,8 @@ static int similarity_init(
460460
info->blob = NULL;
461461
git_str_init(&info->data, 0);
462462

463-
if (info->file->size > 0 || info->src == GIT_ITERATOR_WORKDIR)
463+
if ((info->file->flags & GIT_DIFF_FLAG_VALID_SIZE) ||
464+
info->src == GIT_ITERATOR_WORKDIR)
464465
return 0;
465466

466467
return git_diff_file__resolve_zero_size(

src/odb.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "filter.h"
1717
#include "repository.h"
1818
#include "blob.h"
19+
#include "oid.h"
1920

2021
#include "git2/odb_backend.h"
2122
#include "git2/oid.h"
@@ -58,10 +59,7 @@ static int error_null_oid(int error, const char *message);
5859

5960
static git_object_t odb_hardcoded_type(const git_oid *id)
6061
{
61-
static git_oid empty_tree = {{ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
62-
0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }};
63-
64-
if (!git_oid_cmp(id, &empty_tree))
62+
if (!git_oid_cmp(id, &git_oid__empty_tree_sha1))
6563
return GIT_OBJECT_TREE;
6664

6765
return GIT_OBJECT_INVALID;

src/oid.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
#include <string.h>
1414
#include <limits.h>
1515

16+
const git_oid git_oid__empty_blob_sha1 =
17+
{{ 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b,
18+
0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 }};
1619
const git_oid git_oid__empty_tree_sha1 =
1720
{{ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
1821
0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }};

src/oid.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "git2/oid.h"
1313

14+
extern const git_oid git_oid__empty_blob_sha1;
1415
extern const git_oid git_oid__empty_tree_sha1;
1516

1617
/**

0 commit comments

Comments
 (0)