Using `git show` to create and apply patches spanning multiple commits

26.8k views Asked by At

Lately I've been using git show <hash> to create diffs for later reference because it's easier to type than git diff <hash>~ <hash> and it shows the commit information (timestamp, user, hash, comment). You can then use git apply <filename> to apply the patch.

I discovered that git show -3 will show the last three commits along with the same extra information. However, git apply will squash it all into the working directory as unstaged changes, and loses all the commit information.

Is there something in git that will apply all that information? It would be a lot simpler to just pass in a flag than breaking the patch up into three files, applying them severally, and creating new commits.

3

There are 3 answers

1
Lily Ballard On BEST ANSWER

You can use git format-patch to generate MIME emails representing the commits, including their metadata (message, authorship, etc). You can then reapply these with git am.

So git format-patch HEAD~3 will generate 3 patches for the last 3 commits, and you can then pipe these all into git am. If you want to be simpler, git format-patch --stdout HEAD~3 will send the MIME messages out on stdout, so you can pipe them around where you want instead of dealing with 3 separate files.

Of course, if you're trying to save commits to reference later, why not just tag them? You can then reapply the commits from them using git cherry-pick.

0
Adam Dymitruk On

try git bundle for sending specific parts of history.

0
Campa On

In Linux you can pipe your delta-generator --- git-show or git-diff, for instance --- with the git-apply command.

(It is also probable safer to always enable 3-way merge with the -3 option)

> git show <sha1> [<path>] | git apply -3
> git diff <sha1-a> <sha1-b> [<path>] | git apply -3

Examples:

  • apply the edits on a specific file made in abcdef:
> git show abcdef dir/file.c | git apply -3
  • apply difference on a file of two different commits abcdef and 123456

> git diff abcdef 123456 foo.h | git apply -3

See also: https://stackoverflow.com/a/12320940/1329340