All of lore.kernel.org
 help / color / mirror / Atom feed
From: Avery Pennarun <apenwarr@gmail.com>
To: Andrey Smirnov <allter@gmail.com>
Cc: git@vger.kernel.org
Subject: Re: [PATCH/RFC 1/2] Add 'git subtree' command for tracking history of  subtrees separately.
Date: Thu, 16 Jul 2009 14:34:58 -0400	[thread overview]
Message-ID: <32541b130907161134n51e070a1l93690d1b8a63bee8@mail.gmail.com> (raw)
In-Reply-To: <loom.20090716T160021-218@post.gmane.org>

On Thu, Jul 16, 2009 at 2:04 PM, Andrey Smirnov<allter@gmail.com> wrote:
> I found the git-subtree aproach of handling sub-repositories very interesting
> and useful to me. This is the previous-to-last feature I've awaited from DVCS
> world since I went into it.

I'm glad you like it.

> My goal was to rebase changes to shared library of two similar projects from one
> project to another. The commits in the more recent project were touching both
> lib/ directory with shared library and the rest of the project.
>
> When I did
>   git subtree split --prefix=lib NewProj -b test-split
>  and
>   git subtree split --prefix=lib OldProj -b test-split-old
> I got the following two trees without a common root:
>
> ...X ----- Y ----- OldProj ----...---- Z ---- NewProj
>
> X' ----- Y'==test-split-old ----- Z'==test-split

So, why don't they have a common root?  This is, of course, the
primary cause of your problems.

How did this shared library get merged into OldProj and NewProj in the
first place?  Did you just copy the files, or did you use something
like 'git merge -s subtree'?  If the latter, you should be able to
convince git-subtree to produce two split repositories with identical
roots, and then merge smoothly between them.

If you just copied the files (or applied patches with git-rebase, etc)
then a common root is impossible, and you'll have to repair the
damage, as I'll explain below:

> Problem:
>
> When I did
>   git subtree merge test-split --prefix=lib
> it printed:
>  Auto-merged lib/x.cgi
>  CONFLICT (add/add): Merge conflict in lib/x.cgi
>  Auto-merged lib/y.cgi
>  CONFLICT (add/add): Merge conflict in lib/y.cgi
>  Automatic merge failed; fix conflicts and then commit the result.
>
> It's obvious that it should be that way because logically both trees don't have
> the same root at the time of merge. But I've expected subtree merge --prefix
> will understand that X' is identical to changes to 'lib/*' in X, Y' to Y and Z'
> to Z.

'git subtree merge' is just like 'git merge' - if you don't have a
shared merge-base commit, it won't know what to do, and will have to
guess.

> Solution:
>
>    git rebase --onto OldProj test-split-old test-split
> it printed:
>  First, rewinding head to replay your work on top of it...
>  Applying ZZZZZ
>  error: x.cgi: does not exist in index
>  error: y.cgi: does not exist in index
>  Using index info to reconstruct a base tree...
>  Falling back to patching base and 3-way merge...
>
> I don't know what magic it used but it did rebase right. Furthermore "-s
> subtree" didn't work at all:
>    git rebase --onto OldProj test-split-old test-split -s subtree
>  First, rewinding head to replay your work on top of it...
>  Fast-forwarded OldProj to OldProj.

Now you've just made a mess.  Instead, I might have tried something like this:

  git checkout -b test-merged test-split
  git rebase test-split-old

Now you've got a split branch test-merged that should contain all the
changes from both test-split and test-split-old, and its parentage is
test-split-old.  Let's make it so that it can merge conflict-free into
either branch:

  git merge -s ours test-split

Next, you merge it into one of your main projects:

  git checkout OldProj
    # you should have used split --rejoin earlier, and the next
command wouldn't be necessary here
  git subtree split --prefix=lib OldProj --rejoin
  git subtree merge --prefix=lib test-merged

And the other:

  git checkout NewProj
    # you should have used split --rejoin earlier, and the next
command wouldn't be necessary here
  git subtree split --prefix=lib NewProj --rejoin
  git subtree merge --prefix=lib test-merged

Now both projects are caught up with test-merged, and moreover, if you
split either of them in the future, they will share a common
merge-base (ie. today's value of test-merged).  Future merges will
therefore be easier.

> And so I ask if this behavior is the way git-subtree was meant to work.
> It probably has sense to add 'rebase' command to git-subtree script to let
> perform such tasks simplier.

I don't think that's a good idea.  git-subtree is completely separate
from rebasing, and doesn't deal with patches at all.  Maybe there
should be some kind of "force-update" option that does what "git
subtree add" does, but wiping out everything in the subtree before it
starts.  That would have simplified the above commands a bit.

Avery

  reply	other threads:[~2009-07-16 18:35 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-26 22:29 [PATCH/RFC 1/2] Add 'git subtree' command for tracking history of subtrees separately Avery Pennarun
2009-04-26 22:29 ` [PATCH/RFC 2/2] Automated test script for 'git subtree' Avery Pennarun
2009-04-30  2:27 ` [PATCH/RFC 1/2] Add 'git subtree' command for tracking history of subtrees separately Avery Pennarun
2009-04-30  3:44   ` Ping Yin
2009-04-30  8:58   ` Finn Arne Gangstad
2009-04-30 14:32     ` Avery Pennarun
2009-07-16 18:04       ` Andrey Smirnov
2009-07-16 18:34         ` Avery Pennarun [this message]
2009-07-16 22:09           ` Andrey Smirnov
2009-07-16 22:27             ` Avery Pennarun
2009-07-17  7:16               ` Andrey Smirnov
2009-07-17 15:47                 ` Avery Pennarun
2009-07-17 17:46                   ` Andrey Smirnov

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

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

  git send-email \
    --in-reply-to=32541b130907161134n51e070a1l93690d1b8a63bee8@mail.gmail.com \
    --to=apenwarr@gmail.com \
    --cc=allter@gmail.com \
    --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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.