找出一个文件来自于哪个git提交

11

一位协作者没有使用版本控制,给我发送了一个带有本地修改的文件。现在他去度假了。我想找出他的编辑是基于哪个版本的。

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

是否有现成的功能可以实现这一点,还是我需要自己编写代码?作为一个不太熟悉Git的人,最有前途的方法是什么?


3
等待他们从度假回来后,训斥他们没有提供修改的全部背景信息和来源,然后再继续处理。 - Makoto
1
虽然这肯定是一个明智的建议,但等待约1个月并不能帮助我解决当前的事态。 - carsten
1
根据更改的性质,从当前主干(master)创建一个分支并查看是否产生冲突也许并不是什么大问题。除非他们所做的更改是至关重要的,否则真的没有太大的必要急着将其合并——但是我不能规定你们的“紧急程度”。个人认为,如果这些更改确实是关键的更改,那么不提供它们来自何处的完整上下文将是一个非常严重的问题,因为这会进一步束缚维护者在适时完成修复工作上的能力。 - Makoto
你可以(滥用)git bisect来自动化这个任务。 - jub0bs
4
一个不使用版本控制的高级开发人员......这个世界已经糟糕透了。 - Jonathan Wakely
显示剩余5条评论
2个回答

5
我不知道有任何标准的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”从零列开始打印,并且提交ID被覆盖。 - Felipe Alvarez
@FelipeAlvarez 我猜行为在不同的环境下可能会有所不同。在我的环境中,我得到了正确的输出(Ubuntu 15.04,git 2.1.4)。对于这种情况,我想另一种选择是将 git diff 命令的输出保存在一个变量中,并从相同的 echo 命令输出提交 ID 变量和 diff 变量。 - Alderath
或者在echo的位置使用printf - Felipe Alvarez

2
我会创建一个新分支,包含同事的更改,并使用git merge-base命令:

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


3
我认为这并不符合他的期望。我认为git merge-base会搜索提交历史树,并找到最佳的“祖先”。这意味着,它将非常敏感于您实际创建虚拟新分支的位置。如果您从主分支创建它,结果将与您从某个非常旧的提交创建它时不同。我认为如果原始发布者知道自己从哪个提交中拥有文件,并在该提交之上直接创建分支,那么merge-base会发挥最佳作用。但是,在这种情况下,我认为它完全行不通。然而,我没有尝试过。如果我错了,我会很高兴的! - quetzalcoatl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接