当我将本地功能分支重新绑定到开发分支时,存在一些冲突。 所以我需要解决它们,但这个解决方案实际上是修改我的提交。 所以问题是如果解决是错误的(然后,我丢失了正确的代码)?除了提前备份该分支外,如何恢复到以前的状态?
答案 0 :(得分:3)
正如“Undoing a git rebase”中提到的那样,您始终可以使用git reflog
恢复分支之前的分支,或者,如果您刚刚完成了变基,ORIG_HEAD
(also HEAD@{1})
即使你不想撤销你的rebase,只是简单地引用rebase之前的代码,你可以在所说的rebase之前建立一个tmp
分支:
git branch tmp @{1}
允许您compare a file between your current branch and tmp
:
git diff tmp feature_branch -- myfile.cs
答案 1 :(得分:2)
你很幸运,因为git(主要是 1 )每次执行提交时都只会添加 new 提交。旧的仍在那里,它们变得更难找到。
具体来说,您有本地功能分支 - 我们称之为feat
- 基于远程开发分支,我们可以将其称为origin/devel
。这意味着你有一些提交
“分支”这个origin/devel
。让我们画出:
A - B - C <-- feat
/
...- o - o - * <-- origin/devel
此处A
到C
是您提交的三次提交,而现有的提交大多只是标记为o
,除了*
标记的位置你开始的时候就是origin/devel
。
在某些时候,您执行了git fetch
(或git pull --rebase
,它执行git fetch
)并且您的git联系了您最初克隆的git,以获取新的提交他们制作。假设他们制作了两个新的,并将它们绘制成:
A - B - C <-- feat
/
...- o - o - * - o - x
git fetch
通常 2 在完成之前做的最后一件事(并git pull --rebase
恢复,如果你的git fetch
就是这样做的话)就是更新{ {1}}分支标签,因此origin/
现在指向新的分支标题:
origin/devel
A - B - C <-- feat
/
...- o - o - * - o - x <-- origin/devel
执行的操作(包括git rebase
调用时)很容易描述:复制您的原始提交, 3 然后移动< em>您的标签。在复制之前,原件仍在那里:
git pull --rebase
副本对其父节点的更改与原始节点对其父节点的更改相同。也就是说,无论您在 A - B - C [see below for naming]
/
...- o - o - * - o - x <-- origin/devel
\
A' - B' - C' <-- feat
和*
之间做了什么,git都会尝试对A
进行相同的更改,以提出x
。然后,无论您在A'
和A
之间做了什么,git都会尝试对B
执行相同的操作以获取A'
,依此类推。
当git不能自动完成这些操作时,就会出现这些合并冲突。 (即使git认为可以自动执行它们,你应该以某种方式检查结果,因为git可能会出错。)
您可以查看原始分支 - 原始B'
到A
提交,特别是使用引用提交C
的名称。最简单的一个是C
,ORIG_HEAD
在git rebase
标签移动到C
之前就设置为feat
。但是,还有“reflog”,它跟踪用于命名的提交C'
。您可以使用feat
查看feat
- 分支reflog。您还可以使用git reflog show feat
(替代拼写:git log -g
)。 reflog通常持续更长时间:默认为30到90天。除了git log --walk-reflogs
之外,ORIG_HEAD
名称已替换为各种其他命令(git merge
和git cherry-pick
),因此它只是用于立即更正。
如果您事先知道要保存原始分支,可以创建一个新名称(分支或标记名称)以指向分支的尖端(在这种情况下,提交{ <1}}),在运行git rebase
之前:
C
或者,正如我有时做的那样:
git rebase
然后才开始:
git branch save-feat feat
所以我现在有两个版本的git branch -m feat feat-1
git checkout feat-1
git checkout -b feat-2
分支。
1 Git将删除提交(和其他未使用的存储库对象),但只有在它们真正未被引用之后。特别是,除非你做了删除reflog的事情(包括删除分支),否则reflog会持续一个月或三个旧提交。
2 在较新的git(1.8.5左右)中,git rebase ...
总是更新;在旧版本中,feat
会以禁止更新git fetch
标签的方式调用它。
3 具体来说,git pull
使用一系列origin/branch
操作来复制每个提交。 (请注意,它也会尝试跳过不再需要的提交,除非以交互方式调用。例如,如果您的git rebase
- 到 - git cherry-pick
更改与添加到{{1}的内容完全相同}},A
可以在复制时完全跳过B
,只提供origin/devel
和git rebase
。)