12

This is a imaginary problem, but I'm having real problems with patches. Let's say I have a project with the following git history:

A - B - C

Now if I receive two patches, C1 and C2, that are meant to be applied on C, how should I handle them? If I apply patch C1 first, then I will not be able to apply patch C2 because the repository has become:

A - B - C - C1

Is it possible to apply them both, or do I have to reply to the person sending C2 telling him/her to update the patch?

Now suppose I go offline and work and commit so that the repository becomes:

A - B - C - D - E

Then I check my email and receive a patch for C. Again, is it possible to simply apply that patch, or do I have to ask for an update to the patch?

Jeffrey Bosboom
  • 13,313
  • 16
  • 79
  • 92
phunehehe
  • 8,618
  • 7
  • 49
  • 79
  • Can you do a multiway merge as it's explained here: http://book.git-scm.com/5_advanced_branching_and_merging.html ? – Augusto Mar 07 '11 at 15:25
  • @Augusto Can I merge patches? I think I can only apply patches, not merge. Or is that possible with git? – phunehehe Mar 07 '11 at 15:28
  • my bad - I assume that by patches you meant a link to a fork with a patch. Keeping the same concept, you could create 2 feature branches from C, apply a patch to each of the feature branches and then merge them to the head... I'm sure this will work, but it sounds like a lot of work for me, maybe someone has a better solution. – Augusto Mar 07 '11 at 15:31

3 Answers3

8

The classic way is to:

  • apply the received first patch,
  • refuse any patch which isn't fast-forward and ask the sender to rebase his/her repo first, then re-check the patch, and resend it.

The general idea is that it isn't up to you to solve merge conflicts: only the creator of the patch has the necessary knowledge to solve any conflict with the current source code.

As Linus Torvalds (creator of Git) said in his 2007 Google talk:

So what happens is, remember, distribution means nobody is special.
So instead of me merging, I just push out my first tree, that did not have any merge issues, and I tell the second person:

"hey, I tried to pull from you, but I had merge conflicts and they weren't completely trivial, so I decided you get to do the honors instead."

And they do. And they know what they are doing because it's their changes. So they can do the merges and they probably think I am a moron because the merge was so easy and it is obvious I should have taken their code, but they do the merge and they update their tree, and say "hey, can you pull from me now", and I pull from them and they did all the work for me.

That's what is all about: they did all the work for me. So,... and I take the credit. Now I just need to figure out the step 3: profit.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
5

Most of the time, C2 will apply on top of C1. It's only if they're edits to overlapping sections of the same files that you'll get a merge conflict. Git will take all the parts of the patch that don't conflict, and insert conflict markers that help you resolve the merge.

As for what to do, it depends how large your project is and how competent you are in that section of the code -- I've always just fixed up the conflicts myself, as long as the submitter used a reasonably recent checkout as the base for their patch.

Another commenter mentioned Linus' quote saying that he always makes other people resolve conflicts, but even this isn't quite true; he often asks people to leave conflicts unresolved when sending pull requests so he gets a shot at them.

cjb
  • 699
  • 1
  • 6
  • 8
  • +1 from "another commenter";) My quote from Linux was a bit tongue in cheek, in that it isn't a universal solution, simply a good illustration of the DVCS process and its "publication" workflow (http://stackoverflow.com/questions/2563836/sell-me-distributed-revision-control/2563917#2563917). – VonC Mar 07 '11 at 22:51
3

You can totally at least try to apply all these patches. You may potentially get merge conflicts, and as VonC suggests, you might want the patch submitters to solve them, or you might do it yourself as cjb says! In any case, here's what you want to do.

First case: two patches, C1 and C2.

# apply C1
git am C1.patch
# create a temporary branch (use a real name instead of C2)
git checkout -b C2 C
# apply C2
git am C2.patch
# return to master
git checkout master
# merge the other branch
git merge C2
# and delete the other branch
git branch -d C2

You can handle the second case similarly; it's just that instead of applying C1 you've made commits D and E yourself.

And of course, if the merge fails, and it looks too scary for you to sort through yourself, just blow it away and tell the submitter of C2 to fix it on their end. (git reset --merge; git branch -D C2)

Cascabel
  • 479,068
  • 72
  • 370
  • 318
  • So you isolate the second - riskier - patch in its own local branch, before merging it to C if all goes well. Nice. +1 – VonC Mar 07 '11 at 22:53