73

How can I generate patch for all commits in a given branch by knowing only the branch name?

This step is part of a complex workflow all of which is being automated. Hence requiring someone to manually determine the first commit in the branch is not an option.

Note that anything relying on reflog is not an option either because changes in the branch are not made locally.

funnydman
  • 2,957
  • 3
  • 13
  • 29
akirekadu
  • 1,954
  • 2
  • 21
  • 28
  • Isn't the whole point of git that it doesn't matter if the changes are made locally or not? Please elaborate on your last sentence a lot – Mad Physicist Mar 15 '17 at 04:09
  • check --fork-point notes here https://git-scm.com/docs/git-merge-base – akirekadu Mar 16 '17 at 01:22
  • 1
    Note that you can specify git tags in the commands, so if your automated system(s) can automatically add tags, you can create diffs between these points if you wish. – MikeW Jun 13 '19 at 12:23

1 Answers1

99

If you know from which branch your "given branch" has been created, then making a patch is easy:

git diff master Branch1 > ../patchfile
git checkout Branch2    
git apply ../patchfile

(and you can generate a patch applicable without git too)

But finding the right "creation commit" of a branch can be complex: see "Finding a branch point with Git?"

The OP akirekadu used:

git format-patch $(git merge-base --fork-point master)..branchB 

You can see it used in "git diff between working copy and branch base"

legends2k adds in the comments:

One can verify the generated patch with git apply --stat patchfile
This won't apply, but give the details of the patch.


Warning: AGP notes in the comments that:

$(git merge-base --fork-point master)..branchB command may not find the correct branch root revision every time


ijoseph points out in the comments

Incidentally, Phabricator handles this kind of stuff seamlessly by automatically generating those patch files for each push.

VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283
  • Let's call the branch in question 'B'. The 'source' branch from where B was created is known. However, generating a diff comparing to it will not produce correct results (ie, we need all the changes made only in this branch B) because the source branch might have changes ever since B was created. – akirekadu Mar 16 '17 at 01:26
  • @akirekadu yes, that is why I referred in the answer to http://stackoverflow.com/q/1527234/6309: finding the *current* point of origin of a branch is hard. – VonC Mar 16 '17 at 08:16
  • Fair enough. I ended up going with: git format-patch `git merge-base --fork-point master`..branchB – akirekadu Mar 16 '17 at 17:52
  • @akirekadu Good point. I have included your comment in the answer for more visibility, and added a reference to the fork-point option. – VonC Mar 16 '17 at 17:55
  • 1
    You would need 'git format-path ' in front of the command you added. ie, `git format-patch \`git merge-base --fork-point master\`..branchB` – akirekadu Mar 16 '17 at 21:05
  • One can verify the generated patch with `git apply --stat patchfile`; this won't apply but give the details of the patch. – legends2k May 14 '20 at 13:06
  • @legends2k Thank you. I have included your comment in the answer for more visibility. – VonC May 14 '20 at 13:51
  • @AGP Could you ask a separate question illustrating how this answer does not address your use cse? – VonC Jun 15 '20 at 14:57
  • @VonC It is not reuqired to asked as a separate question. It can be added that $(git merge-base --fork-point master)..branchB command may not find the correct branch root revision every time. That should be enough. – AGP Jun 22 '20 at 08:50
  • Incidentally, [Phabricator](https://github.com/phacility/phabricator) handles this kind of stuff seamlessly by automatically generating those patch files for each push. – ijoseph Sep 30 '20 at 19:37
  • 1
    @ijoseph Thank you. I have included your comment in the answer for more visibility. – VonC Sep 30 '20 at 19:50