On Thu, 7 Apr 2011, Dave Martin wrote:

> The problem seems to be that when a merge is committed, git references
> the merged commits in their original context: no information is
> recorded about how the merge was resolved.  The result just appears by
> magic as the new tree recorded for the merge commit.

you may have a look at the output from "git show <merge_commit_ID>" 
which would show you a combined diff (Git invention) where you can see 
the actual merge resolution if there was a conflict.

> This seems to mean that git format-patch x..y (where x is an ancestor
> of y) does _not_ necessarily give you a patch series which actually
> applies on x (indeed, the generated patch series may not be appliable
> on any commit, in any order).  This is certainly my experience.

Indeed. That works well only for a linear set of commits.

> As a result, it seems very difficult to pick apart the history of a
> branch beyond the last merge commit, because the git repo only records
> the logical ancestry (i.e., which upstream patches got merged) rather
> than any "physical" history (i.e., what sequence of actual changes
> would be needed to reconstruct the branch).  In fact, it seems to be
> nonsense to think in terms of a sequence of patches beyond a merge
> commit.

Well, because a Git history is two-dimentional, you cannot always 
recreate it only with a linear sequence of changes

> What I'm actually trying to do is cherry-pick a few omap- and Thumb-
> specific commits out of the linaro tree to apply on v2.6.39-rc2 --
> just the minimum subset so that I can develop Thumb stuff on a tree
> which is as clean and close to upstream as possible.  But I repeatedly
> run into problems where patch p from branch b depends on
> cherry-picking some other patch q merged branch b, but the cherry pick
> fails since the actual delta recorded for q is in the context of
> someone else's branch (the branch that was merged from).
> 
> If anyone knows a straightforward way to achieve this, I'd be interested ...

What I'd do is (assuming there is already a separate branch with 
v2.6.39-rc2 available):

1) Find the latest commit ID you are interested in, and create a 
   temporary branch with it:

        git branch tmp_branch <commit_ID>
        git checkout tmp_branch

   or if you prefer a shortcut:

        git checkout -b tmp_branch <commit_ID>

2) Find the oldest commit you are interested in, and use it with 
   interactive rebase:

        git rebase -i --onto v2.6.39-rc2 <old_commit_ID>^

   Note the ^ here meaning the parent of the commit.  Here you should 
   specify the starting point which is always exclusive, hence with ^ 
   you make it inclusive.

3) In the editor that pops up, discard all the lines corresponding to 
   those commits you are not interested in bringing forward.  If you 
   don't know if a wanted commit is already present in v2.6.39-rc2 then 
   just keep it in the list -- in most cases Git is able to figure it 
   out automatically.  Then save the file and watch Git go.

4) If patch application problems occur, you then have the option of 
   manually fixing it, or using 'git mergetool' to help you out.  When 
   done just go on with 'git rebase --continue'.  Or you may skip a 
   problematic patch with 'git rebase --skip'.

5) Rename your tmp_branch into something more meaningful, or simply 
   discard it if you're not satisfied with the result.

That's it.  Of course, if you're looking for only a few commits then it 
is probably quicker to go with 'git cherry-pick' on each of them 
instead.


Nicolas

_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to