我经常发现自己处于这种情况:
在最后一步中,我使用git checkout -b new-branch-name,但是在调用该命令后,当前磁头不再引用已拉出的更改。它只有一个父母。它不再是合并。
在执行合并时,如何将合并提交到新分支?
我个人避免git pull。通过避免它,我可以先运行git fetch,然后检查要输入的内容。看完之后,我使用git merge但通常结束后也首先避免了该特定错误,因为我可以看到合并可能很困难,并从一个新分支开始提前。
不过,能够恢复还是很有用的……而且很简单!就像您已经做过的那样:
git pull
# oh no, merge conflicts!
# resolve conflicts
git commit # or git merge --continue
Run Code Online (Sandbox Code Playgroud)
并提交到错误的分支,然后再对其进行修复:
git branch new-branch-name # create new branch to contain the merge
git reset --hard HEAD^1 # back up current branch to first-parent
git checkout new-branch-name # return to new branch
Run Code Online (Sandbox Code Playgroud)
以图解方式,您从开始:
o--o--o <-- your-branch (HEAD)
/
...
\
o--o--o <-- origin/your-branch
Run Code Online (Sandbox Code Playgroud)
合并的结论your-branch将指向*您进行的新合并提交:
o--o--o
/ \
... * <-- your-branch (HEAD)
\ /
o--o--o <-- origin/your-branch
Run Code Online (Sandbox Code Playgroud)
现在,我们添加一个新分支,指向相同的合并提交:
o--o--o
/ \
... * <-- your-branch (HEAD), new-branch-name
\ /
o--o--o <-- origin/your-branch
Run Code Online (Sandbox Code Playgroud)
然后使用git reset将其HEAD附加的分支名称沿第一父级方向向后拖动一个步骤,从而将其恢复到先前的提交:
o--o--o <-- your-branch (HEAD)
/ \
... * <-- new-branch-name
\ /
o--o--o <-- origin/your-branch
Run Code Online (Sandbox Code Playgroud)
我们都准备好了。
所有这些都依赖于有关Git的有用原理:Git实际上就是关于commit的全部。分支名称一直在移动;它们就是我们找到提交的方式。该提交是永久性的(当然,只要我们能找到),不可改变。以您喜欢的方式获取提交,然后可以随意重新命名。
(如果HEAD^1由于各种原因难以键入,请注意,您可以使用HEAD^or HEAD~或什至@^or中的任何一个@~。即:
HEAD并且@是同义词。^1和^不带1,是同义词:1如果省略,则暗含。~1和~不带1,是同义词:1如果省略,则暗含。^和~做不同的事情时,两者都意味着“返回图中的一些步骤”。后面的数字^是父代数字,仅对合并提交有意义:1表示第一个父代。因此,HEAD^1意味着的第一亲HEAD,并HEAD~1意味着返回一个第一亲。应用所有同义词规则是为@^and @~构造的原因。)