Skip to content

Commit

Permalink
Merge branch 'jk/maint-null-in-trees'
Browse files Browse the repository at this point in the history
We do not want a link to 0{40} object stored anywhere in our objects.

* jk/maint-null-in-trees:
  fsck: detect null sha1 in tree entries
  do not write null sha1s to on-disk index
  diff: do not use null sha1 as a sentinel value
  • Loading branch information
gitster committed Aug 27, 2012
2 parents b9148c3 + c479d14 commit 3b75314
Show file tree
Hide file tree
Showing 18 changed files with 188 additions and 32 deletions.
2 changes: 1 addition & 1 deletion builtin.h
Expand Up @@ -43,7 +43,7 @@ extern int check_pager_config(const char *cmd);
struct diff_options;
extern void setup_diff_pager(struct diff_options *);

extern int textconv_object(const char *path, unsigned mode, const unsigned char *sha1, char **buf, unsigned long *buf_size);
extern int textconv_object(const char *path, unsigned mode, const unsigned char *sha1, int sha1_valid, char **buf, unsigned long *buf_size);

extern int cmd_add(int argc, const char **argv, const char *prefix);
extern int cmd_annotate(int argc, const char **argv, const char *prefix);
Expand Down
9 changes: 5 additions & 4 deletions builtin/blame.c
Expand Up @@ -110,14 +110,15 @@ static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b, long ctxlen,
int textconv_object(const char *path,
unsigned mode,
const unsigned char *sha1,
int sha1_valid,
char **buf,
unsigned long *buf_size)
{
struct diff_filespec *df;
struct userdiff_driver *textconv;

df = alloc_filespec(path);
fill_filespec(df, sha1, mode);
fill_filespec(df, sha1, sha1_valid, mode);
textconv = get_textconv(df);
if (!textconv) {
free_filespec(df);
Expand All @@ -142,7 +143,7 @@ static void fill_origin_blob(struct diff_options *opt,

num_read_blob++;
if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) &&
textconv_object(o->path, o->mode, o->blob_sha1, &file->ptr, &file_size))
textconv_object(o->path, o->mode, o->blob_sha1, 1, &file->ptr, &file_size))
;
else
file->ptr = read_sha1_file(o->blob_sha1, &type, &file_size);
Expand Down Expand Up @@ -2120,7 +2121,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
switch (st.st_mode & S_IFMT) {
case S_IFREG:
if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) &&
textconv_object(read_from, mode, null_sha1, &buf_ptr, &buf_len))
textconv_object(read_from, mode, null_sha1, 0, &buf_ptr, &buf_len))
strbuf_attach(&buf, buf_ptr, buf_len, buf_len + 1);
else if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)
die_errno("cannot open or read '%s'", read_from);
Expand Down Expand Up @@ -2513,7 +2514,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
die("no such path %s in %s", path, final_commit_name);

if (DIFF_OPT_TST(&sb.revs->diffopt, ALLOW_TEXTCONV) &&
textconv_object(path, o->mode, o->blob_sha1, (char **) &sb.final_buf,
textconv_object(path, o->mode, o->blob_sha1, 1, (char **) &sb.final_buf,
&sb.final_buf_size))
;
else
Expand Down
2 changes: 1 addition & 1 deletion builtin/cat-file.c
Expand Up @@ -146,7 +146,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name)
die("git cat-file --textconv %s: <object> must be <sha1:path>",
obj_name);

