threads / discuss / 11410

Anomalous conflicts during git rebase

Subject: Anomalous conflicts during git rebase

## tl;dr

8 messages between Dec 27, 2007 and Dec 28, 2007.

replies: 7people: 4as markdown or json

adr3nald0s@gmail.com· Dec 27, 2007, 22:42 UTC · lore
On a clone of linux-2.6:
    git checkout -b topic/test v2.6.15
    touch drivers/a-file.c
    git add drivers/a-file.c
    git commit -m 'Add a file'
    git checkout -b temp0 v2.6.16
    git rebase topic/test
I get the following:
    Applying [ACPI] handle ACPICA 20050916's acpi_resource.type rename
  
    error: patch failed: drivers/acpi/glue.c:99
    error: drivers/acpi/glue.c: patch does not apply
    error: patch failed: drivers/char/hpet.c:897
    error: drivers/char/hpet.c: patch does not apply
    Using index info to reconstruct a base tree...
    Falling back to patching base and 3-way merge...
    Auto-merged drivers/acpi/glue.c
    Auto-merged drivers/acpi/pci_link.c
    Auto-merged drivers/char/hpet.c
    CONFLICT (content): Merge conflict in drivers/char/hpet.c
    Failed to merge in the changes.
    Patch failed at 0007.
  
    When you have resolved this problem run "git rebase --continue".
    If you would prefer to skip this patch, instead run "git rebase --skip".
    To restore the original branch and stop rebasing run "git rebase --abort".

Is this a bug, or is there a reason I am seeing conflicts in files I've never touched?

Johannes Sixt· Dec 27, 2007, 22:57 UTC · re: adr3nald0s@gmail.com · lore

Re: Anomalous conflicts during git rebase

adr3nald0s@gmail.com wrote:
Show 12 quoted lines
> On a clone of linux-2.6:
> 
>     git checkout -b topic/test v2.6.15
>     touch drivers/a-file.c
>     git add drivers/a-file.c
>     git commit -m 'Add a file'
>     git checkout -b temp0 v2.6.16
>     git rebase topic/test
> 
> I get the following:
> 
>     Applying [ACPI] handle ACPICA 20050916's acpi_resource.type rename
..
>     CONFLICT (content): Merge conflict in drivers/char/hpet.c
..
> Is this a bug, or is there a reason I am seeing conflicts in files
> I've never touched?
You are using the rebase the wrong way round.

The (first) argument to git rebase tells *where the current branch* will be moved to, and not *which branch to move*.

So, instead of last two commands (git checkout...; git rebase...) you say
    git rebase v2.6.16
and you don't need the branch temp0.
-- Hannes
adr3nald0s@gmail.com· Dec 28, 2007, 15:35 UTC · re: Johannes Sixt · lore

Re: Anomalous conflicts during git rebase

Johannes Sixt <johannes.sixt@telecom.at> writes:
Show 19 quoted lines
> adr3nald0s@gmail.com wrote:
>> On a clone of linux-2.6:
>> 
>>     git checkout -b topic/test v2.6.15
>>     touch drivers/a-file.c
>>     git add drivers/a-file.c
>>     git commit -m 'Add a file'
>>     git checkout -b temp0 v2.6.16
>>     git rebase topic/test
>> 
>> I get the following:
>> 
>>     Applying [ACPI] handle ACPICA 20050916's acpi_resource.type rename
> ..
>>     CONFLICT (content): Merge conflict in drivers/char/hpet.c
> ..
>> Is this a bug, or is there a reason I am seeing conflicts in files
>> I've never touched?
>

I am not picking on you, Johannes, but I was expecting a response like this:

> You are using the rebase the wrong way round.

I am very well aware of how rebase is intended to be used. The components of git are not always used for their semantic purpose. As recommended frequently on this list, it is common to bend them to your purpose and use them in non-intuitive ways.

The purpose of the commands above is to have a git repository from 2.6.15 forward that has our code, XEN and some cherry-pick'd back-ported fixes integrated throughout. We will be doing a lot of git-bisect'ing to find where various things changed that break our code and certain edge-case usages of XEN.

So my question stands and it is not, "Adr3nalD0S, why _would_ you do this?" It is, "Why does git report conflicts that do not exist?"

P.S. This isn't the first project I have run into this on. It's just the first one where I decided to try and do something about it.

Daniel Barkalow· Dec 27, 2007, 23:45 UTC · re: adr3nald0s@gmail.com · lore

Re: Anomalous conflicts during git rebase

On Thu, 27 Dec 2007, adr3nald0s@gmail.com wrote:
Show 9 quoted lines
> 
> On a clone of linux-2.6:
> 
>     git checkout -b topic/test v2.6.15
>     touch drivers/a-file.c
>     git add drivers/a-file.c
>     git commit -m 'Add a file'
>     git checkout -b temp0 v2.6.16
>     git rebase topic/test

This will rebase temp0 (= v2.6.16) onto topic/test. This process linearizes the history being rebased, and conflicts in that history (that were resolved in the merges) show up when the second change to those lines gets introduced.

What you probably want is
...
 git commit -m 'Add a file'
 git checkout -b temp0
 git rebase v2.6.16
	-Daniel
*This .sig left intentionally blank*
adr3nald0s@gmail.com· Dec 28, 2007, 15:54 UTC · re: Daniel Barkalow · lore

Re: Anomalous conflicts during git rebase

