【问题标题】:find out which git commit a file was taken from找出文件来自哪个 git commit
【发布时间】:2015-10-04 06:19:48
【问题描述】:

一个不使用版本控制的合作者向我发送了一个包含一些本地修改的文件。现在他去度假了。我想知道他的编辑基于哪个版本。

我认为最有希望的方法是以某种方式迭代最近的提交并检查差异的长度是最小的。

是否有一些现成的功能,或者我需要自己编写代码?我自己不是 git 专家,最有希望的方法是什么?

【问题讨论】:

  • 等到他们度假回来,告诫他们不要提供完整的上下文来说明他们修改了什么以及它来自哪里,然后从那里开始。
  • 虽然这当然是一个明智的建议,但在目前的情况下,等待约 1 个月对我没有帮助。
  • 根据更改的性质,从当前在野外(master)中创建一个分支并查看碰撞可能并不可怕。除非他们所做的更改是关键任务,否则真的不应该那么急于让他们进入 - 但我远不能决定你会在什么“匆忙”中。就个人而言,如果他们 关键更改,不提供它们来自何处的完整上下文将是一个非常严重的问题,因为它会阻碍维护人员及时得到正确的修复。
  • 问题是该合作者是资深项目开发者之一。这些更改很可能实际上并没有破坏任何东西,主要问题是将这些更改与同时发生在主干上的更改合并。
  • 不使用版本控制的高级开发者……世界是#@%$ed。

标签: git


【解决方案1】:

我不知道有什么标准的 git 命令可以做到这一点。但是一个简单的脚本可以帮助完成这项任务。首先,创建一个tmp-branch 并将文件提交到这个分支。然后创建一个如下所示的简单脚本,以打印该文件与该文件的 50 个最新版本的不同之处。

#!/bin/bash

BRANCH="tmp-branch"
FILE="path/to/file.txt"
RECENT_COMMITS=$(git rev-list -50 master -- $FILE)

for COMMIT in $RECENT_COMMITS
do
    echo -n "$COMMIT: "
    git diff $BRANCH $COMMIT --shortstat -- $FILE
done

不是全自动的,但它会给你如下输出。在此输出中,您标识更改最少的版本。在我的示例中,我用作示例的简单更改基于edff0c0

e2b2c157a81e0523e7d4a0a52df79cb4fce981ac:  1 file changed, 12 insertions(+), 16 deletions(-)
154d84736f4df3dd968450599dc254cda56f2057:  1 file changed, 12 insertions(+), 13 deletions(-)
ba11ecc3a4d8268f43589fb929f0877e65879f13:  1 file changed, 11 insertions(+), 13 deletions(-)
017a7a5abdffeb37671a03c0db2e32c37b0ee6bd:  1 file changed, 8 insertions(+), 9 deletions(-)
cc97d3453ebde37b02a42ca7263bf7a983222d4d:  1 file changed, 8 insertions(+), 5 deletions(-)
a84adb9e337d2cf1e851924cf27f5f0bfdca790f:  1 file changed, 7 insertions(+), 4 deletions(-)
9a3c10cefc133792377851b1b5cb8a69d3ffd788:  1 file changed, 7 insertions(+), 3 deletions(-)
edff0c0155b77e39599402574ba1c4aa02c1bbac:  1 file changed, 6 insertions(+), 2 deletions(-)
413800ab0de606548c0c69b4b35e50b527d33d7f:  1 file changed, 13 insertions(+), 2 deletions(-)
af689f1d6d76303d8e39311f48a977b87260586e:  1 file changed, 13 insertions(+), 2 deletions(-)
25123d4196533a0f3ce718a288bc3c5d975ad865:  1 file changed, 24 insertions(+), 3 deletions(-)
e7ca01b247f7e32010f256b55696c3ecb1d72144:  1 file changed, 26 insertions(+), 5 deletions(-)
6e9c2a561cc606f34ccb2cc918b297187c2e8c42:  1 file changed, 33 insertions(+), 23 deletions(-)

我不确定这种方法是否万无一失。您可能还应该看看几个周围的提交。

【讨论】:

  • echo -n 已损坏,因为git 从第 0 列开始打印,并且提交 ID 被覆盖。
  • @FelipeAlvarez 我想不知何故,不同环境之间的行为必须有所不同。在我的环境中,我得到了正确的输出(Ubuntu 15.04,git 2.1.4)。对于这种情况,我想另一种方法是将 git diff 命令的输出保存在一个变量中,并从同一个 echo 命令输出 commit id 变量和 diff 变量。
  • 或使用printf 代替echo
【解决方案2】:

我会用同事的更改创建一个新分支,然后使用 git merge-base:

git merge-base 找到两个提交之间的最佳共同祖先,以便在三向合并中使用。如果后者是前者的祖先,则一个共同祖先比另一个共同祖先更好。没有更好的共同祖先的共同祖先是最佳共同祖先,即合并基础。请注意,一对提交可以有多个合并基础。

【讨论】:

  • 我认为这不是他想要的。我认为 git merge-base 搜索 提交树 并找到哪个“祖先”是最好的。这意味着,它会非常敏感地知道您实际上是在哪里创建了虚假的新分支。如果你从 master-head 中创建它,结果将与你从一些非常古老的提交中创建它不同。我认为,如果 OP 知道他的文件来自哪个提交,以及他何时直接在该提交上创建了一个分支,我认为 merge-base 会工作得最好。我认为这在这种情况下完全行不通。但是,我没有尝试过。如果我错了,我会很高兴!
猜你喜欢
  • 2016-12-01
  • 2020-09-15
  • 2020-10-30
  • 2019-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-08
  • 2011-04-06
相关资源
最近更新 更多