if (!textconv_object(obj_context.path, obj_context.mode, sha1, &buf, &size))
if (!textconv_object(obj_context.path, obj_context.mode, sha1, 1, &buf, &size))
die("git cat-file --textconv: unable to run textconv on %s",
obj_name);
break;
Expand Down
8 changes: 6 additions & 2 deletions builtin/diff.c
Expand Up @@ -29,6 +29,8 @@ static void stuff_change(struct diff_options *opt,
unsigned old_mode, unsigned new_mode,
const unsigned char *old_sha1,
const unsigned char *new_sha1,
int old_sha1_valid,
int new_sha1_valid,
const char *old_name,
const char *new_name)
{
Expand All @@ -54,8 +56,8 @@ static void stuff_change(struct diff_options *opt,

one = alloc_filespec(old_name);
two = alloc_filespec(new_name);
fill_filespec(one, old_sha1, old_mode);
fill_filespec(two, new_sha1, new_mode);
fill_filespec(one, old_sha1, old_sha1_valid, old_mode);
fill_filespec(two, new_sha1, new_sha1_valid, new_mode);

diff_queue(&diff_queued_diff, one, two);
}
Expand Down Expand Up @@ -84,6 +86,7 @@ static int builtin_diff_b_f(struct rev_info *revs,
stuff_change(&revs->diffopt,
blob[0].mode, canon_mode(st.st_mode),
blob[0].sha1, null_sha1,
1, 0,
path, path);
diffcore_std(&revs->diffopt);
diff_flush(&revs->diffopt);
Expand All @@ -108,6 +111,7 @@ static int builtin_diff_blobs(struct rev_info *revs,
stuff_change(&revs->diffopt,
blob[0].mode, blob[1].mode,
blob[0].sha1, blob[1].sha1,
1, 1,
blob[0].name, blob[1].name);
diffcore_std(&revs->diffopt);
diff_flush(&revs->diffopt);
Expand Down
4 changes: 2 additions & 2 deletions combine-diff.c
Expand Up @@ -111,7 +111,7 @@ static char *grab_blob(const unsigned char *sha1, unsigned int mode,
return xcalloc(1, 1);
} else if (textconv) {
struct diff_filespec *df = alloc_filespec(path);
fill_filespec(df, sha1, mode);
fill_filespec(df, sha1, 1, mode);
*size = fill_textconv(textconv, df, &blob);
free_filespec(df);
} else {
Expand Down Expand Up @@ -823,7 +823,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
&result_size, NULL, NULL);
} else if (textconv) {
struct diff_filespec *df = alloc_filespec(elem->path);
fill_filespec(df, null_sha1, st.st_mode);
fill_filespec(df, null_sha1, 0, st.st_mode);
result_size = fill_textconv(textconv, df, &result);
free_filespec(df);
} else if (0 <= (fd = open(elem->path, O_RDONLY))) {
Expand Down
20 changes: 12 additions & 8 deletions diff-lib.c
Expand Up @@ -206,7 +206,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
if (silent_on_removed)
continue;
diff_addremove(&revs->diffopt, '-', ce->ce_mode,
ce->sha1, ce->name, 0);
ce->sha1, !is_null_sha1(ce->sha1),
ce->name, 0);
continue;
}
changed = match_stat_with_submodule(&revs->diffopt, ce, &st,
Expand All @@ -220,6 +221,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
newmode = ce_mode_from_stat(ce, st.st_mode);
diff_change(&revs->diffopt, oldmode, newmode,
ce->sha1, (changed ? null_sha1 : ce->sha1),
!is_null_sha1(ce->sha1), (changed ? 0 : !is_null_sha1(ce->sha1)),
ce->name, 0, dirty_submodule);

}
Expand All @@ -236,11 +238,12 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
static void diff_index_show_file(struct rev_info *revs,
const char *prefix,
struct cache_entry *ce,
const unsigned char *sha1, unsigned int mode,
const unsigned char *sha1, int sha1_valid,
unsigned int mode,
unsigned dirty_submodule)
{
diff_addremove(&revs->diffopt, prefix[0], mode,
sha1, ce->name, dirty_submodule);
sha1, sha1_valid, ce->name, dirty_submodule);
}

static int get_stat_data(struct cache_entry *ce,
Expand Down Expand Up @@ -295,7 +298,7 @@ static void show_new_file(struct rev_info *revs,
&dirty_submodule, &revs->diffopt) < 0)
return;

diff_index_show_file(revs, "+", new, sha1, mode, dirty_submodule);
diff_index_show_file(revs, "+", new, sha1, !is_null_sha1(sha1), mode, dirty_submodule);
}

static int show_modified(struct rev_info *revs,
Expand All @@ -312,7 +315,7 @@ static int show_modified(struct rev_info *revs,
&dirty_submodule, &revs->diffopt) < 0) {
if (report_missing)
diff_index_show_file(revs, "-", old,
old->sha1, old->ce_mode, 0);
old->sha1, 1, old->ce_mode, 0);
return -1;
}

Expand Down Expand Up @@ -347,7 +350,8 @@ static int show_modified(struct rev_info *revs,
return 0;

diff_change(&revs->diffopt, oldmode, mode,
old->sha1, sha1, old->name, 0, dirty_submodule);
old->sha1, sha1, 1, !is_null_sha1(sha1),
old->name, 0, dirty_submodule);
return 0;
}

