views:

599

answers:

4

How do I get a patch from a commit in order to send it to another developer? And how do I best avoid a merge conflict with this patch when merging our trees at a later date?

If you know how please explain how to do this in your VCS of choice such as subversion, git, Mercurial, bzr or etc.

+1  A: 

In SVN you can simply make your changes then before commiting, pipe the output of the svn diff to a file as such

svn diff > mypatch.diff

you can then revert your changes and apply the patch at a later date using

patch -p0 -i mypatch.diff

As always don't blindly apply patches to your code and always inspect them first.

You may also find that the patch will break your source code if the source files have changed significantly enough since the patch was taken.

You also can not guarantee that there will not be merge conflicts when you attempt to check in the code.

Xian
+2  A: 

In git you can pipe the output of git-diff between two commits like this:

git diff fa1afe1 deadbeef > patch.diff

Send the patch.diff to the developer and let him git-apply it to his workspace like this:

git apply patch.diff

If the other developer already has the commits available in his repository he could always pipe it in himself without merging like this:

git apply < git diff fa1afe1 deadbeef

You can then add and commit the changes in the diff the usual way.


Now here comes the interesting part when you have to merge the patch back to the master branch (that is public). Consider the following revision tree where C* is the applied patch from C in the master branch:

A---B---C---D          master, public/master
     \
      E---C*---F       feature_foo

You can use git-rebase to update the topic branch (in this example named feature_foo) with it's upstream head. What that means is when you type in the following:

git rebase master feature_foo

Git will rearrange the revision tree like this and will also apply the patch itself:

A---B---C---D          master, public/master
             \
              E*---F*  feature_foo

Merging to the upstream branch will now be an easy fast-forward merge. Also check that the new commits E* and F* work as the previous E and F respectively.

You can do the same thing against another developer's branch using the same steps but instead of doing it on a public repo, you'll be fetching revisions from the developer's repository. This way you won't have to ask the other developer for a patch if it is already available from what he published at his repo.

Please note to never rebase a public branch because the command will rewrite git history which is something you don't want to do on branches that people depend on and will create a mess when merging to remote repositories. Also never forget to integrate often so others in your team can take part of your changes.

Spoike
Found out afterwards that you can do the same thing with git format-patch to format a patch and git am to apply and commit the patch. Example:git format-patch -k --stdout R1...R2 | git am -3 -k
Spoike
+1  A: 

Bzr handles sending a "merge directive", meaning it sends the patch for you so that the other party can simply click "OK" to merge and there's less futzing around with patch/apply etc.

just: $ bzr send -o mycode.patch

hendrixski
bzr send only creates a merge directive between two different branches. I was looking for how to create patches like single commits or cherry-picking, and how merging works when applying those patches.
Spoike
A: 

In Subversion there is no nice way of doing this. Yes, you can use svn diff + patch but this will only postpone your problems until you are going to merge and by then chances are that you've forgotten about it.

The way you would do it in Subversion would be to create a branch, do the commit on the branch and ask the recipient of the patch to switch to the branch. Then you can merge the branch back to trunk in the usual way.

JesperE