magit 比 git CLI 好用在哪里?

magit 和 emacs 结合起来有很多方便的地方,而且偶尔能学到新的东西。 比如 magit 很多 buffer 都是可以操作的。举个例子,点开某个 commit diff,按 u 可以 revert hunk,按回车可以跳转到那个 commit 对应的这个文件。总之就是很多小细节用起来非常的自然,不用可以去记

1 个赞

git设计得太复杂了。光用命令行根本记不住。

1 个赞

但没辙,这玩意流行起来了,连 FreeBSD 都在用 Git 管理代码(他们的项目甚至还会用 GitHub Actions)。

还是需求驱动的问题,开源项目每个人需求都不同,参数不断增加就变成这样了。

1 个赞

我只需要一个非常非常少的子集。加起来也就是个八个命令就行了。

其他人可以也弄一个子集。很多功能一般也用不着

我讲一个最近发现的很喜欢的细节。我有时候本地会有比较多的变更,而commit的时候只想提交指定文件里的一部分hunk。 如果使用CLI,那我需要使用git add -p xxx,CLI会自动分hunk,然后按hunk问我如何处理。如果并不想提交整个hunk,只想提交里面的某几行,那就得split,然后重复前面的步骤。 而在magit里,我只需要mark set,选中想提交的几行然后stage即可。 后者比前者优雅太多了。

6 个赞

magit 和 CLI 不是同一个抽象层的东西,不太好比较,magit 是对部分 CLI 提供的命令接口用交互式 UI 做封装,git 里很多操作是需要 UI 设计的,而且感觉这方面探索远没有结束(也就是我还期待有更好的交互方式出现)。写代码用的最多的是 diff 比较之后局部代码块的提交和撤回,大部分 IDE 或者基于 git 的UI程序重点也是在这块。magit 只是依托 emacs ,以快捷键为主。横向和 vscode 比较的话,我更喜欢vscode 的方式,因为提交前会打开左右两个 buffer,两个 buffer 都是完整的源代码,左边是修改前的,右边是修改后的,只有有差异的部分是颜色高亮的,然后两个 buffer 中间有一个箭头 → 和一个加号 :heavy_plus_sign:, 点击箭头就是用修改前的内容覆盖修改后的(所以是撤回),点击加号是添加到暂存库(也就是右边覆盖左边buffer),如下形式:

无论点击箭头还是加号,版本上的差异都会消失,所以点击后高亮就会消失。 我觉得这点比 magit 的方式更直观,也能精确到每个小的 hunk, 这种 UI 直接改变我写代码的习惯,甚至可以直接在右侧 buffer 里修改,写代码同时看到修改前和修改后代码,但你的注意力只会关注那些差异的部分,不容易乱,能把注意力引导在少量的但重要的信息上的工具就是好工具。

但 git 作为一个基于时间片的数据库,里面还有大量的增删改查接口,IDE 更多是面向写代码层面的。 如果你想研究某个项目,希望从第一次 git commit 开始看,每次只看差异部分,但很多提交都是些 bug fix 或者修改 readme,这时候就需要在整个提交树上做标记(自己加注释,根据提交者或提交信息过滤)然后在几个关键的提交之间反复比较差异,这就需要另外一种可视化或者交互方式了,IDE 里集成起来可能代价太高,目前我用的是 gitkraken ,但其实还是能感觉到一些不足,用的也不是很熟,就不展开说了。

另外 magit status 和 git status 本身就是不同的命令,后者默认只是显示出有差异的文件名,前者除了文件之外,还把具体差异的diff 代码也显示了出来,所以执行了更多命令,如果代码量大,修改多,效率自然会更低。

1 个赞

建议你研究一下 emacs 内置的 ediff,非常强大

magit 是有集成 ediff 的,在 magit status buffer 里光标移动到代码差异部分,按 e 就会弹出 ediff,然后也能出现左右两个 buffer 比较的视图,但可视化效果没有那么流畅 (似乎没法在不同版本之间边修改边更新高亮),而且 maigt+ediff 连招里面的一套按键,对于大部分人来说是优点,但对我却是问题:

主要原因是,我是 evil用户,以下图里的按键

全都是复用 evil 里常用的按键,但 magit status 里更大问题在于一个buffer里不同 section 下同一个按键对应不同功能,比如放在diff区域按 e 是ediff,放在标题上又是 evil-forward-word-end, 这导致我在 diff 区域有时候想用 e 移动到句子里某个词上,去复制上个版本的内容时,结果先弹出 ediff buffer,而 ediff buffer 里居然又是一套新的按键(还有一个专门 ediff control panel来接管按键),导致我经常在 magit status 里因为按错按键而打开一堆ediff buffer ,然后要用 ediff 的专用按键去检查、退出,为了提交个代码,我得切换三四套按键体系,实在心累,这是我几乎不用 magit 的直接原因(我之前大部分 org 笔记,emacs 配置等个人项目都是用 magit,但后面直接绑定快捷键用 vscode 打开项目,专门用来对比 git 差异和提交代码 :sweat_smile:)。

