I know there has been very similar questions here, but they didn't solve my problem. Perhaps there's something I'm not understanding well.
This is a portion of the commit history of fitnesse (https://github.com/unclebob/fitnesse/):
* | | | | | | | | | | | | | | | fa86be8 Avoid possible issue when using CachingPage under heavy memory load.
|/ / / / / / / / / / / / / / /
* | | | | | | | | | | | | | | 7b4a07a Merge pull request #256 from barredijkstra/fitnesse_issue_250
|\ \ \ \ \ \ \ \ \ \ \ \ \ \ \
| * | | | | | | | | | | | | | | ecf5891 Fixed test checking for OS specific exception message.
| * | | | | | | | | | | | | | | 082236e Added rendering of cause exceptions. Fix for unclebob/fitnesse#250
* | | | | | | | | | | | | | | | a92b37f Merge pull request #243 from amolenaar/fix/243-hash-table-rendering
I want the list of commits between 2 commit hashes. In this particular case, I want the commits between ecf5891
and 7b4a07a
, and I expect the result to be:
ecf5891
7b4a07a
Si far I've been using git rev-list commit_hash_from_here^..commit_hash_up_to_here
and it has worked fine with linear history. However, in this case I get a lot more commits.
I've tried this and it works just as expected:
git log --since='<date ecf5891>' --until='<date 7b4a07a>'
(I've manually searched for those 2 dates).
One possible solution is to get the 2 dates and just do that, but I think there should be a better way.
Edit:
7b4a07a
parents are ecf5891
and a92b37f
. So far, the solutions work fine if I want to go from ecf5891
to 7b4a07a
, but if I want to go from a92b37f
to 7b4a07a
I want to get:
7b4a07a
ecf5891
082236e
a92b37f
but I don't get a92b37f
To see the changes between two commits, you can use git diff ID1.. ID2 , where ID1 and ID2 identify the two commits you're interested in, and the connector .. is a pair of dots. For example, git diff abc123.. def456 shows the differences between the commits abc123 and def456 , while git diff HEAD~1..
If you have the hash for a commit, you can use the git show command to display the changes for that single commit. The output is identical to each individual commit when using git log -p .
You could also have two or more different commits off the same parent commit ( parent hash ), and this is fine too, but every commit hash will vary. Unless you're surprisingly, mind blowingly (un)lucky.
The commit hash is an SHA-1 hash made up of a few properties from the commit itself. As mentioned above, it is a lot more complex than this post can go into, but understanding the fundamentals is a great first step. The git hash is made up of the following: The commit message.
I think that you`re looking for --ancestry-path, in your case:
git rev-list --ancestry-path 7b4a07a..ecf5891
"Between" is a somewhat slippery notion, when it comes to git commits.
The text you show above, with a snippet of graph output, shows why from^..to
produces more than just those two commits: the to
part is a merge commit.
The notation A..B
is really just shorthand for B ^A
. That is, "everything starting from B
and working backwards, minus everything starting from A
and working backwards". But B
is a merge commit, so "everything starting there and working backwards" uses both parents.
Here the first parent of 7b4a07a
is a92b37f
(not in your [original] snippet above but I cloned the linked repo and found it). We can refer to it symbolically, though, and I will below. The second parent of 7b4a07a
is ecf5891
, the "from" part you're interested in.
When you ask for:
ecf5891^..7b4a07a
that means:
7b4a07a ^ecf5891^
which is the same as:
7b4a07a ^082236e
which gets you both parents of the merge, and then trims off everything from 082236e
back. You need to trim off everything from 7b4a07a^
—the first parent—and back as well:
git rev-list 7b4a07a ^ecf5891^ ^7b4a07a^ git log --oneline 7b4a07a ^ecf5891^ ^7b4a07a^
In general, though, you have to figure out which descendent line(s) to chop-off.
Edit: you can stick with the A..B
notation, but you do need to add the extra "exclude". So jthill's answer works too, once you move the hat to the front.
Re your edit ("if I want to go from a92b37f
to 7b4a07a
"): we're back to that issue of "between" being a slippery notion. Which commits are "between"? There's a direct line from a92b37f
to 7b4a07a
, because a92b37f
is one of the two parents of the merge commit 7b4a07a
. So by the earlier logic ("commits directly on an ancestral line", perhaps "inclusive") that would just be one, or maybe both, of those two commits. But you say you want two commits that are not, in any ancestral sense, related to a92b37f
at all. Why do you want those two particular commits? What makes 082236e
"interesting" and 082236e^
, its parent, "uninteresting"?
First identify the relevant 2 commit hashes that you need for getting the list of commit hashes in between them by using
git log --oneline
Then you can pick the relevant two commit hashes and find the commit hashes in between them by using
git log <commit hash 1>..<commit hash 2> --oneline | cut -d " " -f 1
Add ^7b4a07a~ to also exclude everything reachable from the merge's first parent. You're only excluding what's reachable from its second parent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With