Reputation: 17453
git format-patch OlderSHA..NewerSHA
normally creates one patch file per commit between OlderSHA
and NewerSHA
, exclusive of OlderSHA
(it's the base for the changes) and inclusive of NewerSHA
.
For instance, in this "real world" example, there are five commits between SHAs and so git format-patch
makes five patch files.
git format-patch 3caf9c2..0aa9968
0001-About-as-far-as-you-get-adding-new-module-to-RCP-wit.patch
0002-Add-a-trivial-service.patch
0003-Rename-files-and-add-lazy-module-class.patch
0004-Add-WCS-shim-and-add-to-testRouteMap.patch
0005-Add-module-to-routing-to-enable-lazy-loading.patch
I would like to produce a single file representing all of the changes between OlderSHA
and NewerSHA
that could be applied in a single command. I'm not looking to preserve state between the two SHAs; I only want the final differences stored in the patch file.
git format-patch --single-file-option? 3caf9c2..0aa9968
EVERYTHING_BETWEEN_SHAs.patch
I've looked over the docs on format-patch
a bit and if this is an option, I've missed it.
The problem is a little hard to google, as "single file", even "output single patch file" seem to converge on "I want patches that related to a single file" results instead.
Note that I also don't simply want to concatenate five files into one; I want the difference between the two commits in a single file with a single entry or section in the resulting file for each file's changes. (If foo
changes to bar
in commit 2 and back to foo
in commit 5, I don't want it to appear in SuperPatch.patch)
Does this option exist?
Upvotes: 0
Views: 176
Reputation: 30858
I'll add some notes to @jthill answer.
"All of the changes between OlderSHA
and NewerSHA
" is ambiguous. Considering such a scenario,
git init foo
cd foo
touch a.txt
git add .
git commit -mroot
git branch new
echo hello > a.txt
git commit -am'hello'
git checkout new
echo world > a.txt
git commit -am'world'
git checkout master
The log graph would be like,
* d1f8ac1 (new) world
| * dd5329d (HEAD -> master) hello
|/
* 8db55b4 root
git format-pach master new
would create one patch for d1f8ac1
only, whose diff is between 8db55b4
and d1f8ac1
, as if generated by git diff master...new
(three dots). It's different from the diff between dd5329d
and d1f8ac1
, as if generated by git diff master..new
(two dots).
When OlderSHA
is an ancestor of NewerSHA
, the 2 diffs are the same. When OlderSHA
is diverged from NewerSHA
, as described in the above scenario, the 2 diffs are different.
There is also a special case, in which OlderSHA
and NewerSHA
are unrelated. They don't share any common ancestor. git format-patch OlderSHA NewerSHA
generates patches for all commits reachable from both OlderSHA
and NewerSHA
. git diff OlderSHA..NewerSHA
and git diff OlderSHA...NewerSHA
generate the same diff.
When you need the ...
diff, use
git format-patch OlderSHA..$(git commit-tree -m - \
-p `git merge-base OlderSHA NewerSHA` NewerSHA^{tree})
When you need the ..
diff, use
git format-patch OlderSHA..$(git commit-tree -m - -p OlderSHA NewerSHA^{tree})
Here git format-patch OlderSHA..$()
could also be git format-patch -1 $()
. And for the special case, use the ..
diff way, or use the ...
diff way without -p $(git merge-base OlderSHA NewerSHA)
git commit-tree
creates a commit, whose message log is specified by -m
, whose parent is specified by -p
and whose tree is specified by NewerSHA^{tree}
. It's like to make a new commit based on OlderSHA
or the merge-base of OlderSHA
and NewerSHA
, and the commit has the exactly same code with NewerSHA
.
Upvotes: 0
Reputation: 60235
Probably the most compact way to get this in general would be
git format-patch OlderSHA..$(git commit-tree -m - \
-p `git merge-base OlderSHA NewerSHA` NewerSHA^{tree})
with the merge-base needed in case OlderSHA isn't strictly an ancestor. If it is, you can lose it and do
git format-patch OlderSHA..$(git commit-tree -m - -p OlderSHA NewerSHA^{tree})
and if you want a nicer commit message in the patch you can use multiple -m
's or lose the -m
and feed the full message in through commit-tree's stdin.
Upvotes: 1