Reputation: 5127
Morning all, Let's say I have a series of commits as follows:
I know I can use
$ git diff -c --binary abc000..def555 > /tmp/abc000_def555.patch
to produce a patch to upgrade a system from abc000 to def555.
But what if I wanted to (for reasons to dull to get into) exclude def333 from the patch - how can I do this? Note that I do not want to revert def333, its just that I do not want the patch to incorporate this commit.
Thanks
Upvotes: 22
Views: 8625
Reputation: 81
Old question, however I needed to do this to visually inspect the difference between two commits and I wanted to exclude some of the commits.
The most effective and easy way I found was to first use the git-format-patch command to generate all the commits in patch files on disk in a dedicated directory; and then use a command to find and delete those files that contained commit numbers which I wanted to remove. Finally, I concatenated all the remaining patch files into a single file which is what the OP is asking for.
On a Linux system with Bash you can do the following:
git format-patch --full-index <start-commit>..<end-commit>
mkdir all_patches
mv *.patch all_patches/
cd all_patches/
rm -rf `egrep -lsr "commit1-to-exclude|commit2-to-exclude|commit3-to-exclude" . `
cat * >> final.diff
Upvotes: 0
Reputation: 13468
It is not possible to git diff
and exclude one or more commits. You have to make a new branch, revert the unwanted commits, then diff it and make a patch:
git checkout --branch <branch-name>-diff-branch // Create a throwaway branch.
git revert <unwanted-sha> // Get rid of the unwanted commit. Do this as many times as necessary, you cannot revert multiple SHAs at once.
git diff > new.patch // Create your new patch.
git checkout - // Checkout previous branch, nice trick eh?!
git branch --delete --force <branch-name>-diff-branch // Delete the throwaway branch.
p.s. I didn't want to butcher torek's answer too much so I posted a new one that I think is more concise.
Upvotes: 8
Reputation: 7138
You could try using git rebase -i and then drop the commit you don't need. Another way is to cherry-pick the commits you need on a different branch.
Upvotes: 1
Reputation: 488453
Actually all git diff
s are commit-pair-wise: the above compares the trees/files in abc000
against those in def555
. If for instance def333
changes dir/file
but there are no changes to dir/file
between abc000
and def555
(e.g., the change in def333
is canceled out by something along the way) you might not see dir/file
in there at all.
In general, though, changes made in def333
will have altered dir/file
in a way that shows up when comparing the version in abc000
against the one in def555
. So you will probably see that change.
The easiest way to get a diff that shows "what def555
would look like if def333
were reverted" is to do just that: create a tree (on a temporary branch) with the change reverted. To do it with an actual named branch, you might do something like this:
git checkout def555 # by ID, so that you get a "detached HEAD"
git checkout -b temp-branch
git revert --no-edit def333
git diff [options] abc000
git checkout somebranch; git branch -D temp-branch
What if you don't want a temp branch? Well, that's trivial: just don't create one. Get a "detached HEAD" as above, do the revert as above, and then git checkout somebranch
. There's no temporary branch to delete, except for the unnamed one that git will warn that you are leaving behind ... which is just what you wanted.
Upvotes: 12
Reputation: 10305
I would say you create a new branch, cherry-pick the commits you need and then do the diff
Upvotes: 3