目前的 vc-git-working-revision
实现是这样的:
一旦 git rebase <newbase>
产生冲突,函数返回就变成了 <newbase>
。
感觉这样不太合理,明明 rebase 过程中止了,大部分文件还处于 rebase 之前的状态,此时应该取 REBASE_HEAD 才对。
但既然 git 已经把 HEAD 指针都改了,那么是不是有它的合理性?(或者说 vc-git 这边只好将错就错了?)
重现步骤:
git checkout feat-xxx
git rebase <newbase>
- 提示有冲突
M-: (vc-git-working-revision nil)
- 返回
"<newbase>“
- 期望
"feat-xxx"
没觉得代码有什么问题。 vc-working-revision
的文档是"Return the repository version from which FILE was checked out."
在命令行下git log
看一下最后一个commit是什么。
“明明 rebase 过程中止了”也不准确,有conflict不等于终止rebase,终止rebase的命令行是git rebase --abort
, 没有运行此命令行就还在rebase过程中。
确实"过程中止“不准确,应该说还没完成。
git log
是根据 HEAD
来的,所以显示的是 newbase 分支。
我还是不太理解为什么 rebase 冲突未解决的时候时候,HEAD 要指向 newbase ,假如 shell prompt 跟随 HEAD,就会出现让人困惑的场景,例如:
[🔀 feat-xx] $ git rebase newbase
Auto-merging file.el
CONFLICT (content): Merge conflict in file.el
error: could not apply efab581... *1
...
[🔀 newbase] $ <---- 假如 shell prompt 跟随 HEAD,这里就该显示 newbase 了。
好在 fish-shell 的 fish_git_prompt
命令就比较合理,它返回的是 <feat-xx>|REBASE-i
:
git 本身也有个 git-prompt
(我刚刚才知道),它也会处理 rebase-mrege 状态:
我为啥纠结这个问题呢。
因为我在 mode line 上显示了 vc 状态,所以面临的窘境跟 shell prompt 显示错误是一回事:当 rebase 冲突,我就看到 mode 上的分支名称从 feat-xx
切到了 <newbase>
。
(另,这里还有个错误,就是当 <newbase>
名字小于 7 的时候就会出错,因为 vc-git-mode-line-string
有个 (substring ... 0 7)
的操作,但如果返回 feat-xx|REBASE-i
就远大于 7 了,暂时避开了错误😄)
我现在是修复了 vc-git-mode-line-string
函数,当 rebsse 发生冲突时,让其返回 feat-xx|REBASE-i/m
(参考 fish_shell_prompt
),而不是抛错。但这个修复我感觉太个人化了,所以没打算 PR。
而 vc-working-revision
如果我理解没错的话,也应当修复,并且可以 PR 试试看会不会被采纳。
rebase
的意思就是基于newbase再一个个apply当前branch的commit。既然commit因为冲突没apply上,HEAD不就是newbase的最后一个commit吗?
建议你不用纠结这时的状态显示了. 下一步马上就是git mergetool
, git rebase --continue
, git rebase --abort
.
你可以读一下电子书 pro git, Git - Book
熟悉git 命令行操作再学emacs的vc或magit就很简单了。