git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <junkio@cox.net>
To: Andreas Ericsson <ae@op5.se>
Cc: git@vger.kernel.org
Subject: Re: [RFD] remembering hand resolve...
Date: Wed, 25 Jan 2006 15:56:15 -0800	[thread overview]
Message-ID: <7v1wyvn9pc.fsf@assigned-by-dhcp.cox.net> (raw)
In-Reply-To: 43D7810D.9010508@op5.se

Andreas Ericsson <ae@op5.se> writes:

> Junio C Hamano wrote:
>> The thing is, I find myself resolving the same conflicts over
>> and over.  This is because the master branch tends to advance
>> faster than topic branches that touch an overlapping area.
>
> How can that be possible? If the area of code in master is modified
> beyond simple merging from the topic-branches, the resulting diff
> (which has to be against master's HEAD) should apply cleanly so long
> as there aren't *new* changes to master, in which case the pu commit
> needs adaptation again, so it wouldn't really be the same conflict (or
> even necessarily a similar one), would it?

In general, you are right.  When the change that advances
"master" touches the same area as those held-back topic branches
touch, the earlier resolution between topic branches may not help.

However, the change to the "master" that leap-frogs these
held-back topic branches is often independent from the changes
in these held-back topic branches.

For example, as of this morning, my "master" and "pu" were like
this:

        $ git show-branch master pu
        * [master] Merge branches 'jc/clone', 'md/env' and 'mo/path'
         ! [pu] Merge jc/revparse,jc/abbrev
        --
         - [pu] Merge jc/revparse,jc/abbrev
         - [pu^] Merge lt/revlist,jc/diff,jc/bind
         + [pu^^3] combine-diff: fix appending at the tail of a list.
         + [pu^2] rev-parse --flags/--no-flags usability fix.
         + [pu^3] diff-tree: abbreviate merge parent object names wit...
         + [pu^^2] rev-list: stop when the file disappears
         + [pu^^3^] diff-tree --cc: denser combined diff output for a...
         + [pu^^3~2] diff-tree -c: show a merge commit a bit more sen...
         + [pu^^4] fsck-objects, convert-objects: understand bound co...
         + [pu^^4^] rev-list: understand bound commits.
         + [pu^^4~2] rev-list: simplify --object list generation.
         + [pu^^4~3] commit-tree: --bind <sha1> <path>/ option.
         + [pu^^4~4] write-tree: --prefix=<path>/ and --exclude=<pref...
         + [pu^^4~5] read-tree: --prefix=<path>/ option.
         + [pu^3^] rev-parse: --abbrev option.
         + [pu^3~2] abbrev cleanup: use symbolic constants
        -- [master] Merge branches 'jc/clone', 'md/env' and 'mo/path'

