@matheusbsbs / matheus-bagliano / commits / 177a830268
Fork 0

diff-lib: define diff_get_merge_base()

In a future commit, we will be using this function to implement --merge-base functionality in various diff commands. Signed-off-by: Denton Liu <liu.denton@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Denton Liu committed Sep 20, 2020 at 04:22 UTC 177a8302683da62a62b5b03e8192fcfa897db750
2 files changed +47
diff-lib.c
+45
@@ -13,6 +13,7 @@
13 #include "submodule.h"
14 #include "dir.h"
15 #include "fsmonitor.h"
16 +#include "commit-reach.h"
17
18 /*
19 * diff-files
@@ -512,6 +513,50 @@ static int diff_cache(struct rev_info *revs,
513 return unpack_trees(1, &t, &opts);
514 }
515
516 +void diff_get_merge_base(const struct rev_info *revs, struct object_id *mb)
517 +{
518 + int i;
519 + struct commit *mb_child[2] = {0};
520 + struct commit_list *merge_bases;
521 +
522 + for (i = 0; i < revs->pending.nr; i++) {
523 + struct object *obj = revs->pending.objects[i].item;
524 + if (obj->flags)
525 + die(_("--merge-base does not work with ranges"));
526 + if (obj->type != OBJ_COMMIT)
527 + die(_("--merge-base only works with commits"));
528 + }
529 +
530 + /*
531 + * This check must go after the for loop above because A...B
532 + * ranges produce three pending commits, resulting in a
533 + * misleading error message.
534 + */
535 + if (revs->pending.nr < 1 || revs->pending.nr > 2)
536 + BUG("unexpected revs->pending.nr: %d", revs->pending.nr);
537 +
538 + for (i = 0; i < revs->pending.nr; i++)
539 + mb_child[i] = lookup_commit_reference(the_repository, &revs->pending.objects[i].item->oid);
540 + if (revs->pending.nr == 1) {
541 + struct object_id oid;
542 +
543 + if (get_oid("HEAD", &oid))
544 + die(_("unable to get HEAD"));
545 +
546 + mb_child[1] = lookup_commit_reference(the_repository, &oid);
547 + }
548 +
549 + merge_bases = repo_get_merge_bases(the_repository, mb_child[0], mb_child[1]);
550 + if (!merge_bases)
551 + die(_("no merge base found"));
552 + if (merge_bases->next)
553 + die(_("multiple merge bases found"));
554 +
555 + oidcpy(mb, &merge_bases->item->object.oid);
556 +
557 + free_commit_list(merge_bases);
558 +}
559 +
560 int run_diff_index(struct rev_info *revs, unsigned int option)
561 {
562 struct object_array_entry *ent;
diff.h
+2
@@ -580,6 +580,8 @@ void diff_warn_rename_limit(const char *varname, int needed, int degraded_cc);
580 */
581 const char *diff_aligned_abbrev(const struct object_id *sha1, int);
582
583 +void diff_get_merge_base(const struct rev_info *revs, struct object_id *mb);
584 +
585 /* do not report anything on removed paths */
586 #define DIFF_SILENT_ON_REMOVED 01
587 /* report racily-clean paths as modified */