git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 10/24] merge-base --independent to print reduced parent list in a merge

From
Jonathan Nieder <jrnieder@gmail.com>
Date
Aug 17, 2010, 07:01 UTC
Message-ID
<20100817070154.GJ22057@burratino>
In-Reply-To
<20100817065147.GA18293@burratino>

While show-branch --independent does not support more than MAX_REVS revs, git internally supports more with a different algorithm. Expose that functionality as "git merge-base --independent".

This should help scripts to catch up with builtin merge in supporting dodecapus.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 Documentation/git-merge-base.txt |    9 ++++++++
 builtin/merge-base.c             |   21 ++++++++++++++-----
 t/t6010-merge-base.sh            |   39 +++++++++++++++++++++++++++++++++++++-
 3 files changed, 62 insertions(+), 7 deletions(-)
diff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.txt
index 125207e..eedef1b 100644
--- a/Documentation/git-merge-base.txt
+++ b/Documentation/git-merge-base.txt
@@ -8,7 +8,9 @@ git-merge-base - Find as good common ancestors as possible for a merge
 
 SYNOPSIS
 --------
+[verse]
 'git merge-base' [-a|--all] [--octopus] <commit> <commit>...
+'git merge-base' --independent <commit>...
 
 DESCRIPTION
 -----------
@@ -42,6 +44,13 @@ OPTIONS
 	in preparation for an n-way merge.  This mimics the behavior
 	of 'git show-branch --merge-base'.
 
+--independent::
+	Instead of printing merge bases, print a minimal subset of
+	the supplied commits with the same ancestors.  In other words,
+	among the commits given, list those which cannot be reached
+	from any other.  This mimics the behavior of 'git show-branch
+	--independent'.
+
 DISCUSSION
 ----------
 
diff --git a/builtin/merge-base.c b/builtin/merge-base.c
index c301286..96dd160 100644
--- a/builtin/merge-base.c
+++ b/builtin/merge-base.c
@@ -24,6 +24,7 @@ static int show_merge_base(struct commit **rev, int rev_nr, int show_all)
 
 static const char * const merge_base_usage[] = {
 	"git merge-base [-a|--all] [--octopus] <commit> <commit>...",
+	"git merge-base --independent <commit>...",
 	NULL
 };
 
@@ -41,15 +42,19 @@ static struct commit *get_commit_reference(const char *arg)
 	return r;
 }
 
