Git - 在解决冲突错误之前,是否有可能恢复到状态

时间:2014-08-03 01:52:42

标签: git storyboard

当我将本地功能分支重新绑定到开发分支时,存在一些冲突。 所以我需要解决它们,但这个解决方案实际上是修改我的提交。 所以问题是如果解决是错误的(然后,我丢失了正确的代码)?除了提前备份该分支外,如何恢复到以前的状态?

2 个答案:

答案 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

此处AC是您提交的三次提交,而现有的提交大多只是标记为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的名称。最简单的一个是CORIG_HEADgit 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 mergegit 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/develgit rebase。)