Skip to content

Commit 177a830

Browse files
Denton-Lgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4c3fe82 commit 177a830

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

diff-lib.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "submodule.h"
1414
#include "dir.h"
1515
#include "fsmonitor.h"
16+
#include "commit-reach.h"
1617

1718
/*
1819
* diff-files
@@ -512,6 +513,50 @@ static int diff_cache(struct rev_info *revs,
512513
return unpack_trees(1, &t, &opts);
513514
}
514515

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+
515560
int run_diff_index(struct rev_info *revs, unsigned int option)
516561
{
517562
struct object_array_entry *ent;

diff.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,8 @@ void diff_warn_rename_limit(const char *varname, int needed, int degraded_cc);
580580
*/
581581
const char *diff_aligned_abbrev(const struct object_id *sha1, int);
582582

583+
void diff_get_merge_base(const struct rev_info *revs, struct object_id *mb);
584+
583585
/* do not report anything on removed paths */
584586
#define DIFF_SILENT_ON_REMOVED 01
585587
/* report racily-clean paths as modified */

0 commit comments

Comments
 (0)