threads / patch / 32217

v2, 3 partsAllow for MERGE_MODE to specify more then one mode

Subject: [PATCH v2 2/3] Allow for MERGE_MODE to specify more then one mode

## tl;dr

11 messages between Nov 27, 2012 and Nov 28, 2012. Diffs are folded; open one to read it.

replies: 10people: 3as markdown or json

Kacper Kornet· Nov 27, 2012, 23:00 UTC · lore

[PATCH v2 0/3] Add option to change order of parents in merge commit

The second version of patches introducing option to change order of parents in merge commits. The changes in respect to the previous version:

- I have divided the changes to the preparatory ones, which
  only refactore the code without introducing new functionality, and
  the commit which introduces the new option
- The documentation for the new options has been added

This is not yet a final version, as the tests are missing. But maybe while I'm working on them there will be some comments.

Kacper Kornet (3):
  Process MERGE_MODE before MERGE_HEAD
  Allow for MERGE_MODE to specify more then one mode
  Add option to transpose parents of merge commit
 Documentation/merge-options.txt |  7 +++++++
 builtin/commit.c                | 22 ++++++++++++++--------
 builtin/merge.c                 | 16 ++++++++++++----
 commit.c                        | 11 +++++++++++
 commit.h                        |  2 ++
 git-pull.sh                     |  4 +++-
 6 files changed, 49 insertions(+), 13 deletions(-)
-- 
1.8.0.1
Kacper Kornet· Nov 27, 2012, 23:00 UTC · re: Kacper Kornet · lore

[PATCH v2 1/3] Process MERGE_MODE before MERGE_HEAD

It is in preparation to introduce --transpose-parents option to git-merge, when the content of MERGE_MODE will dictate how the MERGE_HEAD is interpreted.

Signed-off-by: Kacper Kornet <draenog@pld-linux.org>
---
 builtin/commit.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
Show changes to builtin/commit.c +6 −6
diff --git a/builtin/commit.c b/builtin/commit.c
index 1dd2ec5..273332f 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1481,6 +1481,12 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 
 		if (!reflog_msg)
 			reflog_msg = "commit (merge)";
+		if (!stat(git_path("MERGE_MODE"), &statbuf)) {
+			if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
+				die_errno(_("could not read MERGE_MODE"));
+			if (!strcmp(sb.buf, "no-ff"))
+				allow_fast_forward = 0;
+		}
 		pptr = &commit_list_insert(current_head, pptr)->next;
 		fp = fopen(git_path("MERGE_HEAD"), "r");
 		if (fp == NULL)
@@ -1496,12 +1502,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 		}
 		fclose(fp);
 		strbuf_release(&m);
