Git Rebase -> 为什么pull的时候有merge?
Git Rebase -> Why is there a merge when pulling?
我创建了一个分支来开发新功能。由于此新功能完全是作为一个新项目开发的,因此唯一可能的冲突源将在解决方案文件中。
随着功能的开发,主分支更新了几次。当我完成开发和测试时,我做了:
git checkout master
git fetch
git pull
git checkout myFeature
git rebase master
rebase(和所有其他命令)运行良好,没有 conflicts/errors/problems 报告。我的下一步是 git status
,结果是:
On branch myFeature
Your branch and 'origin/myFeature' have diverged,
and have 7 and 5 different commits each, respectively. (use "git pull" to merge the remote branch into yours)
当我 git pull
打开合并并查看历史记录时,我的提交被重复了。在我看来,这种重复是不应该发生的。我期待我的提交应该在最后一次(当前)提交之后重新应用。
是我做错了什么还是我的期望有误?
为什么会有合并提交
当你做一个变基时,你正在改变 Git 历史。当您再次拉取时,Git 会再次尝试合并这两个历史记录。默认情况下 git pull
是 git fetch
+ git merge
,这将导致合并提交。
更改历史记录后这不是您想要的,因为它会(部分)恢复您对历史记录的更改。不幸的是 git status
的提示有点误导......
变基/更改历史后你应该做什么
更改历史记录(例如变基)后,您需要强制推送,这样您也可以在远程上获得该历史记录。你告诉 git 然后 "the history is different, but trust me, that's intended".
建议使用 "force push with lease":git push --force-with-lease
- 参见 git push --force-with-lease vs. --force。
修复当前状态的步骤
幸运的是,您可以使用 Git reflog 在 git pull
之前返回!
这将修复错误的拉取,不会有任何冲突需要解决:)
所以要执行的步骤:
- 在 reflog
git reflog
中找到正确的提交,所以在 git pull
之前(注意:您可以通过键入 q 退出 reflog)
- Git 重置为该提交,例如
git reset 327fb961e --hard
- 仔细检查并执行
git push --force-with-lease
。
注意:如果 git reset
有误,您可以再次使用 git reflog
:)
注意 2:reflog 仅在您的本地计算机上
这部分足以用于 master
分支的变基。
git checkout master
git fetch
git pull
git checkout myFeature
git rebase master
但是,您可以只使用下面的命令来代替上面的所有命令来做同样的事情。
$ git pull origin master --rebase
在此之后,所有提交哈希将被重写,这就是为什么 git status
显示您的分支已经分歧。
忽略这一点,您可以运行以下命令将重新设置基础的代码推送到远程分支。
$ git push origin HEAD -f
在变基过程中,如果遇到冲突,不想继续变基,可以运行 git rebase --abort
中止变基。
无论如何,如果您发现自己正处于一些不希望的提交相关危险之中,您可以按照以下步骤操作。
git reflog
- 找到最后的完美提交并记下它的提交哈希值
git reset --hard <commit-hash>
- 提供最后的完美提交散列
它将带您到 repo 的最后一个完美代码。
之前的答案看起来不错。只是想直观地说明发生了什么,以防有帮助:
由于 git rebase
修改了历史记录,你在 rebase 后的分支看起来与你在 origin 上的分支不同。
origin/master:
A -> B -> C -> D -> E
你的分行,origin/yourbranch:
A -> B -> F -> G -> H
变基后,yourbranch 看起来像:
A -> B -> C -> D -> E -> F -> G -> H
然后,当你拉动origin/yourbranch时,你会得到:
A -> B -> C -> D -> E -> F -> G -> H - I (merge commit)
\ /
-> F -> G -> H -------------
由于历史不同,所以变成正常的非快进合并。实际上,您的远程和本地分支已成为不同的分支。
我创建了一个分支来开发新功能。由于此新功能完全是作为一个新项目开发的,因此唯一可能的冲突源将在解决方案文件中。
随着功能的开发,主分支更新了几次。当我完成开发和测试时,我做了:
git checkout master
git fetch
git pull
git checkout myFeature
git rebase master
rebase(和所有其他命令)运行良好,没有 conflicts/errors/problems 报告。我的下一步是 git status
,结果是:
On branch myFeature
Your branch and 'origin/myFeature' have diverged, and have 7 and 5 different commits each, respectively. (use "git pull" to merge the remote branch into yours)
当我 git pull
打开合并并查看历史记录时,我的提交被重复了。在我看来,这种重复是不应该发生的。我期待我的提交应该在最后一次(当前)提交之后重新应用。
是我做错了什么还是我的期望有误?
为什么会有合并提交
当你做一个变基时,你正在改变 Git 历史。当您再次拉取时,Git 会再次尝试合并这两个历史记录。默认情况下 git pull
是 git fetch
+ git merge
,这将导致合并提交。
更改历史记录后这不是您想要的,因为它会(部分)恢复您对历史记录的更改。不幸的是 git status
的提示有点误导......
变基/更改历史后你应该做什么
更改历史记录(例如变基)后,您需要强制推送,这样您也可以在远程上获得该历史记录。你告诉 git 然后 "the history is different, but trust me, that's intended".
建议使用 "force push with lease":git push --force-with-lease
- 参见 git push --force-with-lease vs. --force。
修复当前状态的步骤
幸运的是,您可以使用 Git reflog 在 git pull
之前返回!
这将修复错误的拉取,不会有任何冲突需要解决:)
所以要执行的步骤:
- 在 reflog
git reflog
中找到正确的提交,所以在git pull
之前(注意:您可以通过键入 q 退出 reflog) - Git 重置为该提交,例如
git reset 327fb961e --hard
- 仔细检查并执行
git push --force-with-lease
。
注意:如果 git reset
有误,您可以再次使用 git reflog
:)
注意 2:reflog 仅在您的本地计算机上
这部分足以用于 master
分支的变基。
git checkout master
git fetch
git pull
git checkout myFeature
git rebase master
但是,您可以只使用下面的命令来代替上面的所有命令来做同样的事情。
$ git pull origin master --rebase
在此之后,所有提交哈希将被重写,这就是为什么 git status
显示您的分支已经分歧。
忽略这一点,您可以运行以下命令将重新设置基础的代码推送到远程分支。
$ git push origin HEAD -f
在变基过程中,如果遇到冲突,不想继续变基,可以运行 git rebase --abort
中止变基。
无论如何,如果您发现自己正处于一些不希望的提交相关危险之中,您可以按照以下步骤操作。
git reflog
- 找到最后的完美提交并记下它的提交哈希值git reset --hard <commit-hash>
- 提供最后的完美提交散列
它将带您到 repo 的最后一个完美代码。
之前的答案看起来不错。只是想直观地说明发生了什么,以防有帮助:
由于 git rebase
修改了历史记录,你在 rebase 后的分支看起来与你在 origin 上的分支不同。
origin/master:
A -> B -> C -> D -> E
你的分行,origin/yourbranch:
A -> B -> F -> G -> H
变基后,yourbranch 看起来像:
A -> B -> C -> D -> E -> F -> G -> H
然后,当你拉动origin/yourbranch时,你会得到:
A -> B -> C -> D -> E -> F -> G -> H - I (merge commit)
\ /
-> F -> G -> H -------------
由于历史不同,所以变成正常的非快进合并。实际上,您的远程和本地分支已成为不同的分支。