Reputation: 44807
I'm trying to make a patch, following https://kernelnewbies.org/FirstKernelPatch
My patch needs to be made of my last two commits, not just the last one.
When I git format-patch HEAD^^
the result is:
0001-added-pca9570-driver.patch
0002-removed-whitespace.patch
I want just one patch with all those changes in it. The man page just says:
DESCRIPTION
Prepare each commit with its patch in one file per commit...
How can I make one patch from two commits?
Upvotes: 1
Views: 3447
Reputation: 1057
Here's another variant along the lines of Mark Adelsberger's answer, where I show how to (ab)use from an interactive rebase git rebase -i
.
So, you need to checkout a topic branch, squash the two commits into one commit and then craft a patch.
This is just so we have a sandbox to mess around.
$ git checkout -b squashing_commits
We will tell git to rebase the current tip of the branch (i.e. the HEAD). To do so, git needs a new HEAD. We can ask the new HEAD to be "current minus two commits". Like this:
$ git rebase -i HEAD~2
At this point, you'll see something like this:
pick 21760270369e Your first commit
pick 2bf13c197901 Your second commit
# Rebase 9f7b54945e64..2bf13c197901 onto 9f7b54945e64 (2 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
And you want to squash the second on top of the first, so you need the s
command:
pick 21760270369e Your first commit
s 2bf13c197901 Your second commit
# Rebase 9f7b54945e64..2bf13c197901 onto 9f7b54945e64 (2 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
Save this in your editor and exit (:wq
in vim). Now you can check the result, where you will see a squashed commit with both commit logs stacked.
$ git show HEAD
$ git format-patch -1
Profit!
Upvotes: 2
Reputation: 30938
git format-patch -2 --stdout > last2.patch
When you apply last2.patch
via git am
, two commits will be made.
cat 0001-added-pca9570-driver.patch 0002-removed-whitespace.patch > last2.patch
can work too.
Update:
After reading @Mark Adelsberger 's answer, I realise I may have misunderstood your need.
If you just need the diff patch exluding commit infomation, git diff HEAD^^ > last2.patch
is enough. The patch can be applied via git apply last2.patch
.
If you need the commit infomation as well, Mark's answer has provided one solution. There are several other similar methods.
git checkout -b patch
git reset HEAD^^ --soft
git commit
git format-patch -1
git checkout -
git branch -D patch
A patch that contains two commits' changes is created. You can apply it via git am
which automatically makes a commit.
It's also okay to apply the 2 commits first and then squash them into one.
Upvotes: 2
Reputation: 45819
Depends on what you need (and, somewhat, on why).
ElpieKay's answer will get you patches for both commits in a single file, but that's not necessarily the same thing as a single patch.
What hackerman suggests in comments isn't wrong, but for all practical purposes it's incomplete. Using a history rewrite to squash the commits is a valid way to set yourself up so that format-patch
will create truly a single patch with all the changes; but there are a couple ways to approach that, especially if you can't (or don't want to) permanently replace your two commits with a new single commit.
Given
X --- A --- B <--(master)
and wanting a patch with changes from both A
and B
, you could
git checkout HEAD^^
putting you in detached head state, then
git merge --squash master
git commit
creating a temporary commit with all the changes
X --- A --- B <--(master)
\
AB <--()
^HEAD
and now
git format-patch HEAD^
will produce the patch, and
git checkout master
will put everything back to normal. The potential downside of this is that metadata in the email headers (e.g. the SHA1 ID from which it says the patch was created) won't line up with your real history.
I assume, since you're looking at format-patch
, that you need the email wrapping? I mean, if not it may be a lot simpler to just git diff HEAD^^
or something similar...
Upvotes: 2