git 日志历史简化
假设我有以下历史记录
D---E-------F
/ \ \
B---C---G---H---I---J
/ \
A-------K---------------L--M
git log --ancestry-path D..M 会给我
E-------F
\ \
G---H---I---J
\
L--M
但是,我只想要以下内容
E
\
G---H---I---J
\
L--M
或者
E-------F
\
I---J
\
L--M
本质上,我只想遍历一条路径,而不是两条路径。
这可能吗?如果是这样,命令是什么?
编辑:
我尝试过使用 --first-parent,但这并不完全是这样。 git log --first-parent G..M 给了我
F
\
H---I---J
\
L--M
它包括 F,因为 F 是 I 的第一个父母。 相反,我希望
H---I---J
\
L--M
任何帮助
解决方案(对我有用):
正如 @VonC 所说,没有任何一行可以做到这一点。所以我最终使用了 bash 脚本。
- 对于 'git log --ancestry-path G..M' 中的每个提交,
- 确定 $commit 的父级是否包含我们之前所在的提交
- 如果是,则继续。做一些有趣的事情。
- 如果不是,则跳过该提交。
例如, git log --first-commit G..M 是
H - F - I - J - L - M
但是,F 的父级是 E,而不是 H。所以我们省略 F,给我
H - I - J - L - M
耶!
Let's say I have the following history
D---E-------F
/ \ \
B---C---G---H---I---J
/ \
A-------K---------------L--M
git log --ancestry-path D..M will give me
E-------F
\ \
G---H---I---J
\
L--M
However, I would like just the following
E
\
G---H---I---J
\
L--M
Or
E-------F
\
I---J
\
L--M
Essentially, I would like to traverse down only one path, not two.
Is this possible? And if so, what is the command?
Edit:
I've tried using --first-parent, but this isn't exactly it.
git log --first-parent G..M gives me
F
\
H---I---J
\
L--M
It includes F, because F is the first parent of I. Instead I'd like
H---I---J
\
L--M
Any help would be appreciated
Solution (that worked for me):
As @VonC stated, there isn't a single one-liner that does this. So I ended up using a bash script.
- For each commit in 'git log --ancestry-path G..M'
- Determine if $commit's parent includes the commit we were previously on
- If yes, continue. do something interesting.
- If no, skip that commit.
For example, git log --first-commit G..M is
H - F - I - J - L - M
However, F's parent is E, not H. So we omit F, giving me
H - I - J - L - M
Yay!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不认为这是直接可能的(除非您事先知道要包含/排除的确切列表,这否定了遍历 DAG 的目的)
实际上, OP Ken Hirakawa 设法通过以下方式获得预期的线性历史记录:
对于每个提交,确保它是上一个提交的直接子级。
这是 Ken Hirakawa 编写的脚本。
这是我的脚本,用于创建在 历史简化 部分中提到的 DAG git log 手册页,对于
--ancestry-path
:您会在末尾找到我用来创建类似历史记录的 bash 脚本(使用根目录的名称和您的用户名来调用它) 。
我定义:
我得到:
从那里,我不能排除提交 I 的父级之一。
祖先路径确实返回:
这与日志手册页一致:
I don't think this is directly possible (unless you know in advance the exact list to include/exclude, which negates the purpose of walking the DAG)
Actually, the OP Ken Hirakawa managed to get the expected linear history by:
And for each commit, making sure it is a direct child of the previous commit.
Here is the script writtten by Ken Hirakawa.
Here is my script to create the DAG mentioned in the History Simplification section of the git log man page, for
--ancestry-path
:You will find at the end the bash script I used to create a similar history (call it with the name of the root dir, and your username).
I define:
I get:
From there, I cannot exclude one of the parents of commit I.
The ancestry-path does return:
which is consistent with the log man page:
我必须承认我不理解你的解决方案 - 它不适用于我的示例 - 但是如果我正确理解了你的用例(给定一对提交,你想要一个任意线性路径它们之间,没有分割),我有同样的问题,以下解决方案似乎有效:
生成的脚本如下所示:
它可以像
single-ancestry-path 那样调用.sh RANGE_EXPRESSION DECORATION_ARGS
,通常支持与git log
相同的装饰参数(实际上是git show
,每次提交都会调用一次),因此采用著名的来自 https://stackoverflow.com/a/9074343/74296 的lg2
示例,调用可能看起来像这样: 例如:已经九年了,所以我希望有一个更简单的答案,但我找不到。
I have to admit I didn't understand your solution - it didn't work for my example - but if I understood your use-case correctly (given a pair of commits, you want an arbitrary linear path between them, with no splits), I have the same problem, and the following solution seems to work:
A resulting script looks like:
It can be called like
single-ancestry-path.sh RANGE_EXPRESSION DECORATION_ARGS
, supporting generally the same decoration arguments asgit log
(it is in factgit show
, being called once per commit), so taking the famouslg2
example from https://stackoverflow.com/a/9074343/74296, the call might look like this: eg:It's been 9 years, so I would have hoped there would be an easier answer, but I can't find one.
我也不喜欢合并所带来的问题,并在我的主流历史中放弃了它。每当主分支上有大量合并时,我都会以相同的内容重新提交它,但作为单个提交。
这里,G'、I' 和 L' 是我重新提交合并结果的点。
分支描述只是描述了一个场景,我可以在其中可视化发生的问题树。因此,G 和 G'(类似于 I 和 I')的内容将是相同的,团队负责人已合并到开发人员的最新工作中。和L'一样,L也集成了主流的功能。
我完全理解避免问题并不等于解决问题,并且对那些现在面临问题的人表示同情。
I too dislike the problems that result from merging and have dispensed with having it in my mainstream history. Whenever there is a large merge onto a main branch I will recommit it with identical contents but as a single commit.
Here, G', I' and L' would be points where I have re-commited merge results.
The branch descriptions simply describe a scenario where I can visualize the problem tree occurring. So the contents of G and G' (similarly I and I') would be the same, the team leader having merged in the work-to-date of the developer. And L' the same as L, the feature integrated onto the mainstream.
I totally understand that avoiding a problem is not the same as solving it, and sympathize with those facing the problem now.