如何解决由于不正确的变基,如何压缩重复提交? 如何在 beta/master 上重新设置 master如何在 beta/bootstrap 上重新设置 beta/master
由于我早期犯的错误并且当时没有解决,我有一个特定的、复杂的 Git 情况。我将首先解释我采取的步骤(使用 Git 网络视觉效果)到达我的位置。
- 我从最初的
master
分支开始。
- 我创建了一个
new-catalog
分支并进行了一组提交A
。
- 我使用过时的本地
new-catalog
重新定位master
,并拉入新的重新定位的new-catalog
分支。 (虽然我当时不知道,但这将是我痛苦的开始)
这创建了第二组提交 A'
与 A
相同,但具有新时间戳的不同提交。
- 我创建了一个
beta/master
分支(仍在过时的本地master
之外),并将new-catalog
推送到beta/master
。
- 我在
B
上进行了另一组提交beta/master
。
- 我从
beta/bootstrap
创建了一个子分支beta/master
。
既然我在这里,我想将 beta/master
重新设置为 master
,以准备 PR 回到 master
。我确实尝试过变基,但是,我遇到了一些奇怪的冲突,我怀疑是由于重复的提交集 A
和 A'
。使用 beta/master
重新设置 master
的最安全方法是什么?
我已经考虑进行交互式变基并压缩/删除初始提交集 A
,但我也不想丢失这些提交的时间信息。如果这是最好的选择,我愿意丢失时间信息,但我只是想看看有没有更好的方法。
此外,如果我能够成功地对 beta/master
进行变基,是否还需要对 beta/bootstrap
进行变基?或者我可以在没有任何冲突的情况下 PR 到 beta/master
吗?
我做了一个 git-practice repository 来重现这些错误,this 是整个网络。
非常感谢!
解决方法
使用 beta/master
重新设置 master
的最安全方法是什么?
我发现进行交互式 rebase 并删除初始提交集 A
是一种简化一切的安全方法。与我之前的想法相反,变基保留了作者时间戳(如使用 git log
时所见)并且仅替换提交时间步长(如在 GitHub 中所见)。
如何在 beta/master
上重新设置 master
-
git checkout beta/master
检查
beta/master
分支。 -
git rebase -i master
在
beta/master
上以交互方式重新设置master
。 -
删除原始提交集
A
在文本编辑器中用
pick
替换原始集合d
中的每个提交的A
。对于我的git-practice
存储库,这将是提交3e8c537
、642dc34
、7e2fa44
和b40f340
。然后,保存并退出编辑器。
-
处理任何合并冲突
然后 Git 会将
beta/master
中的每个提交(从分支底部/最深的父提交开始)与master
的 HEAD 进行比较。如果您遇到任何合并冲突,则顶部更改将是
master
分支(您要变基到的分支)的 HEAD 中的当前代码,底部更改将是与该提交对应的代码更改与 HEAD 冲突。您可以选择顶部更改、底部更改、两者兼而有之。在获得所需的文件后,请确保保存文件并
git add
以暂存更改。然后,git rebase --continue
继续。如果你合并所有的冲突,它应该成功rebase并显示
Successfully rebased and updated refs/heads/beta/master.
-
git push --force origin beta/master
这将推送您的本地
beta/master
并覆盖您的远程origin/beta/master
。
我是否也需要对 beta/bootstrap
进行变基?或者我可以在没有任何冲突的情况下 PR 到 beta/master
吗?
您可以 PR(合并提交)到 beta/master
,但变基会大量清理提交历史。
如何在 beta/bootstrap
上重新设置 beta/master
-
git checkout beta/bootstrap
检查
beta/bootstrap
分支。 -
git rebase --onto beta/master beta/master@{1} beta/bootstrap
在
beta/bootstrap
上重新设置beta/master
。 -
git push --force origin beta/bootstrap
这将推送您的本地
beta/bootstrap
并覆盖您的远程origin/beta/bootstrap
。
我不确定我是否理解正确。但我尝试在本地重现该问题并修复它。我使用了你的 git-practis 存储库。
我将本地主分支重置为提交 fb90356(我模拟中断主分支)并创建“new-catalog-demo”分支。
这是两次更改后的样子
[u@d git-practice]$ git reset --hard fb90356
HEAD wskazuje teraz fb90356 Add JavaScript
[u@d git-practice]$ git log -1
fb90356 Add JavaScript
[u@d git-practice]$ git checkout -b new-catalog-demo
Przełączono na nową gałąź „new-catalog-demo”
[u@d git-practice]$ git commit -a -m"Add feature 1"
[new-catalog-demo 5c91e3d] Add feature 1
1 file changed,2 insertions(+),1 deletion(-)
[u@d git-practice]$ git commit -a -m"Add feature 2"
[new-catalog-demo ed804d5] Add feature 2
1 file changed,2 insertions(+)
[u@d git-practice]$ git log --oneline --graph
* ed804d5 (HEAD -> new-catalog-demo) Add feature 2
* 5c91e3d Add feature 1
* fb90356 (master) Add JavaScript
* a0f3d5a Add another main feature
然后我确实重新定位到中断主服务器并从原点/主服务器拉取。这是它之后的样子。与此同时,我将 master 重置为另一个提交以模拟来自另一方的一些更改。在第二个日志中,我们可以看到 A',B' 提交。
[u@d git-practice]$ git rebase master
Pomyślnie przestawiono i zaktualizowano refs/heads/new-catalog-demo.
[u@d git-practice]$ git log --oneline --graph
* c3f9338 (HEAD -> new-catalog-demo) Add feature 2
* 5ddb34c Add feature 1
* b89ef1b (master) Change another feature
* e7278df Change a main feature
* fb90356 Add JavaScript
* a0f3d5a Add another main feature
* 5a7b447 Add main feature
[u@d git-practice]$ git pull origin master
[u@d git-practice]$ git log --oneline --graph
* 3b9619e (HEAD -> new-catalog-demo) Merge branch 'master' of https://github.com/itsjoshthedeveloper/git-practice into new-catalog-demo
|\
| * b4bf1c6 (origin/master,origin/HEAD) Update main feature
| * f716c02 Change another main feature #-->> B' ??
| * f4f9669 Change main feature #-->> A' ??
| * 98acbf4 Reset changed features
* | c3f9338 Add feature 2
* | 5ddb34c Add feature 1
|/
* b89ef1b (master) Change another feature
* e7278df Change a main feature
* fb90356 Add JavaScript
* a0f3d5a Add another main feature
* 5a7b447 Add main feature
* ec699c4 Update README
* 395a5c6 Add h1
* e1633b3 Add index.html
* f11b51f Initial commit
我想我重现了你的问题。这是我修复它的方法
首先,我们必须检查 git reflog
以找到位置,在不适当的 rebase 之前,我们有 new-catalog-demo
分支进行了更改。
[u@d git-practice]$ git reflog
3b9619e (HEAD -> new-catalog-demo) HEAD@{0}: pull origin master: Merge made by the 'recursive' strategy.
c3f9338 HEAD@{1}: rebase (finish): returning to refs/heads/new-catalog-demo
c3f9338 HEAD@{2}: rebase (pick): Add feature 2
5ddb34c HEAD@{3}: rebase (pick): Add feature 1
ed804d5 HEAD@{8}: commit: Add feature 2
5c91e3d HEAD@{9}: commit: Add feature 1
fb90356 HEAD@{10}: checkout: moving from master to new-catalog-demo
fb90356 HEAD@{11}: reset: moving to fb90356
b4bf1c6 (origin/master,origin/HEAD) HEAD@{12}: clone: from https://github.com/itsjoshthedeveloper/git-practice.git
我发现 new-catalog-demo
上最后一次好的提交是 ed804d5
,所以我重新设置到这一点。
u@d git-practice]$ git reset --hard ed804d5
HEAD wskazuje teraz ed804d5 Add feature 2
现在我有我的 new-catalog-demo
分支和我的 ole 更改,然后我将它重新基于中断主
[u@d git-practice]$ git log --oneline --graph
* c3f9338 (HEAD -> new-catalog-demo) Add feature 2
* 5ddb34c Add feature 1
* b89ef1b (master) Change another feature
不,我们可以将其发布到 origin/master 以确保我们在 master 分支的当前状态下执行此操作。
[u@d git-practice]$ git rebase origin/master
Pomyślnie przestawiono i zaktualizowano refs/heads/new-catalog-demo.
[u@d git-practice]$ git log --oneline --graph
* 86a2a81 (HEAD -> new-catalog-demo) Add feature 2
* 3dca49f Add feature 1
* b4bf1c6 (origin/master,origin/HEAD) Update main feature
* f716c02 Change another main feature
最后我们可以将 new-catalog-demo
合并到本地 master。
[u@d git-practice]$ git checkout master
Przełączono na gałąź „master”
Twoja gałąź jest za „origin/master” o 4 zapisy i może zostać przewinięta.
(użyj „git pull”,aby zaktualizować lokalną gałąź)
[u@d git-practice]$ git merge new-catalog-demo
Aktualizowanie b89ef1b..86a2a81
Fast-forward
README.md | 5 ++++-
web/index.html | 2 +-
2 files changed,5 insertions(+),2 deletions(-)
[u@d git-practice]$ git log --oneline --graph
* 86a2a81 (HEAD -> master,new-catalog-demo) Add feature 2
* 3dca49f Add feature 1
* b4bf1c6 (origin/master,origin/HEAD) Update main feature
* f716c02 Change another main feature
* f4f9669 Change main feature
* 98acbf4 Reset changed features
* b89ef1b Change another feature
* e7278df Change a main feature
* fb90356 Add JavaScript
* a0f3d5a Add another main feature
* 5a7b447 Add main feature
* ec699c4 Update README
* 395a5c6 Add h1
* e1633b3 Add index.html
* f11b51f Initial commit
现在历史是干净的,我们没有错过任何更改,也没有重复提交。我希望您现在了解如何使用 git reflog
解决此类问题。
没有“奇怪的冲突”,这只是变基的效果。甚至不考虑重复提交,因为已经合并到 beta/master
分支。正如您所注意到的,您的存储库有点混乱,但您仍然可以轻松(可能不会很快)达到所需的状态。问题是您在将更改合并到 master
之前等待的时间太长,具有冗余提交的副作用:除了重复的 new-catalog
分支之外,合并的拉取请求提交实际上是一个快进来自new-catalog
。你可以自己验证你对同一棵树有多次提交:我在说
| * ec73ee6 Merge pull request #4 from itsjoshthedeveloper/new-catalog
|/|
| * 84aabf5 Merge branch 'new-catalog' of https://github.com/itsjoshthedeveloper/git-practice into new-catalog
| |\
| | * b40f340 Add a new JS feature
| | ...
| | ...
| | ...
| * | 4b463f5 Add a new JS feature
为了消除任何疑问,您可以很容易地找到哪个是 rebase 过程开始使用 git log $(git merge-base master beta/master) -n 1 --format="%h %s"
的公共根,它返回
f4f9669 Change main feature
当您在 beta/master
上变基 master
时出现的冲突来自您在 beta/master
上的整个 web/index.html
分支中所做的更改。最后一个文件在原始 master
中也已更改,这是您冲突的原因,而不是重复的 new-catalog
。那么,一般该怎么做呢?
这是一个困境:git merge
获取分支的提示和最近的公共根,它尝试将它们合并在一起并创建提交(除非指定 --no-commit
),除非不存在冲突,“简单”那样。另一方面,使用 git rebase
您可能有更多的冲突需要解决,这是由每次提交的投影 (cherry-pick
) 引起的,从一个新的基础开始,但以线性历史结束.建议您只在频繁集成变更时选择第二种方式,尽可能避免多个分支之间的冲突。
关于 beta/bootstrap
分支,查看您在那里所做的更改,基于 beta/master
或 master
的变基不应产生任何冲突。但是,对您来说,首先在 beta/bootstrap
上重新设置 beta/master
,然后在 beta/bootstrap
上重新设置(或在此之前进行合并)master
肯定更方便。通过这种方式,只需一次 rebase,您就可以将他们的两个技巧都推进。
甚至考虑使用 rerere
:您似乎陷入困境,因为您有太多的冲突要解决。 git rerere
是一个非常有趣的功能,它包括缓存您如何解决某个冲突。假设您完成了一次合并,但最终您决定进行 rebase 并从零开始:一些冲突会自动解决,因为它们与之前遇到的相同。
编辑: 来自评论:
我首先尝试在 beta/bootstrap
上重新设置 beta/master
,但是在 beta/master
上重新设置 master
之后,我不得不在 beta/bootstrap
上重新设置 beta/master
再次
当然,您每次只能重新设置一个分支,即使它们共享大部分历史记录。为避免 rebase --onto
,您可以在 beta/bootstrap
上重新设置 beta/master
,在 beta/bootstrap
上重新设置下一个 master
。此时,beta/bootstrap
分支同时具有 master
分支和 beta/master
提交作为其祖先。要将 beta/master
分支移动到 master
主线上的新提交,您必须使用诸如 git branch -f beta/master beta/bootstrap~2
之类的东西来强制它。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。