Skip to content

Commit 203a2fe

Browse files
iabervongitster
authored andcommitted
Allow callers of unpack_trees() to handle failure
Return an error from unpack_trees() instead of calling die(), and exit with an error in read-tree, builtin-commit, and diff-lib. merge-recursive already expected an error return from unpack_trees, so it doesn't need to be changed. The merge function can return negative to abort. This will be used in builtin-checkout -m. Signed-off-by: Daniel Barkalow <[email protected]>
1 parent 9cb76b8 commit 203a2fe

File tree

4 files changed

+56
-41
lines changed

4 files changed

+56
-41
lines changed

builtin-commit.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ static void create_base_index(void)
200200
die("failed to unpack HEAD tree object");
201201
parse_tree(tree);
202202
init_tree_desc(&t, tree->buffer, tree->size);
203-
unpack_trees(1, &t, &opts);
203+
if (unpack_trees(1, &t, &opts))
204+
exit(128); /* We've already reported the error, finish dying */
204205
}
205206

206207
static char *prepare_index(int argc, const char **argv, const char *prefix)

builtin-read-tree.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
268268
parse_tree(tree);
269269
init_tree_desc(t+i, tree->buffer, tree->size);
270270
}
271-
unpack_trees(nr_trees, t, &opts);
271+
if (unpack_trees(nr_trees, t, &opts))
272+
return 128;
272273

273274
/*
274275
* When reading only one tree (either the most basic form,

diff-lib.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,8 @@ int run_diff_index(struct rev_info *revs, int cached)
737737
opts.unpack_data = revs;
738738

739739
init_tree_desc(&t, tree->buffer, tree->size);
740-
unpack_trees(1, &t, &opts);
740+
if (unpack_trees(1, &t, &opts))
741+
exit(128);
741742

742743
diffcore_std(&revs->diffopt);
743744
diff_flush(&revs->diffopt);
@@ -789,6 +790,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)
789790
opts.unpack_data = &revs;
790791

791792
init_tree_desc(&t, tree->buffer, tree->size);
792-
unpack_trees(1, &t, &opts);
793+
if (unpack_trees(1, &t, &opts))
794+
exit(128);
793795
return 0;
794796
}

unpack-trees.c

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
219219
}
220220
#endif
221221
ret = o->fn(src, o, remove);
222+
if (ret < 0)
223+
return ret;
222224

223225
#if DBRT_DEBUG > 1
224226
printf("Added %d entries\n", ret);
@@ -359,18 +361,18 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
359361
}
360362

361363
if (o->trivial_merges_only && o->nontrivial_merge)
362-
die("Merge requires file-level merging");
364+
return error("Merge requires file-level merging");
363365

364366
check_updates(active_cache, active_nr, o);
365367
return 0;
366368
}
367369

368370
/* Here come the merge functions */
369371

370-
static void reject_merge(struct cache_entry *ce)
372+
static int reject_merge(struct cache_entry *ce)
371373
{
372-
die("Entry '%s' would be overwritten by merge. Cannot merge.",
373-
ce->name);
374+
return error("Entry '%s' would be overwritten by merge. Cannot merge.",
375+
ce->name);
374376
}
375377

376378
static int same(struct cache_entry *a, struct cache_entry *b)
@@ -388,18 +390,18 @@ static int same(struct cache_entry *a, struct cache_entry *b)
388390
* When a CE gets turned into an unmerged entry, we
389391
* want it to be up-to-date
390392
*/
391-
static void verify_uptodate(struct cache_entry *ce,
393+
static int verify_uptodate(struct cache_entry *ce,
392394
struct unpack_trees_options *o)
393395
{
394396
struct stat st;
395397

396398
if (o->index_only || o->reset)
397-
return;
399+
return 0;
398400

399401
if (!lstat(ce->name, &st)) {
400402
unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID);
401403
if (!changed)
402-
return;
404+
return 0;
403405
/*
404406
* NEEDSWORK: the current default policy is to allow
405407
* submodule to be out of sync wrt the supermodule
@@ -408,12 +410,12 @@ static void verify_uptodate(struct cache_entry *ce,
408410
* checked out.
409411
*/
410412
if (S_ISGITLINK(ce->ce_mode))
411-
return;
413+
return 0;
412414
errno = 0;
413415
}
414416
if (errno == ENOENT)
415-
return;
416-
die("Entry '%s' not uptodate. Cannot merge.", ce->name);
417+
return 0;
418+
return error("Entry '%s' not uptodate. Cannot merge.", ce->name);
417419
}
418420

