@matheusbsbs / matheus-bagliano / commits / 203a2fe117
Fork 0

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