列表在 git 中的两个提交散列之间提交

我知道这里有很多类似的问题,但是他们没有解决我的问题。 也许有些事我不太明白。

这是适应性提交历史(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

我想要两个提交哈希之间的提交列表。在这种特殊情况下,我希望在 ecf58917b4a07a之间进行提交,我希望结果是:

ecf5891
7b4a07a

到目前为止,我一直在使用 git rev-list commit_hash_from_here^..commit_hash_up_to_here,它的工作良好的线性历史。然而,在这种情况下,我得到了更多的提交。

我已经试过了,效果和预期的一样:

git log --since='<date ecf5891>' --until='<date 7b4a07a>'

(我已经手动搜索了这两个日期)。

一个可能的解决办法是得到两个日期,只是这样做,但我认为应该有一个更好的方法。

编辑: 父母是 ecf5891a92b37f。到目前为止,如果我想从 ecf58917b4a07a,解决方案工作得很好,但是如果我想从 a92b37f7b4a07a,我想得到:

7b4a07a
ecf5891
082236e
a92b37f

但我没有 a92b37f

101239 次浏览

Add ^7b4a07a~ to also exclude everything reachable from the merge's first parent. You're only excluding what's reachable from its second parent.

"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 B ^A0.

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

I think that you`re looking for --ancestry-path, in your case:

git rev-list --ancestry-path 7b4a07a..ecf5891