首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Git中,如何获得与三向合并相关的三个提交In (例如,在自定义合并驱动程序中)?

在Git中,如何获得与三向合并相关的三个提交In (例如,在自定义合并驱动程序中)?
EN

Stack Overflow用户
提问于 2019-10-18 09:15:18
回答 2查看 87关注 0票数 1

在下面的图表中,时间从下到上流动:

代码语言:javascript
复制
| |
| |
3 | this is a commit on master, myfile.txt was modified by this commit
| |
| 2 this is a commit on branch mybranch, myfile.txt was modified by this commit
| |
|/
|
1   this is a commit on master, myfile.txt was modified by this commit

现在我需要将mybranch合并到master中,如果我正确理解Git,myfile.txt现在需要文件级别的合并(参见https://git-scm.com/docs/gitattributes#_performing_a_three_way_merge),因为在合并所涉及的两个分支中myfile.txt都被修改了。

对于自定义合并驱动程序,帮助说明:

-- merge.*.driver变量的值用于构造一个命令来运行以合并祖先版本(%O)、当前版本(%A)和其他分支版本(%B)。这三个令牌被替换为临时文件的名称,这些文件在构建命令行时保存这些版本的内容。

我的理解是,%O将是一个临时文件的名称,myfile.txt的内容在提交1%A将是一个临时文件的名称,myfile.txt的内容在提交3%B将是一个临时文件的名称,其内容为at myfile.txt at commit 2

临时文件的名称是否以某种方式嵌入提交id ( SHA-1)?

有没有办法获得123的提交id?

EN

回答 2

Stack Overflow用户

发布于 2019-10-18 19:01:17

--我的理解是,%O将是一个临时文件的名称,myfile.txt的内容在提交1%A将是一个临时文件的名称,myfile.txt的内容在提交3%B将是一个临时文件的名称,其内容为at myfile.txt at commit 2

是这样的。

是否以某种方式嵌入临时文件的名称提交id ( SHA-1)?

不是的。

有获得123提交id的方法吗?

不可靠,不。通常可以通过找到实际的git merge命令并解析其参数来找到提交3的名称或哈希ID,而提交2通常是HEAD。因此,提交1是git merge-base -all HEAD <3>的结果,只要它只是一个散列ID。

当有多个合并基时,这里的问题就出现了。在这种情况下,这三个提交的ID可以取决于这是否是一个递归合并。如果合并是使用git merge -s resolve运行的,则合并基是N个合并基之一,按(明显)随机选择。如果合并是使用git merge -s recursive (或默认情况)运行的,则合并将多次运行,对每个合并基运行一次,然后再以合并基合并的提交方式运行,可能是递归的。

您最好的选择是不需要这些信息,因为重构它是杂乱无章和不可靠的。

票数 1
EN

Stack Overflow用户

发布于 2019-10-20 11:16:32

有获得1、2和3提交id的任何方法吗?

是的,但不一定总是这样。

代码语言:javascript
复制
$ git init
$ touch .gitignore
$ git add .gitignore
$ git ci -m .gitignore
$ echo 1 > myfile.txt
$ git add myfile.txt
$ git ci -m 'this is a commit on master, myfile.txt was modified by this commit'
$ git co -b mybranch
$ echo 2 >> myfile.txt 
$ git ci -am "this is a commit on branch mybranch, myfile.txt was modified by this commit"
$ git co master 
$ echo 3 >> myfile.txt 
$ git ci -am "this is a commit on master, myfile.txt was modified by this commit"
$ git log --graph --all --oneline
* 2d0b94b (HEAD -> master) this is a commit on master, myfile.txt was modified by this commit
| * d223e74 (mybranch) this is a commit on branch mybranch, myfile.txt was modified by this commit
|/  
* 0bf67f0 this is a commit on master, myfile.txt was modified by this commit
* b6c7c02 .gitignore
$ git merge mybranch 
Auto-merging myfile.txt
CONFLICT (content): Merge conflict in myfile.txt
Automatic merge failed; fix conflicts and then commit the result.
$

此时,您可以使用git ls-files -u轻松地获得1、2和3的blob。

代码语言:javascript
复制
git ls-files -u
100644 d00491fd7e5bb6fa28c517a0bb32b8b506539d4d 1       myfile.txt
100644 2b2f2e1b9261c50c3816610eb3eb140fabf1745a 2       myfile.txt
100644 1191247b6d9a206f6ba3d8ac79e26d041dd86941 3       myfile.txt
$ ./what-commit-contains-file-blob.sh myfile.txt d00491fd7e5bb6fa28c517a0bb32b8b506539d4d
0bf67f0 this is a commit on master, myfile.txt was modified by this commit
$ ./what-commit-contains-file-blob.sh myfile.txt 2b2f2e1b9261c50c3816610eb3eb140fabf1745a
2d0b94b (HEAD -> master) this is a commit on master, myfile.txt was modified by this commit
$ ./what-commit-contains-file-blob.sh myfile.txt 1191247b6d9a206f6ba3d8ac79e26d041dd86941
d223e74 (mybranch) this is a commit on branch mybranch, myfile.txt was modified by this commit
$ cat what-commit-contains-file-blob.sh 
#!/bin/sh

# https://stackoverflow.com/questions/223678/which-commit-has-this-blob
# https://stackoverflow.com/a/32611564/23118

file=${1:?missing file name argument}
blob=${2:?missing blob argument}

git log --all --pretty=format:%H -- $file \
        | xargs -n1 -I% sh -c "git ls-tree % -- $file | grep -q $blob && echo %" \
        | xargs -n 1 git log -n 1 --oneline
$

因此,对于这个简单的例子,repo这个解决方案工作得很好,但是一个blob可以是多次提交的一部分,所以我不确定这是否总是会给出一个唯一的结果。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58447695

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档