另外,手动定位特定的 hunk 、打开 ediff 然后检查、关闭、提交commit,和 vscode 这种一键展示差异和差异上下文,并且中间用两个直观的按钮来刻画操作是很不一样的,这也是我说这种模式能培养习惯的原因,不是 单纯的 diff 比较视图的能力,是这一套交互方式的简单、有效和无副作用性。

不太明白你说的更新高亮是什么,但是在一边修改然后应用是可以的

你可以自己改成一致的

进入 ediff 之后可以遍历所有的 diff,不用一个一个定位

这个我看了一下,ediff 也是可以的,就是左边是修改前的代码(上一次 commit的代码),右边是目前工作区代码,然后每次修改后,差异都会重新高亮出来。这部分不是核心,只是有的时候提交前可以临时修改然后即时比较差异。

这个要等待个人需求和有足够的时间了。用 vscode 提交代码的时候都是鼠标操作,然后完全图形化点几个按键(这方面不像是编辑操作,涉及精确定位、修改、复制粘贴、多行编辑等等,所以需要一套按键模式。但修改完提交代码时,都是一眼看一下各个 hunk 的区别,知道自己改了些什么,如果功能比较统一,commit message 比较好写就提交,所以个人感觉 git 里最常用的操作不需要太多键盘交互,图形化+鼠标就很好了),更复杂的 git 命令都记录在 org 里,类似常用命令行速查表,需要的时候直接查出来复制执行就可以了,再复杂的就问 AI 了,所以目前没有动机去定制。

这里指的是,打开 magit status 后需要手动再定位到一个文件差异上,然后打开 ediff buffer (这个buffer 默认是覆盖了 status buffer),检查完差异后又要返回到 magit bufer 去按 cc 提交,然后弹出一个新 buffer 写 git message。 但 vscode 里是,左侧有一个 nerd tree 形式的侧边栏充当 magit status buffer, 这个buffer里包括 commit 提交框,点击文件后 diff 双栏结构直接就在右侧 window 并列显示,个人更喜欢这种文件、diff 信息,commit 填写框都在一个视图里情形,所有信息一目了然,当然 magit 也可以定制,但这和上一条一样,目前还没有足够多时间和足够多已有问题促使自己去定制。

我就是因为evil跟很多emacs原生窗口快捷键冲突才放弃evil的,并不是所有插件都能很好的兼容evil,自己弄又很麻烦,还是用原生的emacs快捷键更方便

我目前还是用内置的 vc 配合 cli,vc可以覆盖我使用场景的80%,有些自己常用但vc没有的就写个elisp函数,很够用了。最开始也是靠 magit 学会了大部分的 git,magit 的问题是很多操作我用不到,用的到的为了保证一致性layer藏的过深,也不是对于我最舒服的,不如用elisp定制。

1 个赞

我想着的也是,如果以后定制也从内置的 vc 结合 ediff 着手,不太会想去改 maigt

我是从 vim 转到 emacs,主要是为了用 evil+org+roam+jupyter 的,不在这个核心需求里的包有冲突的话,基本都弃用或者只是用很少一部分不冲突的功能

我在windows上用git extension比较多,鼠标点点比较舒服。 怎么设置magit-status的打开单git commit的diff像git extension那样。 我看git extension查看单个git commit的diff,命令是这样。

"C:\Program Files\Git\bin\git.exe" -c color.ui=never -c diff.submodule=short -c diff.noprefix=false -c diff.mnemonicprefix=false -c diff.ignoreSubmodules=none -c core.safecrlf=false diff --find-renames --find-copies --unified=3 "d2e38138c25eb43fcb00b3fb55339578f5bb49ba" "36343bed39c48632b3df55fa280494ebf20038a1" -- "Utils.java"
1 个赞
  1. magit-cherry-donate:这个太好用了,可以选中某个区域的 commit 直接把它们嫁接到别的分支上,很适合在其他分支开发时想选中部分内容合入主线。

大佬这个怎么用的,没用过,我一般cherrypick都是一个一个的用l oA A操作。

在任意界面选中某个范围连续的 commits,按下 A 可以看到 dispatcher 界面:

image

“Apply elsewhere” 下面有 Donate 一项,按下 d,选择一个其他 branch 就可以了,这样你选中的 commits 就会移动到那个 branch 上了。

4 个赞