如果我直接在主分支上工作(虽然我尽量避免这样做),我通常使用git pull --rebase
。但是如果我忘记了进行变基并执行了git pull
,有没有一种方法可以撤销此操作并使它线性化,而不是合并提交?此时进行变基是否明智(如果可以的话)?
我知道我可以默认启用拉取时的变基操作,以便不会忘记,但这更多地涉及到在这种情况下应该做什么。
简短回答(已由@Alex在评论中给出):git reset --hard HEAD^
,但仅当存在合并提交时才有效(否则你只是从快进备份了一个提交)。
带说明的长版本:
git pull
实际上就是git fetch
后跟git merge
(除非你使用--rebase
进行覆盖,就像你所提到的那样)。因此,你只需要查看是否得到了一个实际的合并提交:
$ git pull
Updating 171ce6f..523bacb
Fast-forward
mp.py | 24 ++++++++++++++++++++++++
1 files changed, 24 insertions(+), 0 deletions(-)
create mode 100644 mp.py
git log
,尤其是在下面执行图形化操作时,将会看到缺少合并提交。$ git reset --hard HEAD^
HEAD is now at 171ce6f ignore *.log files
[现在我落后于remotes/origin/master
一步]
$ echo '# pointless comment' >> selfref.py
$ git add selfref.py
$ git commit -m 'added to force merge'
[master 260e129] added to force merge
1 files changed, 1 insertions(+), 0 deletions(-)
$ git pull
Merge made by recursive.
mp.py | 24 ++++++++++++++++++++++++
1 files changed, 24 insertions(+), 0 deletions(-)
create mode 100644 mp.py
$ git log --graph --decorate --abbrev-commit --pretty=oneline
* c261bad (HEAD, master) Merge branch 'master' of [ssh url]
|\
| * 523bacb (origin/master, origin/HEAD) add multiprocessing example
* | 260e129 added to force merge
|/
* 171ce6f ignore *.log files
master
再次指向(在这种情况下)260e129。幸运的是,这个命名非常容易实现。$ git rev-parse HEAD^
260e1297900b903404c32f3706b0e3139c043ce0
(当前这个两个父提交合并的另一个父提交是 HEAD^2
.) 所以:
$ git reset --hard HEAD^
HEAD is now at 260e129 added to force merge
现在我们可以将分支变基到 remotes/origin/master
(我会使用非常简短的名称 origin
来命名它):
$ git rebase origin
First, rewinding head to replay your work on top of it...
Applying: added to force merge
现在,图形化的一行日志显示为:
$ git log --graph --decorate --abbrev-commit --pretty=oneline
* 4a0b2e2 (HEAD, master) added to force merge
* 523bacb (origin/master, origin/HEAD) add multiprocessing example
* 171ce6f ignore *.log files
git pull
并且它抱怨合并失败,该怎么办。:-)git reset --hard
回到拉取之前的状态,然后重新拉取是解决问题的方法。我想给你一些建议,帮助保持历史线性。为了在拉取时自动将分支进行变基,请设置以下git配置。
$ git config branch.autosetuprebase always
应用此设置后,您无需使用--rebase
参数输入完整的拉取命令,只需使用git pull
即可。
您可以在这篇文章中获得更多信息: http://stevenharman.net/git-pull-with-automatic-rebase
git config --global pull.rebase true
- lleo
git reset --hard
回到 pull 之前的状态,然后重新进行 pull 是正确的方法。 - Alexander Oh