Expand Down Expand Up @@ -380,7 +384,7 @@ static void do_oneway_diff(struct unpack_trees_options *o,
struct diff_filepair *pair;
pair = diff_unmerge(&revs->diffopt, idx->name);
if (tree)
fill_filespec(pair->one, tree->sha1, tree->ce_mode);
fill_filespec(pair->one, tree->sha1, 1, tree->ce_mode);
return;
}

Expand All @@ -396,7 +400,7 @@ static void do_oneway_diff(struct unpack_trees_options *o,
* Something removed from the tree?
*/
if (!idx) {
diff_index_show_file(revs, "-", tree, tree->sha1, tree->ce_mode, 0);
diff_index_show_file(revs, "-", tree, tree->sha1, 1, tree->ce_mode, 0);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion diff-no-index.c
Expand Up @@ -82,7 +82,7 @@ static struct diff_filespec *noindex_filespec(const char *name, int mode)
if (!name)
name = "/dev/null";
s = alloc_filespec(name);
fill_filespec(s, null_sha1, mode);
fill_filespec(s, null_sha1, 0, mode);
if (name == file_from_standard_input)
populate_from_stdin(s);
return s;
Expand Down
16 changes: 10 additions & 6 deletions diff.c
Expand Up @@ -2541,12 +2541,12 @@ void free_filespec(struct diff_filespec *spec)
}

void fill_filespec(struct diff_filespec *spec, const unsigned char *sha1,
unsigned short mode)
int sha1_valid, unsigned short mode)
{
if (mode) {
spec->mode = canon_mode(mode);
hashcpy(spec->sha1, sha1);
spec->sha1_valid = !is_null_sha1(sha1);
spec->sha1_valid = sha1_valid;
}
}

