magit 太好用了,没用的朋友一定要试试

入职了几个月,都是在 iterm ssh 到服务器,然后开 emacs 写 c++,然后另外开一个 terminal 处理 git 相关的问题。一直听说过 magit,但尝试去使用新的东西总是不那么容易了。上个礼拜,让自己逐步将 git 工作流迁移到 magit 中。这几天的体验越来越好。 特开一贴哈哈。

2 个赞

最好是再分享一下你的magit工作流,不然显得很苍白

1 个赞

好的,我今天找时间整理整理发送,昨天有事哈哈

magit 是我还在坚持用 emacs 的唯二原因之一(另一个是 org mode)确实太好用了,整个 git 的工作流从开发到提交,push 一气呵成,再加上 magit-forge 对 github 的支持很完善,创建 PR,审查 PR 合并 PR 也很方便,非常赞

这个文档,常用用法总结挺详细的 ~ 有需要的参考一下

5 个赞

magit 算是emacs的killer application了,支持楼主总结自己的体验

我算是个半吊子magit使用者吧,我觉得magit特别好的一点是,它每一次使用的时候弹出来的选项都是和git 命令行是一一对应的, 你不用去猜它这个名字到底对应的是命令行的哪个选项,这样我还接触到了不少git的新的各种神奇选项,而且因为每次使用都知道命令行选项对应的是啥,不至于脱离了magit满眼抓瞎不会使用命令行了😂

2 个赞

有没有跟magit一样好用的svn客户端?

有个大概叫 git-svn 的插件,这样本地是git仓库也能用 magit 来用。

我知道git-svn,但我们公司用的是一个巨大无比的仓库,而且必须完整checkout出来才能编译,所以没办法使用git-svn。

svn真没有这么好用的客户端,现在凑合用着自带的vcs,或者dsvn。以前还有个psvn

用 SVN 不也得全部 checkout 吗?用 git-svn 也一样啊,也同样可以只从 HEAD checkout,不用走一遍历史记录了。

用 git-svn 也一样啊,也同样可以只从 HEAD checkout,不用走一遍历史记录了。

是类似 git clone --depth=1 这种吗?这样产生的shallow repo不是不能commit吗?

magit的缺点是慢

normal workflow

主要记录最近1-2周在 magit 上完成的一些操作,以及一些简单的想法。 magit 有两个特点比较显著,一是绝大部分操作都是一个 magit-status emacs buffer 中发起,一是几乎所有的地方如果你觉得它是可以按 RET 的那它大概就可以,并且能达到你想要的效果。这两点在下面会有介绍。

magit-status buffer 是指:

remote 交互

前提是已经有了一个 git repo.和 remote 的交互一般如下:

  • fetch origin: f
  • push origin: P

这两个还是比较简单的。

branch

  • 根据当前分支创建一个新的分支,然后进行开发,或者切换到一个已经有的分支: b 后选择参数

normal manipulate

这里是实际开发中会涉及的操作,根据开发的不同阶段我用到了如下操作:

  1. 修改了一些代码后,需要提交:
  • stage: s
  • unstage: u
  • commit: c,还可以 amend、reset author 等
  • stash: z,不多介绍
  • (optional): 在自己的分支上进行 feature 开发时 commit 提交比较随便,一是 message 自己懂就行二是可能有一大堆 commit,因此正式提交前我会进行 squash 一下,即多个 commit id 压成一个: r + i, 它是开了一个新的 buffer 用于选择我们要压哪些 commit,很好用。比如我新加了 commit-1 和 commit-2,在进行上诉操作后会得到如下 buffer,可以移到 commit 1 那然后 C-c C-c 即可。

2.(optional) 在 CI 上发现我的分支 unmergable

  • rebase: r + e 可以选择 rebase 到哪个分支。比如我的 branch2rebasemain 同时修改了 CMakeLists.txt ,此时我在 branch2rebase 上进行 rebase 操作,它提示有冲突,我们点 unstage 部分

