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 <barkalow@iabervon.org>
Daniel Barkalow committed
Feb 7, 2008 at 11:39 UTC
203a2fe117070964a5bf7cc940a742cad7a19fca
4 files changed
+56
-41
builtin-commit.c
+2
-1
@@ -200,7 +200,8 @@ static void create_base_index(void)
200
die("failed to unpack HEAD tree object");
201
parse_tree(tree);
202
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 */
205
}
206
207
static char *prepare_index(int argc, const char **argv, const char *prefix)
builtin-read-tree.c
+2
-1
@@ -268,7 +268,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
268
parse_tree(tree);
269
init_tree_desc(t+i, tree->buffer, tree->size);
270
}
271
- unpack_trees(nr_trees, t, &opts);
271
+ if (unpack_trees(nr_trees, t, &opts))
272
+ return 128;
273
274
/*
275
* When reading only one tree (either the most basic form,
diff-lib.c
+4
-2
@@ -737,7 +737,8 @@ int run_diff_index(struct rev_info *revs, int cached)
737
opts.unpack_data = revs;
738
739
init_tree_desc(&t, tree->buffer, tree->size);
740
- unpack_trees(1, &t, &opts);
740
+ if (unpack_trees(1, &t, &opts))
741
+ exit(128);
742
743
diffcore_std(&revs->diffopt);
744
diff_flush(&revs->diffopt);
@@ -789,6 +790,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct diff_options *opt)
790
opts.unpack_data = &revs;
791
792
init_tree_desc(&t, tree->buffer, tree->size);
792
- unpack_trees(1, &t, &opts);
793
+ if (unpack_trees(1, &t, &opts))
794
+ exit(128);
795
return 0;
796
}
unpack-trees.c
+48
-37
@@ -219,6 +219,8 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
219
}
220
#endif
221
ret = o->fn(src, o, remove);
222
+ if (ret < 0)
223
+ return ret;
224
225
#if DBRT_DEBUG > 1
226
printf("Added %d entries\n", ret);
@@ -359,7 +361,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
361
}
362
363
if (o->trivial_merges_only && o->nontrivial_merge)
362
- die("Merge requires file-level merging");
364
+ return error("Merge requires file-level merging");
365
366
check_updates(active_cache, active_nr, o);
367
return 0;
@@ -367,10 +369,10 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
369
370
/* Here come the merge functions */
371
370
-static void reject_merge(struct cache_entry *ce)
372
+static int reject_merge(struct cache_entry *ce)
373
{
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);
376
}
377
378
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)
390
* When a CE gets turned into an unmerged entry, we
391
* want it to be up-to-date
392
*/
391
-static void verify_uptodate(struct cache_entry *ce,
393
+static int verify_uptodate(struct cache_entry *ce,
394
struct unpack_trees_options *o)
395
{
396
struct stat st;
397
398
if (o->index_only || o->reset)
397
- return;
399
+ return 0;
400
401
if (!lstat(ce->name, &st)) {
402
unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID);
403
if (!changed)
402
- return;
404
+ return 0;
405
/*
406
* NEEDSWORK: the current default policy is to allow
407
* submodule to be out of sync wrt the supermodule
@@ -408,12 +410,12 @@ static void verify_uptodate(struct cache_entry *ce,
410
* checked out.
411
*/
412
if (S_ISGITLINK(ce->ce_mode))
411
- return;
413
+ return 0;
414
errno = 0;
415
}
416
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);
419
}
420
421
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,
481
* ce->name is an entry in the subdirectory.
482
*/
483
if (!ce_stage(ce)) {
482
- verify_uptodate(ce, o);
484
+ if (verify_uptodate(ce, o))
485
+ return -1;
486
ce->ce_flags |= CE_REMOVE;
487
}
488
cnt++;
@@ -498,8 +501,8 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
501
d.exclude_per_dir = o->dir->exclude_per_dir;
502
i = read_directory(&d, ce->name, pathbuf, namelen+1, NULL);
503
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);
506
free(pathbuf);
507
return cnt;
508
}
@@ -508,16 +511,16 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
511
* We do not want to remove or overwrite a working tree file that
512
* is not tracked, unless it is ignored.
513
*/
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)
516
{
517
struct stat st;
518
519
if (o->index_only || o->reset || !o->update)
517
- return;
520
+ return 0;
521
522
if (has_symlink_leading_path(ce->name, NULL))
520
- return;
523
+ return 0;
524
525
if (!lstat(ce->name, &st)) {
526
int cnt;
@@ -527,7 +530,7 @@ static void verify_absent(struct cache_entry *ce, const char *action,
530
* ce->name is explicitly excluded, so it is Ok to
531
* overwrite it.
532
*/
530
- return;
533
+ return 0;
534
if (S_ISDIR(st.st_mode)) {
535
/*
536
* We are checking out path "foo" and
@@ -556,7 +559,7 @@ static void verify_absent(struct cache_entry *ce, const char *action,
559
* deleted entries here.
560
*/
561
o->pos += cnt;
559
- return;
562
+ return 0;
563
}
564
565
/*
@@ -568,12 +571,13 @@ static void verify_absent(struct cache_entry *ce, const char *action,
571
if (0 <= cnt) {
572
struct cache_entry *ce = active_cache[cnt];
573
if (ce->ce_flags & CE_REMOVE)
571
- return;
574
+ return 0;
575
}
576
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);
579
}
580
+ return 0;
581
}
582
583
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,
595
if (same(old, merge)) {
596
memcpy(merge, old, offsetof(struct cache_entry, name));
597
} else {
594
- verify_uptodate(old, o);
598
+ if (verify_uptodate(old, o))
599
+ return -1;
600
invalidate_ce_path(old);
601
}
602
}
603
else {
599
- verify_absent(merge, "overwritten", o);
604
+ if (verify_absent(merge, "overwritten", o))
605
+ return -1;
606
invalidate_ce_path(merge);
607
}
608
@@ -608,10 +614,12 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
614
static int deleted_entry(struct cache_entry *ce, struct cache_entry *old,
615
struct unpack_trees_options *o)
616
{
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;
623
ce->ce_flags |= CE_REMOVE;
624
add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
625
invalidate_ce_path(ce);
@@ -699,7 +707,7 @@ int threeway_merge(struct cache_entry **stages,
707
/* #14, #14ALT, #2ALT */
708
if (remote && !df_conflict_head && head_match && !remote_match) {
709
if (index && !same(index, remote) && !same(index, head))
702
- reject_merge(index);
710
+ return reject_merge(index);
711
return merged_entry(remote, index, o);
712
}
713
/*
@@ -707,7 +715,7 @@ int threeway_merge(struct cache_entry **stages,
715
* make sure that it matches head.
716
*/
717
if (index && !same(index, head)) {
710
- reject_merge(index);
718
+ return reject_merge(index);
719
}
720
721
if (head) {
@@ -758,8 +766,10 @@ int threeway_merge(struct cache_entry **stages,
766
remove_entry(remove);
767
if (index)
768
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
+ }
773
return 0;
774
}
775
/*
@@ -775,7 +785,8 @@ int threeway_merge(struct cache_entry **stages,
785
* conflict resolution files.
786
*/
787
if (index) {
778
- verify_uptodate(index, o);
788
+ if (verify_uptodate(index, o))
789
+ return -1;
790
}
791
792
remove_entry(remove);
@@ -855,11 +866,11 @@ int twoway_merge(struct cache_entry **src,
866
/* all other failures */
867
remove_entry(remove);
868
if (oldtree)
858
- reject_merge(oldtree);
869
+ return reject_merge(oldtree);
870
if (current)
860
- reject_merge(current);
871
+ return reject_merge(current);
872
if (newtree)
862
- reject_merge(newtree);
873
+ return reject_merge(newtree);
874
return -1;
875
}
876
}
@@ -886,7 +897,7 @@ int bind_merge(struct cache_entry **src,
897
return error("Cannot do a bind merge of %d trees\n",
898
o->merge_size);
899
if (a && old)
889
- die("Entry '%s' overlaps. Cannot bind.", a->name);
900
+ return error("Entry '%s' overlaps. Cannot bind.", a->name);
901
if (!a)
902
return keep_entry(old, o);
903
else