Commits

Junio C Hamano  committed 168cc63 Merge

Merge refs/heads/master from .

  • Participants
  • Parent commits 58eaf28, 0d6a873

Comments (0)

Files changed (3)

File Documentation/git.txt

 
 This is reference information for the core git commands.
 
+Before reading this cover to cover, you may want to take a look
+at the link:tutorial.html[tutorial] document.
+
 The Discussion section below contains much useful definition and
 clarification info - read that first.  And of the commands, I suggest
 reading link:git-update-cache.html[git-update-cache] and

File git-resolve-script

 	dropheads
 	exit 0
 fi
-echo "Trying to merge $merge into $head"
+
+# Find an optimum merge base if there are more than one candidates.
+LF='
+'
+common=$(git-merge-base -a $head $merge)
+case "$common" in
+?*"$LF"?*)
+	echo "Trying to find the optimum merge base."
+	G=.tmp-index$$
+	best=
+	best_cnt=-1
+	for c in $common
+	do
+		rm -f $G
+		GIT_INDEX_FILE=$G git-read-tree -m $c $head $merge \
+			2>/dev/null || continue
+		# Count the paths that are unmerged.
+		cnt=`GIT_INDEX_FILE=$G git-ls-files --unmerged | wc -l`
+		if test $best_cnt -le 0 -o $cnt -le $best_cnt
+		then
+			best=$c
+			best_cnt=$cnt
+			if test "$best_cnt" -eq 0
+			then
+				# Cannot do any better than all trivial merge.
+				break
+			fi
+		fi
+	done
+	rm -f $G
+	common="$best"
+esac
+
+echo "Trying to merge $merge into $head using $common."
+git-update-cache --refresh 2>/dev/null
 git-read-tree -u -m $common $head $merge || exit 1
 result_tree=$(git-write-tree  2> /dev/null)
 if [ $? -ne 0 ]; then

File merge-base.c

  * 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);
 		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;
 			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);
 }