git - 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
解决方案
不幸的是,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
最新的。
推荐阅读
- windows - SSL 访问失败
- reactjs - React 测试问题:编写一个 React 组件,创建一个包含一周 7 天的列表,我们可以在单击它时删除一周中的任意一天?
- docker - Docker - 随机启动一个容器
- c# - 阻止 gtmetrix 网站连接我的网站
- node.js - 当我在苹果 m1 芯片上运行 nvm install 14 时,Clang 命令继续在终端中运行
- python - 用字典中的每个值检查每个值
- flutter - 为什么我的数据没有在实时数据库中使用 Http Patch 更新
- statistics - 为什么调整后的 R2 分数比 R2 分数表现更好?
- sql - 在单个表上递归选择或连接
- java - ElasticSearch 如何聚合“copy_to”字段