How do I get the interdiff between these two git commits?
I'm trying to view the difference between two revisions of the same commit in git. A diff of the diffs, basically. From what I've read so far, this is known as the "interdiff". I've read several tutorials on how to create interdiffs of git patches, but I haven't been able to get these methods to work in my particular case.
So here's the setup. I have two diverging branches, each with slightly different commits:
* 29e734f - (origin/feature_branch, new_commits) New commit 3 (69 minutes ago) <Ajedi32>
* b22ebea - New commit 2 (89 minutes ago) <Ajedi32>
* 09d42c2 - New commit 1 (2 hours ago) <Ajedi32>
| * 467e08f - (old_commits) Old commit 3 (4 weeks ago) <Ajedi32>
| * f2bf1cb - Old commit 2 (4 weeks ago) <Ajedi32>
| * 34a2187 - Old commit 1 (4 weeks ago) <Ajedi32>
|/
* 1b05a4a - (origin/base, base) Base commit (5 weeks ago) <Ajedi32>
In this example, I want to find the interdiff between "Old commit 3" and "New commit 3". I've tried creating a patch file from these two commits and running them through the interdiff
utility, but all I got was this:
1 out of 2 hunks FAILED -- saving rejects to file /tmp/interdiff-1.Kgwx8u.rej
interdiff: Error applying patch1 to reconstructed file
I'm not really sure what that means, so I'm kind of stuck now. Where do I go from here?
Note: I'm am not looking for git diff old_commits new_commits
here. I don't want the revisions to commits 1 and 2 included in the output.
Solution 1:
Git 2.19 introduces a new command, git range-diff
which does this:
git-range-diff - Compare two commit ranges (e.g. two versions of a branch)
git range-diff [--color=[<when>]] [--no-color] [<diff-options>] [--no-dual-color] [--creation-factor=<factor>]\ ( <range1> <range2> | <rev1>...<rev2> | <base> <rev1> <rev2> )
Description
This command shows the differences between two versions of a patch series, or more generally, two commit ranges (ignoring merge commits).
To that end, it first finds pairs of commits from both commit ranges that correspond with each other. Two commits are said to correspond when the diff between their patches (i.e. the author information, the commit message and the commit diff) is reasonably small compared to the patches' size. See
Algorithm
below for details.Finally, the list of matching commits is shown in the order of the second commit range, with unmatched commits being inserted just after all of their ancestors have been shown.
So, in your case:
git range-diff base old_commits new_commits
Would automatically match up the commits made in the old_commits
branch with the commits in the new_commits
branch, and display a summary of the differences between each commit.
Or, if you just want the changes from the last commit in each of those branches, you'd run:
git range-diff old_commits~..old_commits new_commits~..new_commits
For more on range-diff, see the official documentation.
Solution 2:
Perhaps something like this:
git log -p -1 new_commits > patch.new
git log -p -1 old_commits > patch.old
diff patch.old patch.new
Or for a terse one-liner (in bash
):
diff <(git log -p -1 old_commits) <(git log -p -1 new_commits)
Solution 3:
If there are few differences between the two commits, comparing lines removed and lines added (i.e. only those starting with + or -) is effective. It gets rid of the noise introduced by the hunks boundaries starting with @@ or the commit message body that are not significant:
diff -u --ignore-matching-lines '^[^+-]' \
<(git show 1d9e4ac) <(git show 7b8e5c9)
a sample outout is:
--- /dev/fd/63 2015-02-13 13:27:08.612683558 +0100
+++ /dev/fd/62 2015-02-13 13:27:08.616683527 +0100
@@ -62,13 +57,24 @@
}
diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h
-index 0113662..282cbeb 100644
+index 3b2e6e6..0a633a5 100644
--- a/src/crush/CrushWrapper.h
+++ b/src/crush/CrushWrapper.h
-@@ -874,6 +874,25 @@ public:
- return false;
+@@ -863,6 +863,36 @@ public:
+ if (!crush) return -1;
+ return crush_find_rule(crush, ruleset, type, size);
}
-
++
++ bool ruleset_exists(int const ruleset) const {
++ for (size_t i = 0; i < crush->max_rules; ++i) {
++ if (crush->rules[i]->mask.ruleset == ruleset) {
++ return true;
++ }
++ }
++
++ return false;
++ }
++
+ /**
+ * Return the lowest numbered ruleset of type `type`
+ *