我经常遇到这种情况:
在最后一步中,我使用git checkout -b new-branch-name
,但是在调用该命令后,当前磁头不再引用已撤消的更改。它只有一个父母。它不再是合并。
在执行合并时,如何将合并提交到新分支?
答案 0 :(得分:5)
我个人避免使用git pull
。通过避免它,我可以先运行git fetch
,然后检查发生了什么。看了之后,我然后使用git merge
,但通常结束 的操作,避免了第一个错误放置,因为我可以看到合并可能很困难,并且需要事先在新分支上开始。
不过, 能够恢复...非常有用,而且很容易!就像您已经做过的那样:
git pull
# oh no, merge conflicts!
# resolve conflicts
git commit # or git merge --continue
并提交到错误分支,然后对其进行修复:
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
从语法上来说,您从开始:
o--o--o <-- your-branch (HEAD)
/
...
\
o--o--o <-- origin/your-branch
合并的结论前进your-branch
指向您进行的新合并提交*
:
o--o--o
/ \
... * <-- your-branch (HEAD)
\ /
o--o--o <-- origin/your-branch
我们现在添加一个 new 分支,指向同一合并提交:
o--o--o
/ \
... * <-- your-branch (HEAD), new-branch-name
\ /
o--o--o <-- origin/your-branch
,然后使用git reset
将附加了HEAD
的分支名称沿第一父级方向向后拖,将其恢复到先前的提交:
o--o--o <-- your-branch (HEAD)
/ \
... * <-- new-branch-name
\ /
o--o--o <-- origin/your-branch
我们都准备好了。
所有这些都依赖于有关Git的有用原理:Git实际上就是有关 commits 的全部内容。分支名称一直在移动;它们就是我们查找提交的方式。 commits 是永久的(当然,只要我们能找到它们)并且是不可更改的。以您喜欢的方式获取提交,然后可以随意重新排列名称。
(如果出于各种原因难以键入HEAD^1
,请注意,您可以使用HEAD^
或HEAD~
甚至@^
或@~
中的任何一个。那就是:
HEAD
和@
是同义词。^1
和^
是同义词:1
被隐含。~1
和~
是同义词:1
被隐含。^
和~
做不同的事情时,均表示“返回图中的一些步骤”。 ^
之后的数字是父代数字,仅对合并提交有意义:1
表示第一父代。因此,HEAD^1
表示 HEAD
的第一父级,而HEAD~1
表示返回一个第一父级。应用所有同义词规则就是给我们@^
和@~
构造的原因。)
答案 1 :(得分:1)
使用非提交合并,更改分支,在此处提交
git checkout <yourbranch>
git fetch
git merge --no-commit origin/<yourbranch>
# if conflicts : resolve conflicts then
git checkout -b <newbranch>
# if NO conflicts, just
git add path/to/relevant/files
git commit
答案 2 :(得分:1)
回答一个稍微不同的问题-如果您已经使用git checkout -b new-branch
创建分支,则合并不会完全丢失。这是我恢复的方式:首先,存储更改。然后使用strategy=ours
重新运行合并,然后重新应用隐藏的更改并提交。
git merge upstream/master
# resolve conflicts
git checkout -b new-branch
# oh, noes! merge lost.
git stash
git merge upstream/master --no-commit --strategy=ours
git stash pop
git commit