IDEA 用了好几年再换 VS Code,最别扭的是提交代码和处理合并冲突

IDEA 里改过的文件会自己落进默认的 Changes 变更列表。提交时在 Commit 工具窗口勾上要交的那几个、写好消息就行,Git 的暂存区基本见不着。JetBrains 的提交文档把暂存区写成一个要去设置里手动打开的选项(Version Control | Git 下的 Enable staging area)。VS Code 的源代码管理视图正好反过来:未暂存和已暂存分成两块摆在眼前,点 Commit 只带走 Staged Changes 那一组。什么都没暂存时,它会按你的 Git 设置决定要不要提示全部加进去。从 IDEA 过来的人,头一周多半在这两块之间来回拖文件。

只交半个文件

IDEA 的做法是在 diff 里给代码块打勾,或者右键某一行选 Split Chunks and Include Selected Lines into Commit。VS Code 把这件事放在 diff 编辑器里:在 Changes 下点开文件,选中想交的几行,再点 gutter 上紧挨选区的 Stage 按钮。右键菜单和命令面板里对应的命令叫 Stage Selected Ranges。步骤见官方的 Staging and committing changes。

有个细节得适应:stage 拍下的是那一刻的内容。之后再动这个文件,它会同时出现在两组里,Staged Changes 里是先前拍下的版本,后来的改动还在未暂存那组,得再 stage 一遍才进得了这次提交。

diff 编辑器的 gutter 上和 Stage 并排还有个 Revert,能只撤掉某一块改动,不必整个文件回滚。它丢掉的是工作区内容,跟取消暂存不同,下手前看清楚。

变更列表和 shelve

VS Code 文档里,源代码管理视图就未暂存、已暂存两组,没提到 IDEA 那种能建好几个、编辑时随手把代码块分进去的变更列表。想要这种分组,可以去扩展市场找找。

shelve 的替代是 git stash。IDEA 的文档写得明白:stash 收走全部未提交改动,shelve 才能只挑一部分。VS Code 的命令面板里,Git: Stash 收已跟踪文件的改动,带 (Include Untracked) 的版本连新文件一起带走。另有一条 Stash Staged,只处理暂存区,要求 Git 2.35 或更新(见 branches and worktrees)。先把要搁置的部分暂存,再执行它,效果最接近挑着 shelve。

解冲突时左右是反的

IDEA 一遇到冲突就弹 Conflicts 对话框,合并窗口左边是本地版本,右边是仓库那份,中间显示结果。VS Code 这边,冲突文件会归到源代码管理视图的 Merge Changes 下面。打开文件,每段冲突上方有一排 CodeLens,分别是保留 Current、保留 Incoming、两边都留和打开对比,小冲突点一下就完。

复杂一点的,右键文件选 Open in Merge Editor,进入三方合并界面。这里左边是 Incoming,右边是 Current,Result 在下面,和 IDEA 的方向刚好对调,肌肉记忆最容易栽在这儿。编辑器的 More Actions(…)菜单里可以换布局、显示 base。

另外两点,Resolve merge conflicts 文档里写得清楚:

  • Complete Merge 只暂存当前这一个文件,整个合并操作要回源代码管理视图写好消息、点 Commit 才算完,IDEA 那边对应的是 Accept and Finish。
  • rebase 过程中 Current 指新的基底加上已经重放过的提交,Incoming 才是你自己正在重放的提交,别按字面挑。

半路想放弃,命令面板里按操作类型选对应的 Abort 命令,Merge、Rebase、Cherry Pick 各有一条。

在终端里 pull 出冲突、又想用这个编辑器的话,把 VS Code 配成 git 的合并工具:

git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait --merge "$REMOTE" "$LOCAL" "$BASE" "$MERGED"'

配好以后,出了冲突 Git 也不会自动拉起 VS Code,要自己跑 git mergetool。前提是终端里能直接调用 code 命令。

提交历史不用装东西

IDEA 里看历史一般开 Git 工具窗口的 Log 标签。VS Code 内置了 Source Control Graph,能点开提交看改了哪些文件、跟某个分支或 tag 比较、cherry-pick。单个文件的历史在资源管理器下的 Timeline 视图里,本地保存记录也算一类事件。行级 blame 用命令面板的 Toggle Git Blame Editor Decoration 打开(见 View source control history)。所以看历史用内置的基本就够了,要装扩展,主要也就是为了补多变更列表。去扩展市场挑的时候,看看上次更新是什么时候、issue 有没有人回,装之前留意它要不要连外部服务。

从 IDEA 换过来的各位,最后是习惯了暂存区,还是靠扩展把变更列表补了回来?