419421
static void invalidate_ce_path(struct cache_entry *ce)
@@ -479,7 +481,8 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
479481
* ce->name is an entry in the subdirectory.
480482
*/
481483
if (!ce_stage(ce)) {
482-
verify_uptodate(ce, o);
484+
if (verify_uptodate(ce, o))
485+
return -1;
483486
ce->ce_flags |= CE_REMOVE;
484487
}
485488
cnt++;
@@ -498,8 +501,8 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
498501
d.exclude_per_dir = o->dir->exclude_per_dir;
499502
i = read_directory(&d, ce->name, pathbuf, namelen+1, NULL);
500503
if (i)
501-
die("Updating '%s' would lose untracked files in it",
502-
ce->name);
504+
return error("Updating '%s' would lose untracked files in it",
505+
ce->name);
503506
free(pathbuf);
504507
return cnt;
505508
}
@@ -508,16 +511,16 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
508511
* We do not want to remove or overwrite a working tree file that
509512
* is not tracked, unless it is ignored.
510513
*/
511-
static void verify_absent(struct cache_entry *ce, const char *action,
512-
struct unpack_trees_options *o)
514+
static int verify_absent(struct cache_entry *ce, const char *action,
515+
struct unpack_trees_options *o)
513516
{
514517
struct stat st;
515518

516519
if (o->index_only || o->reset || !o->update)
517-
return;
520+
return 0;
518521

519522
if (has_symlink_leading_path(ce->name, NULL))
520-
return;
523+
return 0;
521524

522525
if (!lstat(ce->name, &st)) {
523526
int cnt;
@@ -527,7 +530,7 @@ static void verify_absent(struct cache_entry *ce, const char *action,
527530
* ce->name is explicitly excluded, so it is Ok to
528531
* overwrite it.
529532
*/
530-
return;
533+
return 0;
531534
if (S_ISDIR(st.st_mode)) {
532535
/*
533536
* We are checking out path "foo" and
@@ -556,7 +559,7 @@ static void verify_absent(struct cache_entry *ce, const char *action,
556559
* deleted entries here.
557560
*/
558561
o->pos += cnt;
559-
return;
562+
return 0;
560563
}
561564

562565
/*
@@ -568,12 +571,13 @@ static void verify_absent(struct cache_entry *ce, const char *action,
568571
if (0 <= cnt) {
569572
struct cache_entry *ce = active_cache[cnt];
570573
if (ce->ce_flags & CE_REMOVE)
571-
return;
574+
return 0;
572575
}
573576

574-
die("Untracked working tree file '%s' "
575-
"would be %s by merge.", ce->name, action);
577+
return error("Untracked working tree file '%s' "
578+
"would be %s by merge.", ce->name, action);
576579
}
580+
return 0;
577581
}
578582

579583
static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
@@ -591,12 +595,14 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
591595
if (same(old, merge)) {
592596
memcpy(merge, old, offsetof(struct cache_entry, name));
593597
} else {
594-
verify_uptodate(old, o);
598+
if (verify_uptodate(old, o))
599+
return -1;
595600
invalidate_ce_path(old);
596601
}
597602
}
598603
else {
599-
verify_absent(merge, "overwritten", o);
604+
if (verify_absent(merge, "overwritten", o))
605+
return -1;
600606
invalidate_ce_path(merge);
601607
}
602608

@@ -608,10 +614,12 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
608614
static int deleted_entry(struct cache_entry *ce, struct cache_entry *old,
609615
struct unpack_trees_options *o)
610616
{
611-
if (old)
612-
verify_uptodate(old, o);
613-
else
614-
verify_absent(ce, "removed", o);
617+
if (old) {
618+
if (verify_uptodate(old, o))
619+
return -1;
620+
} else
621+
if (verify_absent(ce, "removed", o))
622+
return -1;
615623
ce->ce_flags |= CE_REMOVE;
616624
add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
617625
invalidate_ce_path(ce);
@@ -699,15 +707,15 @@ int threeway_merge(struct cache_entry **stages,
699707
/* #14, #14ALT, #2ALT */
700708
if (remote && !df_conflict_head && head_match && !remote_match) {
701709
if (index && !same(index, remote) && !same(index, head))
702-
reject_merge(index);
710+
return reject_merge(index);
703711
return merged_entry(remote, index, o);
704712
}
705713
/*
706714
* If we have an entry in the index cache, then we want to
707715
* make sure that it matches head.
708716
*/
709717
if (index && !same(index, head)) {
710-
reject_merge(index);
718+
return reject_merge(index);
711719
}
712720

713721
if (head) {
@@ -758,8 +766,10 @@ int threeway_merge(struct cache_entry **stages,
758766
remove_entry(remove);
759767
if (index)
760768
return deleted_entry(index, index, o);
761-
else if (ce && !head_deleted)
762-
verify_absent(ce, "removed", o);
769+
else if (ce && !head_deleted) {
770+
if (verify_absent(ce, "removed", o))
771+
return -1;
772+
}
763773
return 0;
764774
}
765775
/*
@@ -775,7 +785,8 @@ int threeway_merge(struct cache_entry **stages,
775785
* conflict resolution files.
776786
*/
777787
if (index) {
778-
verify_uptodate(index, o);
788+
if (verify_uptodate(index, o))
789+
return -1;
779790
}
780791

781792
remove_entry(remove);
@@ -855,11 +866,11 @@ int twoway_merge(struct cache_entry **src,
855866
/* all other failures */
856867
remove_entry(remove);
857868
if (oldtree)
858-
reject_merge(oldtree);
869+
return reject_merge(oldtree);
859870
if (current)
860-
reject_merge(current);
871+
return reject_merge(current);
861872
if (newtree)
862-
reject_merge(newtree);
873+
return reject_merge(newtree);
863874
return -1;
864875
}
865876
}
@@ -886,7 +897,7 @@ int bind_merge(struct cache_entry **src,
886897
return error("Cannot do a bind merge of %d trees\n",
887898
o->merge_size);
888899
if (a && old)
889-
die("Entry '%s' overlaps. Cannot bind.", a->name);
900+
return error("Entry '%s' overlaps. Cannot bind.", a->name);
890901
if (!a)
891902
return keep_entry(old, o);
892903
else

0 commit comments

Comments
 (0)