3.(optional) 有时候会想将当前分支强制同步到另一个分支: reset X,记得选择 hard.

4.(optional) 比如我突然不想 track 某个文件了,则光标移到那一行 => K 甚至 k 直接 delelte

这里有几个我觉得很好的体验:

  1. stage/unstage 时,不是以 file 为单位而是 diff chunk:

  2. 大部分我们认为能 RET 的地方都可以 RET 且和我们预期效果一致:比如我看到我改了 Access.h, 那我想跳转过去看一看,很自然的会按一下 RET,事实也和我们预期一致。

  3. magit-status buffer 作为 magit 核心 buffer,里面展示了我们想要的大部分信息,例如 staged/unstaged、commit、current branch 等等,我们是基于这个已有信息做操作,而 terminal 下我们即使是展示信息也得敲一下 git status (我知道可以 alias),但就感觉 magit 这个真的很方便。

文件查看、编辑相关

我觉得这里是 magit 和 emacs 融合更紧密的地方,下面挨个说。

  • 在 A branch 开发的时候,想临时看下 B branch 某个文件 这如果是我以前的 terminal-based git 工作环境,我甚至得 stash->checkot->view and copy file->checkout back. B 分支的文件我得放在一个临时文件中,然后在 emacs 中开两个 buffer 同时看。 但是 magit 提供了 magit-find-file,我们可以比如绑定到 C-x m f,它可以指定访问某个分支中某个文件,且是放到一个临时的 buffer,只能说极其好用

  • 在代码 MR 整理提交阶段,肯定会碰到想看两个文件 diff 的时候,展示 diff 本身不难,但是要融入编辑性,就是 magit 牛的地方:

编辑性是指,在进行 diff 的时候,我可以 buffer1 看我文件 diff 内容,一边看这个文件真实的内容,然后做修改。具体是通过 d + r 完成的,他需要指定 commit range,是 commitstart…commit-end 的格式。 当然 d 配套的 diff 功能很多,例如 diff 当前 staged files 等等,但我目前没用到。

杂项

git blame

比如我要看当前区域的代码是 who/which commit 提交的。这种都是临时性的需求,因此它是通过特殊 command(C-c M-g b) 以开关的形式操作的(不然看起来太乱了):

当我想看看某个 commit 到底改了啥的时候,我下意识的按了 RET,然后真的跳转过去了,NB

submodule

我最近做的项目有一大堆 thirdparty 依赖,terminal 中处理起来不友好,但是 magit 就很不错 注:所有操作基于 prefix o. 主要问题有如下几个:

  • 有哪些 submodule? => l 它会跳转进入一个临时 buffer 展示 submodule,神奇的是,我们依然可以通过 RET 转到 submodule 内部的 magit-status!
  • 添加修改整个 submodule,不过我目前没这个需求,项目已经有雏形了。
  • 在主 repo 多个分支切换后,submodule 版本不对应问题(dirty) -r + u 表示将 submodule 版本切换到我主 repo 记录的版本
  • submodule untracked files 比如由于一些错误/意外操作,我 git status 显示 submodule 有 untracked contents,此时进入那个 submodule 的 magit-status buffer,直接对想删除的 file 按 k 即可删除,要批量达到 git clean -fd 可以通过 !! 发起外部 git command 完成,也很方便。
17 个赞

如果觉得 magit 好用,还可以在 github 上给那个作者一些 sponsorship 哈

没问题的,我经常在 branch 或者新的仓库上这么用,git svn fetch -r <revision>, 自己在自建的仓库试试就知道了。

其实还好,服务器上配置一般都还可以,我目前项目使用卡顿基本没有,项目也有中等规模了

如果是在server(比如E5-2650)上对linux kernel进行magit的命令,这时候magit的性能是很难忍受的,我选择一边magit一边摸鱼了。

linux kernel 目前100多万个 commit,这个级别的 commit 规模卡没办法了吧