【问题标题】:Find the direct ancestors (parents?) of a git commit查找 git commit 的直接祖先(父母?)
【发布时间】:2017-07-20 18:37:39
【问题描述】:

开始一个新的 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 log 上的一级后代:

#( 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 github cherry-pick


    【解决方案1】:

    标题中问题的答案,查找提交的父级:

    git log --pretty=%p <commit>
    

    %P 获取完整的 sha1。

    但这不是你所期望的。

    假设在您的情况下我们有提交 A 和 B,并且 B 依赖于 A。A 可能是 B 的父级。也可能 B 是 A 之前的许多提交。

    尝试cherry pick B 到当前分支(例如master),就会发生冲突。运行git status 查看哪些文件有冲突。假设他们是foo.cbar.c

    运行git log master..B -- foo.c bar.c 并获得一组涉及foo.cbar.c 的提交。

    运行git log B..master -- foo.c bar.c 并获得另一组提交。

    通过提交消息和补丁比较这两组,以找到第一组中的依赖提交,不包括第二组中具有等效提交的那些。 Cherry-pick你真正需要的那些。

    实际情况可能更复杂。 A 和 B 可能是同一错误的相关提交。只选择 A 或只选择 B 不会产生冲突,但如果你不同时选择两者,则无法修复错误。

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

    【讨论】:

      【解决方案2】:

      您可以解析 diff 以查找旧版本中已更改的所有区域,然后使用 git log -L&lt;start&gt;,&lt;end&gt;:file... (*) 搜索之前触及此代码的提交。因此,对于任何给定的提交,您都可以更早地搜索它所依赖的提交。

      但是,我不确定是否可以根据需要正确定义图形,因为“补丁 B 依赖于补丁 A”的关系不是那么规则。例如,可以创建连续提交 A-B-C-D,这样当 D 依赖 A 和 C 而不是 B,而 C 依赖 B 而不是 A。那么你将如何绘制图形?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-25
        • 1970-01-01
        • 2022-08-19
        相关资源
        最近更新 更多