-		if (!stat(git_path("MERGE_MODE"), &statbuf)) {
-			if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
-				die_errno(_("could not read MERGE_MODE"));
-			if (!strcmp(sb.buf, "no-ff"))
-				allow_fast_forward = 0;
-		}
 		if (allow_fast_forward)
 			parents = reduce_heads(parents);
 	} else {
-- 
1.8.0.1
Kacper Kornet· Nov 27, 2012, 23:00 UTC · re: Kacper Kornet · lore

Presently only one merge mode exists: non-fast-forward. But in future the second one (transpose-parents) will be added, so the need to read all lines of MERGE_MODE.

Signed-off-by: Kacper Kornet <draenog@pld-linux.org>
---
 builtin/commit.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
Show changes to builtin/commit.c +6 −6
diff --git a/builtin/commit.c b/builtin/commit.c
index 273332f..ee0e884 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1427,7 +1427,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 	unsigned char sha1[20];
 	struct ref_lock *ref_lock;
 	struct commit_list *parents = NULL, **pptr = &parents;
-	struct stat statbuf;
 	int allow_fast_forward = 1;
 	struct commit *current_head = NULL;
 	struct commit_extra_header *extra = NULL;
@@ -1481,11 +1480,12 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 
 		if (!reflog_msg)
 			reflog_msg = "commit (merge)";
-		if (!stat(git_path("MERGE_MODE"), &statbuf)) {
-			if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
-				die_errno(_("could not read MERGE_MODE"));
-			if (!strcmp(sb.buf, "no-ff"))
-				allow_fast_forward = 0;
+		if((fp = fopen(git_path("MERGE_MODE"), "r"))) {
+			while (strbuf_getline(&m, fp, '\n') != EOF) {
+				if (!strcmp(m.buf, "no-ff"))
+					allow_fast_forward = 0;
+			}
+			fclose(fp);
 		}
 		pptr = &commit_list_insert(current_head, pptr)->next;
 		fp = fopen(git_path("MERGE_HEAD"), "r");
-- 
1.8.0.1
Junio C Hamano· Nov 28, 2012, 02:17 UTC · re: Kacper Kornet · lore

Re: [PATCH v2 2/3] Allow for MERGE_MODE to specify more then one mode

Kacper Kornet <draenog@pld-linux.org> writes:
Show 31 quoted lines
> Presently only one merge mode exists: non-fast-forward. But in future
> the second one (transpose-parents) will be added, so the need to read
> all lines of MERGE_MODE.
>
> Signed-off-by: Kacper Kornet <draenog@pld-linux.org>
> ---
>  builtin/commit.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/builtin/commit.c b/builtin/commit.c
> index 273332f..ee0e884 100644
> --- a/builtin/commit.c
> +++ b/builtin/commit.c
> @@ -1427,7 +1427,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
>  	unsigned char sha1[20];
>  	struct ref_lock *ref_lock;
>  	struct commit_list *parents = NULL, **pptr = &parents;
> -	struct stat statbuf;
>  	int allow_fast_forward = 1;
>  	struct commit *current_head = NULL;
>  	struct commit_extra_header *extra = NULL;
> @@ -1481,11 +1480,12 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
>  
>  		if (!reflog_msg)
>  			reflog_msg = "commit (merge)";
> -		if (!stat(git_path("MERGE_MODE"), &statbuf)) {
> -			if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
> -				die_errno(_("could not read MERGE_MODE"));
> -			if (!strcmp(sb.buf, "no-ff"))
> -				allow_fast_forward = 0;
> +		if((fp = fopen(git_path("MERGE_MODE"), "r"))) {
Style: s/if((fp/if ((fp/;
Show 5 quoted lines
> +			while (strbuf_getline(&m, fp, '\n') != EOF) {
> +				if (!strcmp(m.buf, "no-ff"))
> +					allow_fast_forward = 0;
> +			}
> +			fclose(fp);

This needs a bit more careful planning for interacting with other people's programs, I suspect.

Your updated builtin/merge.c may write an extra LF after no-ff to make this parser to grok it, but it is entirely plausible that people have their own Porcelain that writes "no-ff" without LF (because that is what we read from this file, and I suspect the current code would ignore "no-ff\n").

At least strbuf_getline() would give us "no-ff" when either "no-ff" or "no-ff\n" terminates the file, so updated code would be able to grok what other people would write, but if other people want to read MERGE_MODE we write, at least we shouldn't break them when we only write no-ff in it (once you start writing "reverse-parents" in the file, they will be broken anyway, as they do not currently expect such token in this file).

I am starting to wonder if this is worth it, though...
Kacper Kornet· Nov 28, 2012, 04:36 UTC · re: Junio C Hamano · lore

Re: [PATCH v2 2/3] Allow for MERGE_MODE to specify more then one mode

On Tue, Nov 27, 2012 at 06:17:28PM -0800, Junio C Hamano wrote:
> Kacper Kornet <draenog@pld-linux.org> writes:
> > Presently only one merge mode exists: non-fast-forward. But in future
> > the second one (transpose-parents) will be added, so the need to read
> > all lines of MERGE_MODE.
> > Signed-off-by: Kacper Kornet <draenog@pld-linux.org>
> > ---
> >  builtin/commit.c | 12 ++++++------
> >  1 file changed, 6 insertions(+), 6 deletions(-)
Show 13 quoted lines
> > diff --git a/builtin/commit.c b/builtin/commit.c
> > index 273332f..ee0e884 100644
> > --- a/builtin/commit.c
> > +++ b/builtin/commit.c
> > @@ -1427,7 +1427,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
> >  	unsigned char sha1[20];
> >  	struct ref_lock *ref_lock;
> >  	struct commit_list *parents = NULL, **pptr = &parents;
> > -	struct stat statbuf;
> >  	int allow_fast_forward = 1;
> >  	struct commit *current_head = NULL;
> >  	struct commit_extra_header *extra = NULL;
> > @@ -1481,11 +1480,12 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
Show 8 quoted lines
> >  		if (!reflog_msg)
> >  			reflog_msg = "commit (merge)";
> > -		if (!stat(git_path("MERGE_MODE"), &statbuf)) {
> > -			if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
> > -				die_errno(_("could not read MERGE_MODE"));
> > -			if (!strcmp(sb.buf, "no-ff"))
> > -				allow_fast_forward = 0;
> > +		if((fp = fopen(git_path("MERGE_MODE"), "r"))) {
> Style: s/if((fp/if ((fp/;
Show 5 quoted lines
> > +			while (strbuf_getline(&m, fp, '\n') != EOF) {
> > +				if (!strcmp(m.buf, "no-ff"))
> > +					allow_fast_forward = 0;
> > +			}
> > +			fclose(fp);
> This needs a bit more careful planning for interacting with other
> people's programs, I suspect.
Show 5 quoted lines
> Your updated builtin/merge.c may write an extra LF after no-ff to
> make this parser to grok it, but it is entirely plausible that
> people have their own Porcelain that writes "no-ff" without LF
> (because that is what we read from this file, and I suspect the
> current code would ignore "no-ff\n").
Show 7 quoted lines
> At least strbuf_getline() would give us "no-ff" when either "no-ff"
> or "no-ff\n" terminates the file, so updated code would be able to
> grok what other people would write, but if other people want to read
> MERGE_MODE we write, at least we shouldn't break them when we only
> write no-ff in it (once you start writing "reverse-parents" in the
> file, they will be broken anyway, as they do not currently expect
> such token in this file).

At this stage in the patch series the format of MERGE_MODE is not changed - "no-ff" is printed without "\n". What should be changed is the next patch. Relevant part should read:

Show changes to builtin/merge.c +2 −0
diff --git a/builtin/merge.c b/builtin/merge.c
index a96e8ea..5ceb291 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -993,6 +999,8 @@ static void write_merge_state(struct commit_list *remoteheads)
 	if (fd < 0)
 		die_errno(_("Could not open '%s' for writing"), filename);
 	strbuf_reset(&buf);
+	if (reversed_order)
+		strbuf_addf(&buf, "reversed-order\n");
 	if (!allow_fast_forward)
 		strbuf_addf(&buf, "no-ff");
 	if (write_in_full(fd, buf.buf, buf.len) != buf.len)

This way when only no-ff is specified all parsers should be happy. If
reversed-order is specified together no-ff the "external" parser
probably would fail. Which in my opinion is a good think at this point,
as it can't correctly interpret MERGE_MODE anyway.
-- 
  Kacper
Junio C Hamano· Nov 28, 2012, 07:30 UTC · re: Kacper Kornet · lore

Re: [PATCH v2 2/3] Allow for MERGE_MODE to specify more then one mode

Kacper Kornet <draenog@pld-linux.org> writes:
> This way when only no-ff is specified all parsers should be happy. If
> reversed-order is specified together no-ff the "external" parser
> probably would fail. Which in my opinion is a good think at this point,
> as it can't correctly interpret MERGE_MODE anyway.
Amen to that.
Kacper Kornet· Nov 27, 2012, 23:00 UTC · re: Kacper Kornet · lore

[PATCH v2 3/3] Add option to transpose parents of merge commit

When the changes are pushed upstream, and in the meantime someone else updated upstream branch git advises to use git pull. This results in history:

     ---A---B---C--
         \     /
          D---E

where B is the local commit. D, E are commits pushed by someone else when the developer was working on B. However sometimes the following history is preferable:

    ---A---D---C'--
        \     /
         '-B-'

The difference between C and C' is the order of parents. This change allow for easier way to obtain this effect by introducing the option --transpose-parents to git-merge and git-pull, which changes the order of parents in resulting commit moving the original first parent to the very end of list of parents.

The transposition is done just before the commit is finalized, so the meaning of "our" and "their" for conflict resolution is not changed, so "ours" denotes local version and "theirs" upstream.

Signed-off-by: Kacper Kornet <draenog@pld-linux.org>
---
 Documentation/merge-options.txt |  7 +++++++
 builtin/commit.c                |  8 +++++++-
 builtin/merge.c                 | 16 ++++++++++++----
 commit.c                        | 11 +++++++++++
 commit.h                        |  2 ++
 git-pull.sh                     |  4 +++-
 6 files changed, 42 insertions(+), 6 deletions(-)
Show changes to 6 files +42 −6

Documentation/merge-options.txt, builtin/commit.c, builtin/merge.c, commit.c, commit.h, git-pull.sh

diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt
index 0bcbe0a..b4fbfdc 100644
--- a/Documentation/merge-options.txt
+++ b/Documentation/merge-options.txt
@@ -88,6 +88,13 @@ option can be used to override --squash.
 	Synonyms to --stat and --no-stat; these are deprecated and will be
 	removed in the future.
 
+--transpose-parents::
+	Transpose the parents in the final commit. The change is made
+	just before the commit so the meaning of 'our' and 'their'
+	concepts remains the same (i.e. 'our' means current branch before
+	the merge).
+
+
 ifndef::git-pull[]
 -q::
 --quiet::
diff --git a/builtin/commit.c b/builtin/commit.c
index ee0e884..ab2b844 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1477,6 +1477,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 	} else if (whence == FROM_MERGE) {
 		struct strbuf m = STRBUF_INIT;
 		FILE *fp;
+		int reversed_order=0;
 
 		if (!reflog_msg)
 			reflog_msg = "commit (merge)";
@@ -1484,10 +1485,13 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 			while (strbuf_getline(&m, fp, '\n') != EOF) {
 				if (!strcmp(m.buf, "no-ff"))
 					allow_fast_forward = 0;
+				if (!strcmp(m.buf, "reversed-order"))
+					reversed_order = 1;
 			}
 			fclose(fp);
 		}
-		pptr = &commit_list_insert(current_head, pptr)->next;
+		if (!reversed_order)
+			pptr = &commit_list_insert(current_head, pptr)->next;
 		fp = fopen(git_path("MERGE_HEAD"), "r");
 		if (fp == NULL)
 			die_errno(_("could not open '%s' for reading"),
@@ -1502,6 +1506,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 		}
 		fclose(fp);
 		strbuf_release(&m);
+		if (reversed_order)
+			pptr = &commit_list_insert(current_head, pptr)->next;
 		if (allow_fast_forward)
 			parents = reduce_heads(parents);
 	} else {
diff --git a/builtin/merge.c b/builtin/merge.c
index a96e8ea..41738a5 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -65,6 +65,7 @@ static int abort_current_merge;
 static int show_progress = -1;
 static int default_to_upstream;
 static const char *sign_commit;
+static int reversed_order=0;
 
 static struct strategy all_strategy[] = {
 	{ "recursive",  DEFAULT_TWOHEAD | NO_TRIVIAL },
@@ -213,6 +214,7 @@ static struct option builtin_merge_options[] = {
 	{ OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key id"),
 	  N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
 	OPT_BOOLEAN(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")),
+	OPT_BOOLEAN(0, "transpose-parents", &reversed_order, N_("reverse order of parents")),
 	OPT_END()
 };
 
@@ -822,9 +824,9 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads)
 
 	write_tree_trivial(result_tree);
 	printf(_("Wonderful.\n"));
-	parent->item = head;
+	parent->item = reversed_order ? remoteheads->item : head;
 	parent->next = xmalloc(sizeof(*parent->next));
-	parent->next->item = remoteheads->item;
+	parent->next->item = reversed_order ? head : remoteheads->item;
 	parent->next->next = NULL;
 	prepare_to_commit(remoteheads);
 	if (commit_tree(&merge_msg, result_tree, parent, result_commit, NULL,
@@ -848,8 +850,12 @@ static int finish_automerge(struct commit *head,
 
 	free_commit_list(common);
 	parents = remoteheads;
-	if (!head_subsumed || !allow_fast_forward)
+	if (!head_subsumed || !allow_fast_forward) {
+	    if (reversed_order )
+		commit_list_insert_end(head, &parents);
+	    else
 		commit_list_insert(head, &parents);
+	}
 	strbuf_addch(&merge_msg, '\n');
 	prepare_to_commit(remoteheads);
 	if (commit_tree(&merge_msg, result_tree, parents, result_commit,
@@ -994,7 +1000,9 @@ static void write_merge_state(struct commit_list *remoteheads)
 		die_errno(_("Could not open '%s' for writing"), filename);
 	strbuf_reset(&buf);
 	if (!allow_fast_forward)
-		strbuf_addf(&buf, "no-ff");
+		strbuf_addf(&buf, "no-ff\n");
+	if (reversed_order)
+		strbuf_addf(&buf, "reversed-order\n");
 	if (write_in_full(fd, buf.buf, buf.len) != buf.len)
 		die_errno(_("Could not write to '%s'"), filename);
 	close(fd);
diff --git a/commit.c b/commit.c
index e8eb0ae..6e58994 100644
--- a/commit.c
+++ b/commit.c
@@ -363,6 +363,17 @@ struct commit_list *commit_list_insert(struct commit *item, struct commit_list *
 	return new_list;
 }
 
+struct commit_list *commit_list_insert_end(struct commit *item, struct commit_list **list_p)
+{
+	struct commit_list *list_iter = *list_p;
+	while(list_iter->next)
+		list_iter = list_iter->next;
+	list_iter->next = xmalloc(sizeof(*list_iter->next));
+	list_iter->next->item = item;
+	list_iter->next->next = NULL;
+	return *list_p;
+}
+
 unsigned commit_list_count(const struct commit_list *l)
 {
 	unsigned c = 0;
diff --git a/commit.h b/commit.h
index b6ad8f3..17ae5e5 100644
--- a/commit.h
+++ b/commit.h
@@ -53,6 +53,8 @@ int find_commit_subject(const char *commit_buffer, const char **subject);
 
 struct commit_list *commit_list_insert(struct commit *item,
 					struct commit_list **list);
+struct commit_list *commit_list_insert_end(struct commit *item,
+					struct commit_list **list);
 struct commit_list **commit_list_append(struct commit *commit,
 					struct commit_list **next);
 unsigned commit_list_count(const struct commit_list *l);
diff --git a/git-pull.sh b/git-pull.sh
index 266e682..d9c7591 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -84,6 +84,8 @@ do
 		no_ff=--no-ff ;;
 	--ff-only)
 		ff_only=--ff-only ;;
+	--transpose-parents)
+		transpose_parents=--transpose-parents;;
 	-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
 		--strateg=*|--strategy=*|\
 	-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
@@ -283,7 +285,7 @@ true)
 	eval="$eval --onto $merge_head ${oldremoteref:-$merge_head}"
 	;;
 *)
-	eval="git-merge $diffstat $no_commit $edit $squash $no_ff $ff_only"
+	eval="git-merge $diffstat $no_commit $edit $squash $no_ff $ff_only $transpose_parents"
 	eval="$eval  $log_arg $strategy_args $merge_args $verbosity $progress"
 	eval="$eval \"\$merge_name\" HEAD $merge_head"
 	;;
-- 
1.8.0.1
Junio C Hamano· Nov 28, 2012, 02:18 UTC · re: Kacper Kornet · lore

Re: [PATCH v2 3/3] Add option to transpose parents of merge commit

Kacper Kornet <draenog@pld-linux.org> writes:
Show 6 quoted lines
> +--transpose-parents::
> +	Transpose the parents in the final commit. The change is made
> +	just before the commit so the meaning of 'our' and 'their'
> +	concepts remains the same (i.e. 'our' means current branch before
> +	the merge).
> +
How does this interact with Octopus merges?
Show 9 quoted lines
> diff --git a/builtin/commit.c b/builtin/commit.c
> index ee0e884..ab2b844 100644
> --- a/builtin/commit.c
> +++ b/builtin/commit.c
> @@ -1477,6 +1477,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
>  	} else if (whence == FROM_MERGE) {
>  		struct strbuf m = STRBUF_INIT;
>  		FILE *fp;
> +		int reversed_order=0;
Style. s/=/ = /;
> +	OPT_BOOLEAN(0, "transpose-parents", &reversed_order, N_("reverse order of parents")

It smells more like "--reverse-parents" (if you deal only with two-head merges), no?

Kacper Kornet· Nov 28, 2012, 04:43 UTC · re: Junio C Hamano · lore

Re: [PATCH v2 3/3] Add option to transpose parents of merge commit

On Tue, Nov 27, 2012 at 06:18:00PM -0800, Junio C Hamano wrote:
> Kacper Kornet <draenog@pld-linux.org> writes:
Show 6 quoted lines
> > +--transpose-parents::
> > +	Transpose the parents in the final commit. The change is made
> > +	just before the commit so the meaning of 'our' and 'their'
> > +	concepts remains the same (i.e. 'our' means current branch before
> > +	the merge).
> > +
> How does this interact with Octopus merges?

It moves the original first parent to the last position. And nothing more. I have forgotten to mention it in the documentation.

Show 9 quoted lines
> > diff --git a/builtin/commit.c b/builtin/commit.c
> > index ee0e884..ab2b844 100644
> > --- a/builtin/commit.c
> > +++ b/builtin/commit.c
> > @@ -1477,6 +1477,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
> >  	} else if (whence == FROM_MERGE) {
> >  		struct strbuf m = STRBUF_INIT;
> >  		FILE *fp;
> > +		int reversed_order=0;
> Style. s/=/ = /;
> > +	OPT_BOOLEAN(0, "transpose-parents", &reversed_order, N_("reverse order of parents")
> It smells more like "--reverse-parents" (if you deal only with
> two-head merges), no?

I have changes to --transpose-parents because of the octopus merges. Although it is not a mathematical transposition in this case, but a cycle permutation.

-- 
  Kacper
Johannes Sixt· Nov 28, 2012, 06:56 UTC · re: Kacper Kornet · lore

Re: [PATCH v2 3/3] Add option to transpose parents of merge commit

Am 11/28/2012 0:00, schrieb Kacper Kornet:
Show 7 quoted lines
> When the changes are pushed upstream, and in the meantime someone else
> updated upstream branch git advises to use git pull. This results in
> history:
> 
>      ---A---B---C--
>          \     /
>           D---E
The commit message will say:
  Merge branch 'master' of /that/remote
  * 'master' of /that/remote:
    E
    D
Show 7 quoted lines
> where B is the local commit. D, E are commits pushed by someone else
> when the developer was working on B. However sometimes the following
> history is preferable:
> 
>     ---A---D---C'--
>         \     /
>          '-B-'
Better:
     ---A--D--E--C'
         \      /
          `----B

In this case, the commit message should say... what? Certainly not the same thing. But I do not see that you changed anything in this regard.

-- Hannes
Junio C Hamano· Nov 28, 2012, 16:52 UTC · re: Johannes Sixt · lore

Re: [PATCH v2 3/3] Add option to transpose parents of merge commit

Johannes Sixt <j.sixt@viscovery.net> writes:
Show 30 quoted lines
> Am 11/28/2012 0:00, schrieb Kacper Kornet:
>> When the changes are pushed upstream, and in the meantime someone else
>> updated upstream branch git advises to use git pull. This results in
>> history:
>> 
>>      ---A---B---C--
>>          \     /
>>           D---E
>
> The commit message will say:
>
>   Merge branch 'master' of /that/remote
>
>   * 'master' of /that/remote:
>     E
>     D
>
>> where B is the local commit. D, E are commits pushed by someone else
>> when the developer was working on B. However sometimes the following
>> history is preferable:
>> 
>>     ---A---D---C'--
>>         \     /
>>          '-B-'
>
> Better:
>
>      ---A--D--E--C'
>          \      /
>           `----B
Yup, that topology is what Kacper's workflow wants.

Stepping back a bit, however, I am not sure if that is really true. The goal of this topic seems to be to keep one integration branch and always merge *into* that integration branch, never *from* it, but for what purpose? Making the "log --first-parent" express the integration branch as a linear series of progress? If so, I suspect a project with such a policy would dictate that D and E also be on a side branch, i.e. the history would look more like this:

      D---E
     /     \
  --A-------X---C---
     \         /
      `-------B

with X being a --no-ff merge of the topic that consists of these two commits.

> In this case, the commit message should say... what? Certainly not the
> same thing. But I do not see that you changed anything in this regard.

True. If the goal is to emulate a merge of B from a side branch into _the_ integration branch, the summary should also emulate the message that would be given when the remote pulled from your current branch.

← back to recent threads