The two merges at the tip of "pu" shows that I merged lt/revlist
(Linus' "stop at disappearance"), jc/diff ("combined diff") and
jc/bind ("bound commit') first because I felt they are more or
less ready, and then jc/revparse and jc/abbrev on top of it.

Two topic branches, jc/abbrev and jc/bind, touch the same area
in commit.c.  The former changes the formatting of "Merge:" line
from prettyprinted commit (we did not honor --abbrev option to
diff-tree when we used that function).  The latter changes the
same function to include a call to add the new "Bind: " lines.
When I made the last merge for the tip of "pu", I had to hand
resolve conflicts in the file.

Now suppose I feel topic branches lt/revlist, jc/diff and
jc/revparse are ready, and want to have them graduate to the
"master" branch.  Also I may get a patch from you fixing
Documentation/Makefile, which none of my topic branches touch,
so I would advance "master" this way:

	$ git checkout master
        $ git pull . lt/revlist
        $ git pull . jc/diff
        $ git pull . jc/revparse
	$ git am -3 -s ./+ae-doc-make.email

What I would do after this step to rebuild "pu" would be to
merge jc/bind and jc/abbrev branches, in some order.  But in
whatever order I merge, I would get the conflict in commit.c
as before:

	$ git checkout pu
        $ git reset --hard master
        $ git pull . jc/bind
        $ git pull . jc/abbrev

If I swap the order I pull in jc/bind and jc/abbrev, the
sections marked with conflict markers <<< === >>> would be
swapped, so the conflict would not be exactly the same, but
the result of the resolution is the same.  I end up making the
result logically the same by hand resolving.

Although I happen to do Octopus when building "pu" but the issue
does not change if the merges were made one branch at a time.

>> If I linearize topic-branches that conflict with each other in
>> some way, say base topic B on top of topic A, I would not have
>> problem merging them into "pu" as long as I do not change my
>> mind later and try to merge only topic B without topic A.  But
>> that defeats the whole point of having independent topic
>> branches.
>
> Wouldn't cherry-pick be useful here? If it isn't, I fail to understand
> how a merge can solve it for you....

Suppose instead of having

              A---B---C jc/bind
             /    
  master ---O
             \    
              D---E---F jc/abbrev

I made this:

              A'--B'--C'--D---E---F
             /        ^jc/bind    ^jc/abbrev
  master ---O

When converting the two topic branches into this sequence,
obviously I have to hand merge the changes A-B-C makes and the
changes D-E-F makes to commit.c file.

I can later attempt to cherry-pick D-E-F on top of updated
"master".  I think that is what you mean by "cherry-picking",
but that would have the same "I've resolved this before" issue.
Because the change D-E-F brings in now depends on the change
A'-B'-C' brings in. But on the tip of the master branch, that
change is not there yet. The cherry-picked changes on top of O
would not cleanly apply.  Even with the 3-way merge fallback,
this is a merge of F and O using C' as the merge base, and we
will see conflicts.

However, as long as I do not have to merge the contents of
jc/abbrev branch in without the contents of jc/bind branch, a
merge to an updated master would not have any conflict between
A'-B'-C' chain and D-E-F chain, and often even after jc/bind and
jc/abbrev advances:

                        G---H jc/bind
                       /
              A'--B'--C'--D---E---F
             /                    ^jc/abbrev
  master ---O---I---J

Pulling jc/bind to master and then jc/abbrev on top it may have
conflicts between the changes O-I-J and C'-G-H bring in, but at
least I would not have to re-resolve the conflicts between
A'-B'-C' and D-E-F chains.  That is what I meant to say.  The
merge is helped by making jc/abbrev topic branch dependent on
the earlier part of jc/bind topic branch.

> Couldn't you do something like this:
>
> for t in $topic_branches; do
> 	checkout $t
> 	git rebase master
> done
> git checkout master
> git branch -D pu
> git checkout -b pu
> git pull . $topic_branches
>
> That's what I thought you were doing right now, but I can't imagine
> that flow leading to the same conflicts over and over, so I must be
> mistaken somehow.

That is exactly what I am doing [*1*]


[Footnote]

*1* In my primary development working tree, I have a checked-out
tree of "todo" branch at Meta/ directory.  The "pu" is built by
running Meta/PU (that is "PU" file in the "todo" branch) from
the toplevel and picking topic branches to merge on top of the
master branch, which essentially does what you just described.

To take a peek at how my primary development working tree looks
like, you could do this:

	$ git clone git://git.kernel.org/pub/scm/git/git GIT
        $ cd GIT
        $ git clone -l -s -n .git Meta
        $ cd Meta
        $ git checkout todo
        $ cd ..
	$ rm Meta/.git/refs/heads/[a-p]* ;# leave only "todo"
        $ rm -f .git/refs/heads/{html,man,todo}

This would give a rough approximation of where I work.

The above clone would not have any of the topic branches; but
their heads appear on merge commits between master and pu.  For
example, in the earlier show-branch output, the tip of "pu" says
"Merge jc/revparse,jc/abbrev", which means pu^1 was the tip of
pu when this merge was made, pu^2 is the tip of jc/revparse
topic, and pu^3 is jc/abbrev.  You can take them apart like so:

	$ git branch jc/revparse pu^2
	$ git branch jc/abbrev pu^3

  reply	other threads:[~2006-01-25 23:56 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-01-25 13:00 [RFD] remembering hand resolve Junio C Hamano
2006-01-25 13:45 ` Andreas Ericsson
2006-01-25 23:56   ` Junio C Hamano [this message]
2006-01-26 11:12     ` How to create and keep up to date a naked/bare repository? Mathieu Chouquet-Stringer
2006-01-26 12:22       ` Junio C Hamano
2006-01-26 15:11         ` Mathieu Chouquet-Stringer
2006-01-26 18:27         ` Mathieu Chouquet-Stringer
2006-01-27  3:36           ` Junio C Hamano
2006-01-27 10:30             ` Refs naming after clone (was: Re: How to create and keep up to date a naked/bare repository?) Josef Weidendorfer
2006-01-27 13:34             ` How to create and keep up to date a naked/bare repository? Mathieu Chouquet-Stringer
2006-01-27 18:41               ` Junio C Hamano
2006-01-27 19:01                 ` J. Bruce Fields
2006-01-27 21:00                   ` Junio C Hamano
2006-01-29  9:10 ` [PATCH/RFC] git-rerere: reuse recorded resolve Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7v1wyvn9pc.fsf@assigned-by-dhcp.cox.net \
    --to=junkio@cox.net \
    --cc=ae@op5.se \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).