Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/24.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
Git 为什么不同的冲突解决方式会导致不同的冲突?_Git_Gerrit_Git Commit_Git Rebase_Git Pull - Fatal编程技术网

Git 为什么不同的冲突解决方式会导致不同的冲突?

Git 为什么不同的冲突解决方式会导致不同的冲突?,git,gerrit,git-commit,git-rebase,git-pull,Git,Gerrit,Git Commit,Git Rebase,Git Pull,我想找到一个答案,解释为什么当我尝试将本地更改与master的更改合并时,git的行为会有所不同,具体取决于使用的命令和顺序 为了确保从干净的环境开始,我将所有内容重置为最新的本地提交69cf18c…,然后选择已存储在Gerrit服务器中的我自己的更改(仅一个文件): git reset --hard 69cf18c... git fetch ssh://... && git cherry-pick FETCH_HEAD 从这里开始,我尝试了三种解决方法,只有第三种方法效果良

我想找到一个答案,解释为什么当我尝试将本地更改与master的更改合并时,git的行为会有所不同,具体取决于使用的命令和顺序

为了确保从干净的环境开始,我将所有内容重置为最新的本地提交
69cf18c…
,然后选择已存储在Gerrit服务器中的我自己的更改(仅一个文件):

git reset --hard 69cf18c...
git fetch ssh://...  && git cherry-pick FETCH_HEAD
从这里开始,我尝试了三种解决方法,只有第三种方法效果良好:

选项1:使用重基拉动

git pull --rebase
git pull
Git将向我显示数百个与我选择的文件无关的更改。即使我尝试
git-rebase--skip
另一个神秘的冲突也会不断出现,而且是无限期的为什么会发生这种情况?我的本地历史是否被一些扭曲了基准的旧本地承诺所污染

选项2:不带重基的拉动

git pull --rebase
git pull
Git将只显示一个冲突,一个与我的文件有关的冲突,直到这里一切正常。但是,在解决了冲突并运行了
git add-u&&git commit
之后,git在我的上面创建了一个新的commit,我无法将它与运行
git rebase--interactive HEAD~2
的我的commit合并(然后我将分别拾取和挤压):

Git没有在编辑器中列出提交“合并”,而是列出数百次其他提交为什么我不能将冲突合并到提交中?

选项3:重置、拉动然后选择

如果我在拉动后进行樱桃采摘,一切正常:

git reset --hard 69cf18c...
git pull
git fetch ssh://...  && git cherry-pick FETCH_HEAD
# solve the conflict
git add -u && git commit -c FETCH_HEAD
为什么按这种顺序,一切都顺利进行?


这3个选项有什么解释吗?提前谢谢你

看来
FETCH_HEAD
的历史与
69cf18c

使用查看器(gitk、gitg、git kraken、git extensions…)或运行以下命令,查看
FETCH_HEAD
69cf18c
的比较历史:

git log --graph --oneline 69cf18c FETCH_HEAD
您应该看到,两个提交的历史都不同,每个分支都有许多其他分支没有的提交(您说的“数百”)


当本地分支有数百个提交要在远程分支上重播时,选项1是正常行为

选项2是git rebase-i处理合并提交时的正常行为:如果合并提交未引入新更改或被“丢弃”


从您描述的内容来看:选项3最接近您要查找的内容。

首先,您需要了解“git rebase”和“git merge”之间的区别

“git pull--rebase”与“git fetch origin;git rebase”相同

“git pull”与“git fetch origin;git merge”相同

Git rebase将所有本地提交移动到远程分支的顶部(默认情况下是远程分支的主分支)。如果远程分支上的多个提交与本地提交冲突,则必须逐个解决,而不是一次,就像爬楼梯一样。最后,在rebase之后,您将发现本地提交位于远程提交之上,并且所有本地提交id都已更改

Git merge只需使用一个额外的合并提交连接本地分支和远程分支,而无需更改本地或远程分支上的提交。它请求冲突合并一次,这样的冲突解决信息保存在新创建的合并提交中

Git rebase更适合于在提交之前解决本地更改。Git merge更适合于合并服务器上的远程分支,或者Git pull请求,这不会改变提交id。Gerrit不将pull请求用作github或bitbucket。Gerrit的最佳实践是在本地避免“git合并”或“git拉”

看起来您很长时间没有重新设置本地分支的基础,因此远程分支上有许多提交与您的冲突。因此,作为选项1,直接重设基础受到阻碍

您可以这样做来解决冲突

  • 基于当前本地分支创建另一个分支
  • 删除本地当前(如主)分支,然后基于远程主分支重新创建它
  • Cherry pick您在本地分支上一个接一个地提交给主分支(如果没有太多)
  • 樱桃采摘gerrit commit

  • 这样,您就不需要任何“git merge”操作,并且可以节省时间来避免为多个冲突重新设置基础。

    重新设置基础和cherry picking一次应用一个提交,您需要解决任何合并冲突,一次提交一个。合并合并分支,您只需解决最终合并冲突。例如,如果您在两个分支上更改了同一行,然后在其中一个分支上撤消该分支上的更改,则樱桃拾取/重基会给您一个合并冲突,而合并不会。这种区别对我来说完全有意义,除了一点:如果我的本地历史与master冲突,为什么只是重置我的上一次提交,然后重新设置基址不会产生相同的冲突?为了进一步澄清我的担忧:如果问题是在我的本地历史中与master冲突,那么在运行git pull--rebase时,仅重置我的更改仍然会要求我解决所有这些不相关的更改。我只是重新测试了它,没有显示任何不相关的更改,只是我自己的更改。另外,master应该与自己的历史保持一致:为什么存储在本地历史记录中的任何旧提交(刚刚下载,我从未接触过)都不能正确地修补最近的更改?大师的历史总是始终如一的。谢谢如果是这样的话,那应该是一种情况:有人重新设置了他/她的提交的基础(或者甚至重新设置了另一个具有不同基础的分支的基础),并强制将其推入远程主分支。这样做之后,即使您没有在本地更改任何内容,您的本地基址也与远程基址不匹配。这就是我所说的,不要对远程分支使用rebase和force pu
    git branch -D master
    git checkout -b master origin/master
    
    git checkout master
    git cherry-pick xxx (xxx is local commit on WIP branch)
    ...
    git cherry-pick xxx
    
    git fetch ssh://...  && git cherry-pick FETCH_HEAD