summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenton Liu <liu.denton@gmail.com>2020-09-20 11:22:23 (GMT)
committerJunio C Hamano <gitster@pobox.com>2020-09-21 04:30:26 (GMT)
commit177a8302683da62a62b5b03e8192fcfa897db750 (patch)
tree3dacb7efb0aa78978ac2d00209ea7d91a86b7440
parent4c3fe82ef17a6636c742b95cd292b83b02876e08 (diff)
downloadgit-177a8302683da62a62b5b03e8192fcfa897db750.zip
git-177a8302683da62a62b5b03e8192fcfa897db750.tar.gz
git-177a8302683da62a62b5b03e8192fcfa897db750.tar.bz2
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>
-rw-r--r--diff-lib.c45
-rw-r--r--diff.h2
2 files changed, 47 insertions, 0 deletions
diff --git a/diff-lib.c b/diff-lib.c
index ed72085..468e3fe 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -13,6 +13,7 @@
#include "submodule.h"
#include "dir.h"
#include "fsmonitor.h"
+#include "commit-reach.h"
/*
* diff-files
@@ -512,6 +513,50 @@ static int diff_cache(struct rev_info *revs,
return unpack_trees(1, &t, &opts);
}
+void diff_get_merge_base(const struct rev_info *revs, struct object_id *mb)
+{
+ int i;
+ struct commit *mb_child[2] = {0};
+ struct commit_list *merge_bases;
+
+ for (i = 0; i < revs->pending.nr; i++) {
+ struct object *obj = revs->pending.objects[i].item;
+ if (obj->flags)
+ die(_("--merge-base does not work with ranges"));
+ if (obj->type != OBJ_COMMIT)
+ die(_("--merge-base only works with commits"));
+ }
+
+ /*
+ * This check must go after the for loop above because A...B
+ * ranges produce three pending commits, resulting in a
+ * misleading error message.
+ */
+ if (revs->pending.nr < 1 || revs->pending.nr > 2)
+ BUG("unexpected revs->pending.nr: %d", revs->pending.nr);
+
+ for (i = 0; i < revs->pending.nr; i++)
+ mb_child[i] = lookup_commit_reference(the_repository, &revs->pending.objects[i].item->oid);
+ if (revs->pending.nr == 1) {
+ struct object_id oid;
+
+ if (get_oid("HEAD", &oid))
+ die(_("unable to get HEAD"));
+
+ mb_child[1] = lookup_commit_reference(the_repository, &oid);
+ }
+
+ merge_bases = repo_get_merge_bases(the_repository, mb_child[0], mb_child[1]);
+ if (!merge_bases)
+ die(_("no merge base found"));
+ if (merge_bases->next)
+ die(_("multiple merge bases found"));
+
+ oidcpy(mb, &merge_bases->item->object.oid);
+
+ free_commit_list(merge_bases);
+}
+
int run_diff_index(struct rev_info *revs, unsigned int option)
{
struct object_array_entry *ent;
diff --git a/diff.h b/diff.h
index aea0d5b..fedfeab 100644
--- a/diff.h
+++ b/diff.h
@@ -580,6 +580,8 @@ void diff_warn_rename_limit(const char *varname, int needed, int degraded_cc);
*/
const char *diff_aligned_abbrev(const struct object_id *sha1, int);
+void diff_get_merge_base(const struct rev_info *revs, struct object_id *mb);
+
/* do not report anything on removed paths */
#define DIFF_SILENT_ON_REMOVED 01
/* report racily-clean paths as modified */