-static int show_octopus_merge_bases(int count, const char **args, int show_all)
+static int handle_octopus(int count, const char **args, int reduce, int show_all)
 {
 	struct commit_list *revs = NULL;
 	struct commit_list *result;
 	int i;
 
-	for (i = count - 1; i >= 0; i++)
+	if (reduce)
+		show_all = 1;
+
+	for (i = count - 1; i >= 0; i--)
 		commit_list_insert(get_commit_reference(args[i]), &revs);
-	result = get_octopus_merge_bases(revs);
+
+	result = reduce ? reduce_heads(revs) : get_octopus_merge_bases(revs);
 
 	if (!result)
 		return 1;
@@ -70,20 +75,24 @@ int cmd_merge_base(int argc, const char **argv, const char *prefix)
 	int rev_nr = 0;
 	int show_all = 0;
 	int octopus = 0;
+	int reduce = 0;
 
 	struct option options[] = {
 		OPT_BOOLEAN('a', "all", &show_all, "output all common ancestors"),
 		OPT_BOOLEAN(0, "octopus", &octopus, "find ancestors for a single n-way merge"),
+		OPT_BOOLEAN(0, "independent", &reduce, "list revs not reachable from others"),
 		OPT_END()
 	};
 
 	git_config(git_default_config, NULL);
 	argc = parse_options(argc, argv, prefix, options, merge_base_usage, 0);
-	if (!octopus && argc < 2)
+	if (!octopus && !reduce && argc < 2)
 		usage_with_options(merge_base_usage, options);
+	if (reduce && (show_all || octopus))
+		die("--independent cannot be used with other options");
 
-	if (octopus)
-		return show_octopus_merge_bases(argc, argv, show_all);
+	if (octopus || reduce)
+		return handle_octopus(argc, argv, reduce, show_all);
 
 	rev = xmalloc(argc * sizeof(*rev));
 	while (argc-- > 0)
diff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh
index 001431b..62197a3 100755
--- a/t/t6010-merge-base.sh
+++ b/t/t6010-merge-base.sh
@@ -3,7 +3,7 @@
 # Copyright (c) 2005 Junio C Hamano
 #
 
-test_description='Merge base computation.
+test_description='Merge base and parent list computation.
 '
 
 . ./test-lib.sh
@@ -75,6 +75,26 @@ test_expect_success 'merge-base G H' '
 	test_cmp expected actual.sb
 '
 
+test_expect_success 'merge-base/show-branch --independent' '
+	git name-rev "$H" >expected1 &&
+	git name-rev "$H" "$G" >expected2 &&
+
+	parents=$(git merge-base --independent H) &&
+	git name-rev $parents >actual1.mb &&
+	parents=$(git merge-base --independent A H G) &&
+	git name-rev $parents >actual2.mb &&
+
+	parents=$(git show-branch --independent H) &&
+	git name-rev $parents >actual1.sb &&
+	parents=$(git show-branch --independent A H G) &&
+	git name-rev $parents >actual2.sb &&
+
+	test_cmp expected1 actual1.mb &&
+	test_cmp expected2 actual2.mb &&
+	test_cmp expected1 actual1.sb &&
+	test_cmp expected2 actual2.sb
+'
+
 test_expect_success 'unsynchronized clocks' '
 	# This test is to demonstrate that relying on timestamps in a distributed
 	# SCM to provide a _consistent_ partial ordering of commits leads to
@@ -125,6 +145,23 @@ test_expect_success 'unsynchronized clocks' '
 	test_cmp expected actual.all
 '
 
+test_expect_success '--independent with unsynchronized clocks' '
+	IB=$(doit 0 IB) &&
+	I1=$(doit -10 I1 $IB) &&
+	I2=$(doit  -9 I2 $I1) &&
+	I3=$(doit  -8 I3 $I2) &&
+	I4=$(doit  -7 I4 $I3) &&
+	I5=$(doit  -6 I5 $I4) &&
+	I6=$(doit  -5 I6 $I5) &&
+	I7=$(doit  -4 I7 $I6) &&
+	I8=$(doit  -3 I8 $I7) &&
+	IH=$(doit  -2 IH $I8) &&
+
+	echo $IH >expected &&
+	git merge-base --independent IB IH >actual &&
+	test_cmp expected actual
+'
+
 test_expect_success 'merge-base for octopus-step (setup)' '
 	# Another set to demonstrate base between one commit and a merge
 	# in the documentation.
-- 
1.7.2.1.544.ga752d.dirty
Previous: Jonathan NiederNext: Jonathan Nieder
Message 16 of 36 in “updating examples/git-merge (plus a builtin/merge fix)”
  1. updating examples/git-merge (plus a builtin/merge fix)Jonathan Nieder, Aug 17, 2010
  2. 01/24 merge: do not mistake (ancestor of) tag for branchJonathan Nieder, Aug 17, 2010
  3. 02/24 t7600 (merge): modernize styleJonathan Nieder, Aug 17, 2010
  4. 03/24 t7600 (merge): do not launch gitk for --debugJonathan Nieder, Aug 17, 2010
  5. Ævar Arnfjörð BjarmasonAug 17, 2010
  6. Sverre RabbelierAug 17, 2010
  7. Jonathan NiederAug 18, 2010
  8. Ævar Arnfjörð BjarmasonAug 18, 2010
  9. Jonathan NiederAug 18, 2010
  10. 04/24 t7600 (merge): check reflog entryJonathan Nieder, Aug 17, 2010
  11. 05/24 t7600 (merge): test merge from branch yet to be bornJonathan Nieder, Aug 17, 2010
  12. 06/24 t6010 (merge-base): modernize styleJonathan Nieder, Aug 17, 2010
  13. 07/24 t6200 (fmt-merge-msg): style nitpicksJonathan Nieder, Aug 17, 2010
  14. 08/24 Documentation: add a SEE ALSO section for merge-baseJonathan Nieder, Aug 17, 2010
  15. 09/24 merge-base --octopus to mimic show-branch --merge-baseJonathan Nieder, Aug 17, 2010
  16. 10/24 merge-base --independent to print reduced parent list in a mergeJonathan Nieder, Aug 17, 2010
  17. 11/24 fmt-merge-msg -m to override subject lineJonathan Nieder, Aug 17, 2010
  18. 11/24 fmt-merge-msg -m to override merge titleJonathan Nieder, Aug 17, 2010
  19. 12/24 merge script: --squash, --ff from unborn branch are errorsJonathan Nieder, Aug 17, 2010
  20. 13/24 merge script: tweak unmerged files message to match builtinJonathan Nieder, Aug 17, 2010
  21. Ævar Arnfjörð BjarmasonAug 17, 2010
  22. 14/24 merge script: refuse to merge during mergeJonathan Nieder, Aug 17, 2010
  23. 15/24 merge script: improve log message subjectJonathan Nieder, Aug 17, 2010
  24. 16/24 merge script: merge -X<option>Jonathan Nieder, Aug 17, 2010
  25. 17/24 merge script: allow custom strategiesJonathan Nieder, Aug 17, 2010
  26. 18/24 merge script: forbid merge -s indexJonathan Nieder, Aug 17, 2010
  27. 19/24 merge script: handle -m --log correctlyJonathan Nieder, Aug 17, 2010
  28. Tay Ray ChuanAug 17, 2010
  29. Jonathan NiederAug 17, 2010
  30. 20/24 merge script: handle many-way octopusJonathan Nieder, Aug 17, 2010
  31. 21/24 merge script: --ff-only to disallow true mergeJonathan Nieder, Aug 17, 2010
  32. 22/24 merge script: handle --no-ff --no-commit correctlyJonathan Nieder, Aug 17, 2010
  33. 23/24 merge script: notice @{-1} shorthandJonathan Nieder, Aug 17, 2010
  34. 24/24 merge script: learn --[no-]rerere-autoupdateJonathan Nieder, Aug 17, 2010
  35. Ævar Arnfjörð BjarmasonAug 17, 2010
  36. Jonathan NiederAug 17, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.