在下面的图表中,时间从下到上流动:
| |
| |
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)?
有没有办法获得1、2和3的提交id?
发布于 2019-10-18 19:01:17
--我的理解是,
%O将是一个临时文件的名称,myfile.txt的内容在提交1,%A将是一个临时文件的名称,myfile.txt的内容在提交3,%B将是一个临时文件的名称,其内容为atmyfile.txtat commit2。
是这样的。
是否以某种方式嵌入临时文件的名称提交id ( SHA-1)?
不是的。
有获得
1、2和3提交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 (或默认情况)运行的,则合并将多次运行,对每个合并基运行一次,然后再以合并基合并的提交方式运行,可能是递归的。
您最好的选择是不需要这些信息,因为重构它是杂乱无章和不可靠的。
发布于 2019-10-20 11:16:32
有获得1、2和3提交id的任何方法吗?
是的,但不一定总是这样。
$ 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。
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可以是多次提交的一部分,所以我不确定这是否总是会给出一个唯一的结果。
https://stackoverflow.com/questions/58447695
复制相似问题