首页 > 解决方案 > git pull feature branch 在使用 master 分支重新设置功能分支之后将恢复重新设置更改

问题描述

我刚刚执行了从 master 到我的功能分支的 git rebase,步骤如下:

$ git checkout master
$ git pull
$ git checkout feature
$ git rebase master

然后发布变基,我尝试如下推送:

$ git push origin feature

上面的命令抛出错误,说我的本地和远程的 HEAD 不一样或其他东西,建议我应该 git pull 代替。因此,我确实拉上了功能分支,如下所示:

$ git pull

现在通过谷歌搜索,我知道我应该做--force push。

因此,我怀疑我作为 rebase 的一部分得到的更改在我的本地分支中消失了,因为我做了 git pull 或者它们在那里,我仍然可以从本地到远程执行 git push,如下所示:

$ git push origin feature --force // maybe force not req. now

或者我需要再次做一个 git rebase master 吗?

我想问的另一件事是,假设我的新功能永远不会修改 master 分支中的现有文件,并且只包含新文件,那么做 rebase 是否有意义,因为当所有文件都是在功能分支中新创建时,甚至如果 master 分支已经向前移动了很少的提交,仍然从 feature 合并到 master 应该是可行的而没有冲突吗?我是对的还是在这里遗漏了什么。

同样,当我在做 rebase 时,我必须解决很多冲突,但是当我第一次合并这些提交时,这些冲突从未发生过,为什么在重放相同的提交时会出现冲突?我是唯一一个在功能分支上工作的人。

另外,重复提交的原因是什么,我的意思是,例如,如果我有一个带有以下 git log 的功能分支:

commit_hash2 My Second Commit
commit_hash1 My First Commit
commit_hashX Latest commit of master branch when we created feature out of it

现在假设 master 使用 commit_hashY 获得了一个新的提交,然后使用 master (git rebase master) 发布 rebase 功能,我觉得 git log in 功能应该如下所示:

commit_hash2 My Second Commit
commit_hash1 My First Commit
commit_hashY Current Latest commit of master branch
commit_hashX Latest commit of master branch when we created feature out of it

但我现在经常看到重复的提交如下:

commit_hash4 My Second Commit
commit_hash3 My First Commit
commit_hash2 My Second Commit
commit_hash1 My First Commit
commit_hashY Current Latest commit of master branch
commit_hashX Latest commit of master branch when we created feature out of it

为什么这种重复,我错过了什么,在这种情况下有人会更喜欢这些额外的重复提交,只是试图理解这个 git 设计背后的想法。

看来我问的太多了:P

标签: gitgithub

解决方案


不幸的是,Git 建议你在 rebase 之后在 push 之前先 pull。你几乎永远不想参与这种情况,所以很多人被这个绊倒并最终陷入你的确切境地。(Git 告诉你 pull 的原因仅仅是因为你的本地提交 ID 已更改,并且 Git 检测到远程分支上的提交 ID 不在本地分支中,并且 Git 不知道它们是旧版本的您不再需要的本地提交。顺便说一句,为了解决您更新的问题,这也是您重复提交的原因:您使用 rebase 重写了您的提交,然后从远程拉入旧版本,而不是强制推送并替换它们。)您只需要记住,在变基之后,您经常会被提示拉动,而您需要强制推动。不过幸运的是,这很容易恢复。基本上,您想回到执行额外拉取之前的位置,这将是您在完成原始命令集后所处的提交 ID:

git checkout master
git pull
git checkout feature
git rebase master

要找到你在那个 rebase 之后的提交 ID,你可以使用这个命令git reflog来显示你最近的所有提交,按最近的排序。如果提交 ID 以及命令和分支名称本身不足以确定哪个是正确的,那么您可以打开另一个命令行并git log [commit-ID]针对不同的 ID 运行以查看哪个是正确的。您将希望使用将您的提交放在最新的master. 如果自 rebase 以来您所做的一切都是拉动,那么它很可能是从顶部开始的第二个提交 ID。一旦确定了要返回的提交,就可以将分支设置回它:

git reset --hard [commit-ID]

现在你会回到 rebase 之后,就好像你没有做 pull 一样,现在你可以正确地把它推出:

git push --force-with-lease

请注意,在推送时,使用它几乎总是更好,--force-with-lease而不是--force.

关于您关于仅添加新文件是否有意义的问题,没有是或否的答案。这是因为如果你坚决反对它,你永远不需要变基。但请注意,变基有 2 个不同的目的:变基到分支(以获取最新更改并简化提交图)和交互式变基(rebase -i) 来修复你的提交。我希望那些反对 rebase 到分支上的人至少仍然会交互式 rebase,尽管我知道有些人甚至出于某种原因也反对这一点。就个人而言,我喜欢变基,我可能每天会做 20 次(分支和交互)。在您的情况下,我仍然会这样做,并且在完成 PR 之前也会再次这样做,以便提交图更容易遵循并且其中不必要的合并提交更少。但是来自Git Flow背景,我仍然在 PR 完成时强制合并提交,以便我可以看到作为 PR 一部分的所有提交,即使由于我只是在完成之前重新设置基准,所以可以进行快进合并。

旁注:我通常建议删除分支的本地副本master并且永远不要检查它!原因是它很快就会过时并且要保持最新状态,您必须不断检查并拉取它,并且在您这样做之后它可能很快就会再次过时,并且您始终可以在不使用它的情况下保存一个步骤, 通过简单地使用origin/master来代替。例如,您可以这样做:

git fetch # update all remote branches
git checkout feature # probably you were already on feature and can just skip this!
git rebase origin/master

这样效率更高,您永远不必担心保持本地副本是master最新的。


推荐阅读