Daniel Barkalow <barkalow@iabervon.org> writes:
> This will rebase temp0 (= v2.6.16) onto topic/test. This process 
> linearizes the history being rebased, and conflicts in that history (that 
> were resolved in the merges) show up when the second change to those lines 
> gets introduced.

Thank you for the explaination of why this is happening. This is something I had not considered WRT git-rebase.

When you say it linearizes history how is this done. Mentally I still have a model of where the "mainline" is at all times and I assumed that git-rebase was following this mainline. However, upon reflection, I realize this is naïve.

When there is a branch and a subsequent merge, does rebase follow both branches? If so, why does it not use the original merged result for the newly rebased file if there are no conflicts between the original merge result and the file that is being rebased onto as compared to their mutual ancestor?

Thanks again.
-- 
Adr3nalD0S
Daniel Barkalow· Dec 28, 2007, 17:58 UTC · re: adr3nald0s@gmail.com · lore

Re: Anomalous conflicts during git rebase

On Fri, 28 Dec 2007, adr3nald0s@gmail.com wrote:
Show 20 quoted lines
> Daniel Barkalow <barkalow@iabervon.org> writes:
> 
> > This will rebase temp0 (= v2.6.16) onto topic/test. This process 
> > linearizes the history being rebased, and conflicts in that history (that 
> > were resolved in the merges) show up when the second change to those lines 
> > gets introduced.
> 
> Thank you for the explaination of why this is happening.  This is
> something I had not considered WRT git-rebase.
> 
> When you say it linearizes history how is this done.  Mentally I still
> have a model of where the "mainline" is at all times and I assumed
> that git-rebase was following this mainline.  However, upon
> reflection, I realize this is naïve.
> 
> When there is a branch and a subsequent merge, does rebase follow both
> branches?  If so, why does it not use the original merged result for
> the newly rebased file if there are no conflicts between the original
> merge result and the file that is being rebased onto as compared to
> their mutual ancestor?

Rebase takes a list of commits that are in the current branch and aren't in the origin branch as what it's going to work on; these are ordered in some arbitrary way such that children always follow parents. It then resets to the origin branch's commit, and, in sequence, cherry-picks each of the commits in the working list. This has two implications:

 - the result is always linear, even if there are forks and merges in the 
   old history, because the new history is formed out of a single sequence 
   of cherry-picks, ignoring the shape of the original.
 - merge results from the old history aren't available, because they're in 
   a commit later in the list than the commit where the cherry-picking 
   finds a conflict.

In theory, of course, it could try to resolve conflicts by looking through the rest of the list for merges which would have those conflicts and using what that merge did. But that's not at all easy, due to the structure of the process, and it's rare that people actually want to rebase history with forks in it, anyway, so it hasn't been done.

	-Daniel
*This .sig left intentionally blank*
adr3nald0s@gmail.com· Dec 28, 2007, 18:33 UTC · re: Daniel Barkalow · lore

Re: Anomalous conflicts during git rebase

Daniel Barkalow <barkalow@iabervon.org> writes:
Show 9 quoted lines
> On Fri, 28 Dec 2007, adr3nald0s@gmail.com wrote:
>
>> When you say it linearizes history how is this done.
>
> Rebase takes a list of commits that are in the current branch and 
> aren't in the origin branch as what it's going to work on; these are 
> ordered in some arbitrary way such that children always follow parents. It 
> then resets to the origin branch's commit, and, in sequence, cherry-picks 
> each of the commits in the working list.
Thanks again for the clear explanation.
> In theory, of course, it could try to resolve conflicts by looking through 
> the rest of the list for merges which would have those conflicts and using 
> what that merge did.  

Given the implementation, this would be just plain ugly. I would not want to attempt to implement something like this, nor would I expect anyone else to do so.

Björn Steinbrink· Dec 28, 2007, 18:54 UTC · re: adr3nald0s@gmail.com · lore

Re: Anomalous conflicts during git rebase

On 2007.12.28 12:33:41 -0600, adr3nald0s@gmail.com wrote:
Show 21 quoted lines
> Daniel Barkalow <barkalow@iabervon.org> writes:
> 
> > On Fri, 28 Dec 2007, adr3nald0s@gmail.com wrote:
> >
> >> When you say it linearizes history how is this done.
> >
> > Rebase takes a list of commits that are in the current branch and 
> > aren't in the origin branch as what it's going to work on; these are 
> > ordered in some arbitrary way such that children always follow parents. It 
> > then resets to the origin branch's commit, and, in sequence, cherry-picks 
> > each of the commits in the working list.
> 
> Thanks again for the clear explanation.
> 
> > In theory, of course, it could try to resolve conflicts by looking through 
> > the rest of the list for merges which would have those conflicts and using 
> > what that merge did.  
> 
> Given the implementation, this would be just plain ugly.  I would not
> want to attempt to implement something like this, nor would I expect
> anyone else to do so.

I wouldn't make sense either. The conflict resolution that was done in the merge commit might need stuff from commits that haven't been rebased yet. For example a new function that was introduced later, it was available for the merge, but is still missing from the rebased linear history.

That said, what _might_ make sense is to teach interactive rebase with -p to use "cherry-pick -m1" or whatever instead of "merge" to recreate the merge commits (or maybe it does that already now? didn't check...). That way, it wouldn't have to rely on rerere being enabled to avoid the repeated resolving of the merge conflicts. I'm not sure how that would need to interact with new changes introduces into one of the rewritten branches.

Björn

← back to recent threads