Expand Down Expand Up @@ -4691,6 +4691,7 @@ static int is_submodule_ignored(const char *path, struct diff_options *options)
void diff_addremove(struct diff_options *options,
int addremove, unsigned mode,
const unsigned char *sha1,
int sha1_valid,
const char *concatpath, unsigned dirty_submodule)
{
struct diff_filespec *one, *two;
Expand Down Expand Up @@ -4722,9 +4723,9 @@ void diff_addremove(struct diff_options *options,
two = alloc_filespec(concatpath);

if (addremove != '+')
fill_filespec(one, sha1, mode);
fill_filespec(one, sha1, sha1_valid, mode);
if (addremove != '-') {
fill_filespec(two, sha1, mode);
fill_filespec(two, sha1, sha1_valid, mode);
two->dirty_submodule = dirty_submodule;
}

Expand All @@ -4737,6 +4738,7 @@ void diff_change(struct diff_options *options,
unsigned old_mode, unsigned new_mode,
const unsigned char *old_sha1,
const unsigned char *new_sha1,
int old_sha1_valid, int new_sha1_valid,
const char *concatpath,
unsigned old_dirty_submodule, unsigned new_dirty_submodule)
{
Expand All @@ -4751,6 +4753,8 @@ void diff_change(struct diff_options *options,
const unsigned char *tmp_c;
tmp = old_mode; old_mode = new_mode; new_mode = tmp;
tmp_c = old_sha1; old_sha1 = new_sha1; new_sha1 = tmp_c;
tmp = old_sha1_valid; old_sha1_valid = new_sha1_valid;
new_sha1_valid = tmp;
tmp = old_dirty_submodule; old_dirty_submodule = new_dirty_submodule;
new_dirty_submodule = tmp;
}
Expand All @@ -4761,8 +4765,8 @@ void diff_change(struct diff_options *options,

one = alloc_filespec(concatpath);
two = alloc_filespec(concatpath);
fill_filespec(one, old_sha1, old_mode);
fill_filespec(two, new_sha1, new_mode);
fill_filespec(one, old_sha1, old_sha1_valid, old_mode);
fill_filespec(two, new_sha1, new_sha1_valid, new_mode);
one->dirty_submodule = old_dirty_submodule;
two->dirty_submodule = new_dirty_submodule;

Expand Down
5 changes: 5 additions & 0 deletions diff.h
Expand Up @@ -19,12 +19,14 @@ typedef void (*change_fn_t)(struct diff_options *options,
unsigned old_mode, unsigned new_mode,
const unsigned char *old_sha1,
const unsigned char *new_sha1,
int old_sha1_valid, int new_sha1_valid,
const char *fullpath,
unsigned old_dirty_submodule, unsigned new_dirty_submodule);

typedef void (*add_remove_fn_t)(struct diff_options *options,
int addremove, unsigned mode,
const unsigned char *sha1,
int sha1_valid,
const char *fullpath, unsigned dirty_submodule);

typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
Expand Down Expand Up @@ -214,12 +216,15 @@ extern void diff_addremove(struct diff_options *,
int addremove,
unsigned mode,
const unsigned char *sha1,
int sha1_valid,
const char *fullpath, unsigned dirty_submodule);

extern void diff_change(struct diff_options *,
unsigned mode1, unsigned mode2,
const unsigned char *sha1,
const unsigned char *sha2,
int sha1_valid,
int sha2_valid,
const char *fullpath,
unsigned dirty_submodule1, unsigned dirty_submodule2);

Expand Down
2 changes: 1 addition & 1 deletion diffcore-rename.c
Expand Up @@ -48,7 +48,7 @@ static struct diff_rename_dst *locate_rename_dst(struct diff_filespec *two,
memmove(rename_dst + first + 1, rename_dst + first,
(rename_dst_nr - first - 1) * sizeof(*rename_dst));
rename_dst[first].two = alloc_filespec(two->path);
fill_filespec(rename_dst[first].two, two->sha1, two->mode);
fill_filespec(rename_dst[first].two, two->sha1, two->sha1_valid, two->mode);
rename_dst[first].pair = NULL;
return &(rename_dst[first]);
}
Expand Down
2 changes: 1 addition & 1 deletion diffcore.h
Expand Up @@ -55,7 +55,7 @@ struct diff_filespec {
extern struct diff_filespec *alloc_filespec(const char *);
extern void free_filespec(struct diff_filespec *);
extern void fill_filespec(struct diff_filespec *, const unsigned char *,
unsigned short);
int, unsigned short);

extern int diff_populate_filespec(struct diff_filespec *, int);
extern void diff_free_filespec_data(struct diff_filespec *);
Expand Down
8 changes: 7 additions & 1 deletion fsck.c
Expand Up @@ -139,6 +139,7 @@ static int verify_ordered(unsigned mode1, const char *name1, unsigned mode2, con
static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
{
int retval;
int has_null_sha1 = 0;
int has_full_path = 0;
int has_empty_name = 0;
int has_zero_pad = 0;
Expand All @@ -157,9 +158,12 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
while (desc.size) {
unsigned mode;
const char *name;
const unsigned char *sha1;

tree_entry_extract(&desc, &name, &mode);
sha1 = tree_entry_extract(&desc, &name, &mode);

if (is_null_sha1(sha1))
has_null_sha1 = 1;
if (strchr(name, '/'))
has_full_path = 1;
if (!*name)
Expand Down Expand Up @@ -207,6 +211,8 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
}

retval = 0;
if (has_null_sha1)
retval += error_func(&item->object, FSCK_WARN, "contains entries pointing to null sha1");
if (has_full_path)
retval += error_func(&item->object, FSCK_WARN, "contains full pathnames");
if (has_empty_name)
Expand Down
2 changes: 2 additions & 0 deletions read-cache.c
Expand Up @@ -1796,6 +1796,8 @@ int write_index(struct index_state *istate, int newfd)
continue;
if (!ce_uptodate(ce) && is_racy_timestamp(istate, ce))
ce_smudge_racily_clean_entry(ce);
if (is_null_sha1(ce->sha1))
return error("cache entry has null sha1: %s", ce->name);
if (ce_write_entry(&c, newfd, ce, previous_name) < 0)
return -1;
}
Expand Down
2 changes: 2 additions & 0 deletions revision.c
Expand Up @@ -345,6 +345,7 @@ static int tree_difference = REV_TREE_SAME;
static void file_add_remove(struct diff_options *options,
int addremove, unsigned mode,
const unsigned char *sha1,
int sha1_valid,
const char *fullpath, unsigned dirty_submodule)
{
int diff = addremove == '+' ? REV_TREE_NEW : REV_TREE_OLD;
Expand All @@ -358,6 +359,7 @@ static void file_change(struct diff_options *options,
unsigned old_mode, unsigned new_mode,
const unsigned char *old_sha1,
const unsigned char *new_sha1,
int old_sha1_valid, int new_sha1_valid,
const char *fullpath,
unsigned old_dirty_submodule, unsigned new_dirty_submodule)
{
Expand Down

0 comments on commit 3b75314

Please sign in to comment.