找到git commit的直接祖先(parent?)

启动一个新的repo并添加一些提交:

#( 03/01/17@10:50am )( tim@tim ):~
   mkdir test && cd test && git init

Initialised empty Git repository in /home/tim/test/.git/

.

#( 03/01/17@11:17am )( tim@tim ):~/test@master✔
   touch readme && git add --all && git commit -am "readme"   

[master (root-commit) 1b7f299] readme
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 readme

.

#( 03/01/17@11:17am )( tim@tim ):~/test@master✔
   touch howto && git add --all && git commit -am "howto" 

[master fd46c4c] howto
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 howto

.

#( 03/01/17@11:19am )( tim@tim ):~/test@master✔
   touch la && git add --all && git commit -am "add la"

[master 4680089] add la
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 la

.

#( 03/01/17@11:20am )( tim@tim ):~/test@master✔
   ls
howto  la  readme

#( 03/01/17@11:20am )( tim@tim ):~/test@master✔
   echo "hello" >> readme && echo "hello" >> howto

#( 03/01/17@11:20am )( tim@tim ):~/test@master✗✗✗
   git commit -am "edit readme and howto"
[master 8969440] edit readme and howto
 2 files changed, 2 insertions(+)

所以现在我们有以下提交:

commit 8969440d52e578113f609d948e6ffd06cec96fa9
Author: Tim Richardson <tim@x.com>
Date:   Wed Mar 1 11:20:54 2017 +0000

    edit readme and howto

commit 4680089c7c1a0ead84f6b2973fd6d9e1356fd5c0
Author: Tim Richardson <tim@x.com>
Date:   Wed Mar 1 11:20:06 2017 +0000

    add la

commit fd46c4cf593752ec8163d8db21042c8dd336f529
Author: Tim Richardson <tim@x.com>
Date:   Wed Mar 1 11:18:09 2017 +0000

    howto

commit 1b7f299c5ad4fc50ce4913ab4cdbbdc761db0487
Author: Tim Richardson <tim@x.com>
Date:   Wed Mar 1 11:17:50 2017 +0000

    readme

让我们签出一个名为test的新分支并将其重置为初始提交:

#( 03/01/17@11:26am )( tim@tim ):~/test@master✔
   git checkout -b test
Switched to a new branch 'test'

#( 03/01/17@11:27am )( tim@tim ):~/test@test✔
   git reset --hard 1b7f299c5ad4fc50ce4913ab4cdbbdc761db0487

HEAD is now at 1b7f299 readme

如果我挑选提交8969440它失败,因为它依赖于fd46c4c和1b7f29而不是4680089:

#( 03/01/17@11:27am )( tim@tim ):~/test@test✔
   git cherry-pick 8969440
error: could not apply 8969440... edit readme and howto
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

但是我可以从1b7f299c中挑选4680089c7而没有任何冲突,即使它不是git日志中的第一级后代:

#( 03/01/17@11:28am )( tim@tim ):~/test@test✗✗✗
   git reset --hard 

HEAD is now at 1b7f299 readme

#( 03/01/17@12:10pm )( tim@tim ):~/test@test✔
   git cherry-pick 4680089c7

[test de3878f] add la
 Date: Wed Mar 1 11:20:06 2017 +0000
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 la

因此,补丁之间存在依赖关系图,如下所示:

+---------+
|         |
| 1b7f299 +--------+
|         |        |
+---------+        |      +----------+
                   +----->+          |
                   |      | 8969440  |
+---------+        |      |          |
|         |        |      +----------+
| fd46c4c +--------+
|         |
+---------+


+---------+
|         |
| 4680089 |
|         |
+---------+

我的问题是给出一个更大的回购,我如何根据补丁计算依赖图?如何使用git来判断哪些提交依赖于其他提交?

最佳答案 标题中的问题的答案,找到提交的父级:

git log --pretty=%p <commit>

完整sha1的%P.

但这不是你所期待的.

假设我们在你的情况下提交了A和B,而B依赖于A. A可能是B的父级.也可能B是A之前的许多提交.

尝试将B选择到当前分支(例如master),并发生冲突.运行git status以查看哪些文件存在冲突.假设它们是foo.c和bar.c.

运行git log master..B – foo.c bar.c并获取一组触摸foo.c或bar.c的提交.

运行git log B..master – foo.c bar.c并获取另一组提交.

通过提交消息和补丁比较这两个集合,以查找第一个集合中的依赖项提交,排除那些在第二个集合中具有等效提交的集合.樱桃挑选你真正需要的那些.

真实情况可能更复杂. A和B可能是同一个bug的相关提交.樱桃选择只有A或只有B导致没有冲突,但如果你不挑选两者,那么这个bug就无法解决.

如果您创建了一个良好的工作流程,例如将所有相关提交压缩为一个,并在最开始时使用提交跟踪每个错误/功能,则可以节省大量时间和精力.找到记录并逐个挑选提交或压缩提交要比搜索缺少的依赖提交容易得多.可能存在冲突,但您可以确定它不是因为您错过了一些依赖项提交.

点赞