Ari*_*zis 84 git rebase git-rebase git-reset
我们都听过一个人应该重订,从未发表的作品,它的危险,等等.但是,我还没有看到张贴如何处理的情况下衍合情况的任何食谱被出版.
现在,请注意,只有存储库仅由已知(并且最好是很小)的人群克隆,这才真正可行,这样无论谁推送rebase或重置,都可以通知其他人他们下次需要注意的时候取(!).
如果你没有本地提交foo并且它被重新定位,我看到的一个明显的解决方案将起作用:
git fetch
git checkout foo
git reset --hard origin/foo
Run Code Online (Sandbox Code Playgroud)
foo根据远程存储库,这将简单地抛弃本地状态以支持其历史记录.
但是,如果一个人在该分支机构进行了大量的本地更改,那么如何处理这种情况呢?
Ari*_*zis 73
在推动变基之后恢复同步在大多数情况下并不那么复杂.
git checkout foo
git branch old-foo origin/foo # BEFORE fetching!!
git fetch
git rebase --onto origin/foo old-foo foo
git branch -D old-foo
Run Code Online (Sandbox Code Playgroud)
IE浏览器.首先,您为远程分支最初的位置设置了一个书签,然后使用它来重播从该点开始的本地提交到重新定位的远程分支.
重新定位就像暴力:如果它不能解决你的问题,你只需要更多.☺
如果查找pre-rebase origin/foo提交ID并使用它,当然可以在没有书签的情况下执行此操作.
这也是您如何处理在获取之前忘记创建书签的情况.什么都不会丢失 - 你只需要检查远程分支的reflog:
git reflog show origin/foo | awk '
PRINT_NEXT==1 { print $1; exit }
/fetch: forced-update/ { PRINT_NEXT=1 }'
Run Code Online (Sandbox Code Playgroud)
这将打印在origin/foo最近一次更改其历史记录的提取之前指向的提交ID .
你可以简单地说
git rebase --onto origin/foo $commit fooRun Code Online (Sandbox Code Playgroud)
Cas*_*bel 11
我想说git-rebase手册页的上游rebase部分的恢复几乎涵盖了所有这些.
这与从你自己的rebase中恢复完全没有什么不同 - 你移动了一个分支,并将历史记录中的所有分支重新定位到新的位置.
Von*_*onC 10
从2014年第一季度的git 1.9/2.0开始,您不必在重写的上游分支上重新标记之前的分支原点,如Aristotle Pagaltzis的回答所述:
请参阅提交07d406b并提交d96855f:
在使用
topic创建的分支上工作后git checkout -b topic origin/master,远程跟踪分支的历史origin/master可能已经被重绕并重建,从而导致了这种形状的历史:
o---B1
/
---o---o---B2--o---o---o---B (origin/master)
\
B3
\
Derived (topic)
Run Code Online (Sandbox Code Playgroud)
其中,
origin/master用于指向承诺B3,B2,B1和现在的点B,你的topic分支开始在它的后面,当顶origin/master在B3.此模式使用reflog
origin/master来查找B3作为分叉点,以便topic可以在更新origin/master的基础上重新定位:
$ fork_point=$(git merge-base --fork-point origin/master topic)
$ git rebase --onto origin/master $fork_point topic
Run Code Online (Sandbox Code Playgroud)
这就是git merge-base命令有一个新选项的原因:
--fork-point::
Run Code Online (Sandbox Code Playgroud)
找到
<commit>从另一个分支(或任何引用)分叉的分支(或任何导致的历史)的点<ref>.
这不只是寻找两个提交的共同祖先,而且还考虑了reflog,<ref>以查看是否导致<commit>从早期分支的分支中分叉的历史<ref>.
"
git pull --rebase"命令使用base分支工作所基于的" "分支(通常是远程跟踪分支)的reflog条目来计算正在重新分配的分支的fork point ,以便处理"base"的情况.分支已被重绕并重建.
例如,如果历史记录看起来像:
- "
base"分支的当前提示是B,但早期的提取观察到它的提示曾经B3然后B2然后B1再进入当前提交,并且- 在最新的"基础"之上重新分配的分支基于提交
B3,它试图找到
B3通过的输出去"git rev-list --reflog base"(即B,B1,B2,B3),直到找到一个提交,它是当前尖端的祖先"Derived (topic)".在内部,我们
get_merge_bases_many()可以一次性计算.
我们希望合并基础Derived和虚构的合并提交,这将通过合并"base (origin/master)"的所有历史提示而产生.
当存在这样的提交时,我们应该得到一个结果,它与"base"的一个reflog条目完全匹配.
Git的2.1(Q3 2014)将增加使这个功能更强大的这样:看到提交1e0dacd由约翰·行动(johnkeeping)
正确处理我们具有以下拓扑的场景:
C --- D --- E <- dev
/
B <- master@{1}
/
o --- B' --- C* --- D* <- master
Run Code Online (Sandbox Code Playgroud)
哪里:
B'是一个固定版本的版本B不是补丁相同的B;C*并且如果以错误的顺序应用,则分别与D*补丁相同C并且D文本冲突;E取决于文字D.的正确结果git rebase master dev是,B被识别为的叉点dev和master,从而C,D,E是需要被重放到提交master; 但C和D是补丁与相同C*和D*等都可以被丢弃,从而使最终结果是:
o --- B' --- C* --- D* --- E <- dev
Run Code Online (Sandbox Code Playgroud)
如果未识别fork-point,则选择B包含B'冲突结果的分支,如果未正确识别补丁相同的提交,则选择C包含D(或等效D*)的分支会导致冲突.