summaryrefslogtreecommitdiff
path: root/merge-base.c
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2005-08-24 04:08:59 (GMT)
committerJunio C Hamano <junkio@cox.net>2005-08-24 04:08:59 (GMT)
commit9585e406224b97b24b46131005b809a6612a3eac (patch)
tree47b47d3fae26e51f2b1d04fd9e898f5a0546da02 /merge-base.c
parent2a29da7c6d6103c4719c71f6cce88e853260912c (diff)
downloadgit-9585e406224b97b24b46131005b809a6612a3eac.zip
git-9585e406224b97b24b46131005b809a6612a3eac.tar.gz
git-9585e406224b97b24b46131005b809a6612a3eac.tar.bz2
Try to find the optimum merge base while resolving.
The merge-base command acquires a new option, '--all', that causes it to output all the common ancestor candidates. The "git resolve" command then uses it to pick the optimum merge base by picking the one that results in the smallest number of nontrivial merges. Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'merge-base.c')
-rw-r--r--merge-base.c52
1 files changed, 38 insertions, 14 deletions
diff --git a/merge-base.c b/merge-base.c
index 923256c..286bf0e 100644
--- a/merge-base.c
+++ b/merge-base.c
@@ -82,13 +82,17 @@ static struct commit *interesting(struct commit_list *list)
* commit B.
*/
-static struct commit *common_ancestor(struct commit *rev1, struct commit *rev2)
+static int show_all = 0;
+
+static int merge_base(struct commit *rev1, struct commit *rev2)
{
struct commit_list *list = NULL;
struct commit_list *result = NULL;
- if (rev1 == rev2)
- return rev1;
+ if (rev1 == rev2) {
+ printf("%s\n", sha1_to_hex(rev1->object.sha1));
+ return 0;
+ }
parse_commit(rev1);
parse_commit(rev2);
@@ -108,7 +112,7 @@ static struct commit *common_ancestor(struct commit *rev1, struct commit *rev2)
if (flags == 3) {
insert_by_date(commit, &result);
- /* Mark children of a found merge uninteresting */
+ /* Mark parents of a found merge uninteresting */
flags |= UNINTERESTING;
}
parents = commit->parents;
@@ -122,26 +126,46 @@ static struct commit *common_ancestor(struct commit *rev1, struct commit *rev2)
insert_by_date(p, &list);
}
}
- return interesting(result);
+
+ if (!result)
+ return 1;
+
+ while (result) {
+ struct commit *commit = result->item;
+ result = result->next;
+ if (commit->object.flags & UNINTERESTING)
+ continue;
+ printf("%s\n", sha1_to_hex(commit->object.sha1));
+ if (!show_all)
+ return 0;
+ commit->object.flags |= UNINTERESTING;
+ }
+ return 0;
}
+static const char merge_base_usage[] =
+"git-merge-base [--all] <commit-id> <commit-id>";
+
int main(int argc, char **argv)
{
- struct commit *rev1, *rev2, *ret;
+ struct commit *rev1, *rev2;
unsigned char rev1key[20], rev2key[20];
+ while (1 < argc && argv[1][0] == '-') {
+ char *arg = argv[1];
+ if (!strcmp(arg, "-a") || !strcmp(arg, "--all"))
+ show_all = 1;
+ else
+ usage(merge_base_usage);
+ argc--; argv++;
+ }
if (argc != 3 ||
get_sha1(argv[1], rev1key) ||
- get_sha1(argv[2], rev2key)) {
- usage("git-merge-base <commit-id> <commit-id>");
- }
+ get_sha1(argv[2], rev2key))
+ usage(merge_base_usage);
rev1 = lookup_commit_reference(rev1key);
rev2 = lookup_commit_reference(rev2key);
if (!rev1 || !rev2)
return 1;
- ret = common_ancestor(rev1, rev2);
- if (!ret)
- return 1;
- printf("%s\n", sha1_to_hex(ret->object.sha1));
- return 0;
+ return merge_base(rev1, rev2);
}