Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么';t git cherry pick覆盖当前分支中的修改,如果它们不同?_Git_Overriding_Cherry Pick_Git Cherry Pick - Fatal编程技术网

为什么';t git cherry pick覆盖当前分支中的修改,如果它们不同?

为什么';t git cherry pick覆盖当前分支中的修改,如果它们不同?,git,overriding,cherry-pick,git-cherry-pick,Git,Overriding,Cherry Pick,Git Cherry Pick,看,我在一个分支中做了一个修改,然后从一个类似的分支中选择了一个提交,这个分支没有这个修改。我不知道修改是否必须回滚 最初,A和B分支都有同一文件的完整副本 begin 123 456 def f 789 klm end 但它们存在分歧。首先,A将def移动到文件末尾,生成重构的A begin 123 456 789 klm end def f 现在,如果我们在这个A的顶部选择B,则恢复原始文件( DEF F 返回到文件的中间)。这很好,因为我声明,一旦我被告知,我会问这个

看,我在一个分支中做了一个修改,然后从一个类似的分支中选择了一个提交,这个分支没有这个修改。我不知道修改是否必须回滚

最初,A和B分支都有同一文件的完整副本

begin
 123
 456
 def f
 789
 klm
end
但它们存在分歧。首先,A将
def
移动到文件末尾,生成重构的A

begin
 123
 456
 789
 klm
end
def f

现在,如果我们在这个A的顶部选择B,则恢复原始文件(<代码> DEF F 返回到文件的中间)。这很好,因为我声明,一旦我被告知,我会问这个问题。B是文件的“他们”版本,这正是我所期望的,因为我们看到B确实赢了:A和B之间的唯一区别在于A重构的位置,在这种情况下,B版本是首选的


然而,我开始问这个问题,因为情况并非总是如此。如果我们对B添加一些更改,例如将过程的第一行123重写为
222
(我在下面的bash代码中标记了这个新版本的B
C
),那么将这个C选入a会有什么结果呢?选择的结果是因为
git cherry pick-Xtheirs
-Xtheirs
部分只说明如何处理冲突的更改,在上一个示例中,两个提交之间没有冲突的更改。合并策略是
递归的
(本例中的默认值),而
他们的
是此策略的一个选项

如果有一种策略叫做他们的,那么你就会得到你所期望的结果

现在,没有
他们的
策略,但有
我们的
策略可以证明这一点。不要使用git cherry pick-X他们的C
,而是试试git cherry pick-strategy=ours C
,看看会发生什么。它将有效地忽略
C
中的更改,并表示没有要提交的内容。这种策略在采摘樱桃时当然是无用的,但它可能有助于理解

要实现您最初真正想要的目标,这里有一种方法:

git checkout A
git read-tree -m -u C
git commit --no-edit -c C

更多关于合并策略的信息可以在中找到。

从我在freenode#git上得到的信息中,人们说,与重基不同的是,拾取仅通过拾取的提交完成更新,它不会查看自公共根以来的累积更改。这意味着,由于B引入了abc文件,当在A和上拾取文件时,将重新引入该文件,从而覆盖整个文件。然而,C只在文件中引入了一个小的更改,因此将保留一个完整的修改

我克隆了你的存储库,有点不明白这是什么意思?您丢失了哪些更改,来自哪个提交?git中的Cherry pick是一个非常强大的命令,但不幸的是,它为更改创建了新的哈希。我并没有丢失任何东西。我想理解它的逻辑。你能准确地解释被问到的问题吗:为什么在我用未分解的提交覆盖它之后,名为
activate
的代码段处于重构位置?看起来很奇怪,我猜你将commit 802cfb6从分支sf2挑选到分支typedfields(这些提交具有相同的消息)但是,在这个cherry pick commit中,858677d添加了新文件.gitignore,所以我不得不修改这个commit。你的cherry pick命令到底是什么样子的?@gauee我在。我已经修改了命令。现在,您可以克隆回购协议,并自动达到困扰我的回购状态
Typefields
确实是从Sing
single_file
分支中选取的,这是它的第一次提交。在此操作期间,我已将重构应用于ProxyDB。你认为这是罪魁祸首吗?我证实了这两个过程中的冲突量是不同的。但我不知道为什么。。。我猜它与3路合并算法有关,但我会验证它。
mkdir preserving ; cd preserving
git init ; echo rrr > root
git add root ; git commit -m root

git checkout -b B ; git checkout -b A

function makeABC {
    echo begin > abc
    echo " 123" >> abc
    echo " 456" >> abc
    echo " def f" >> abc
    echo " 789" >> abc
    echo " klm" >> abc
    echo end >> abc
}

echo commiting ABC into branch A
makeABC ; git add abc ; git commit -m abc

echo refactoring A, def f moved into the end of file
git checkout A
sed -i -e '/def f/d' abc
echo "def f" >> abc
git add abc ; git commit -m "refactoring 'def f'"

echo posting abc into B
git checkout B ; makeABC ; git add abc ; git commit -m "abc in B"

echo choosing which branch to pick
picking="B" ; case $picking in
    "B") ;;
    "C") git checkout -b C ; sed -i -e 's/123/CCC/g' abc
        git add abc ; git commit -m CCC ;;
esac

git checkout A ; git cherry-pick $picking -Xtheirs 

echo observe if refactoring def f is in place in A
gitk --all & 

echo 'preserving' folder created
git checkout A
git read-tree -m -u C
git commit --no-edit -c C