ハクソク

世界を動かす技術を、日本語で。

Magitにおけるリベース

概要

  • Magitの魅力を筆者視点で再発見
  • git logの操作性と発見性の高さ
  • リベース操作の直感的な実行方法
  • Magitがコマンド学習を促進
  • 他のGUIと比べたMagitの独自性

Magitによるgit logの活用

  • MagitはEmacs上で動作するGitインターフェース
  • F3キーでMagitを起動し、lLで全ローカル・リモートブランチのログ表示
  • lはログ系コマンドのプリフィックス、Lは全ブランチ表示
  • 複雑なログコマンドもヒント表示で直感的に組み立て可能
    • 例:-Aで著者絞り込み、リストや名前入力で選択
    • =uで日付範囲指定、カレンダーから選択または手入力
    • -sでdiffstat表示、-- testsでtestsディレクトリ限定
    • bで全ブランチ(リモート含む)表示
  • オプション選択ごとにヒントが表示され、記憶不要で操作可能
  • 一度慣れればコマンドシーケンスも素早く入力可能
  • Magitが実行するgitコマンドがヒントとして表示され、CLI理解も深まる
  • 例:
    $ git log --branches --remote --author=kqr --until=2025-06-01 \
      --graph --color --decorate --no-merges --stat -- tests
    
  • インタラクティブなUIでありながら、コマンドラインの理解も促進

Magitでのリベース操作

  • リベース対象ブランチをgit logから選択し、直感的に操作
  • 現在のブランチは青枠で表示、カーソルで他ブランチ選択
  • **bb␍**でブランチ切り替え(b=checkout, b=branch)、リストはカーソル位置がデフォルト選択
  • 切り替え後、**re␍**でリベース開始(r=rebase, e=elsewhere)、リストはカーソル位置がデフォルト
  • -iを追加すればインタラクティブリベースも可能
  • 編集可能なコミットリストが表示され、**k(削除)f(fixup)w(reword)s(squash)**などのホットキーで操作
  • 利用可能な操作一覧も画面下部に表示

Magitのコマンドトラッキングと学び

  • $キーでMagitが実行したgitコマンドの履歴を確認可能
  • 例:
    git checkout profiling-of-test-suite
    git rebase --autostash optimise-company-name-generation
    
  • --autostashは作業ツリーが汚れていても自動でstashしてリベース後に復元
  • manページ参照で詳細確認可能
  • Magitのデフォルト設定から新しいgitオプション(例:--autostash, --force-with-lease)を知る機会

Magitと他のGitインターフェースの違い

  • コマンドラインでも同等操作は可能だが、インタラクティブなログ表示で構造理解が深まる
  • 視覚的なフィードバックヒントで複雑な操作も安心して実行
  • 他のGUIツールでは得られないコマンド理解学習効果
  • Magitはgitコマンドラインの薄いラッパーとして設計され、透明性・拡張性・効率性を両立
  • ステージ・アンステージ・リセット・リバートなども部分的・インタラクティブに容易に操作可能

まとめ

  • MagitGit操作の学習・効率化に最適なツール
  • ヒント表示コマンドトラッキングで初心者にも上級者にも有用
  • インタラクティブな操作性コマンドライン理解の両立が最大の魅力

Hackerたちの意見

もう8年以上、毎日magitを使ってるんだけど、その間に他の仲間にもこのツールの素晴らしさを伝えようとしたんだ。生産性が上がって、学びにも役立ったから。でも、誰一人として使ってくれる人がいなかった。説得力がないのか、ツールの使い方が個人の好みによるのか、理由はわからないけど、ちょっと悲しい気持ちになるよ。magitのUXは本当に素晴らしい。特にリベースに関しては、サブセットリベース(--ontoを使うやつね、詳しくは https://git-scm.com/book/en/v2/Git-Branching-Rebasing#_more_...)がめちゃくちゃ簡単にできる。CLIでブランチの順番を覚えるのは難しいけど、magitでは基本的に「r s」だけで済むから、本当に魔法みたいだよ。
Magitは間違いなく最高のGit GUIだよ。でも、ほとんどの人にとってEmacsが障壁になってるのが残念。多くの人が使っているのは、もっと使いにくいGitツールだから、面倒なツールで簡単にできるワークフローを選んじゃう。一般的には、いろんなゴミコミットをブランチにして、GitHubやGitLabの「スカッシュ&マージ」機能を使ってPR/MRを一つのコミットにまとめる感じ。だから、ほとんどのGitインターフェースがこれほど優れていないせいで、Gitの可能性をフルに活用できていないのが悲しい。多くの人はGit UIのためだけにEmacsを学ぼうとは思わないしね。
同じく、Emacsがほとんどの人にとっての障壁になってるね。
MagitがSmartGitよりも何が簡単なの?
個人的には、magitでのリベースはあんまり好きじゃないな。コンフリクトが出たときに混乱しちゃうし。主に使う理由は、コミットのレビューとステージングなんだ。行単位での非線形ステージング(同時に変更を元に戻せるのもいいし)は、コミットを丁寧に作りたいときにめっちゃ便利なんだよね。
Magitを使ってたけど、4年前にLazyGitを見つけてからは戻れなくなった。Emacsの肥大化もなくて、TUIベースのUXが素晴らしくて、すぐにキーを押すだけでアクションができるのがいいね。
> 誰かを使うように説得できたことは一度もないよ。ほとんどの人は「ただのgitの上にあるインターフェース」だと思ってるから、いくつかの具体例がないと、本当に複雑なタスクをすぐに終わらせられることに気づかないんだ。こういう表面的な意見は何度も見たことがある。
同じ経験だわ。同僚に見せたけど、誰もツールをうまく使おうとはしなかった。VSCodeの代替品(edamagit)を探しても、試そうとする人すらいなかった。でも、リポジトリのブランチが多いって文句言ってたけど、俺には全然影響なかったのに、彼らのGUI gitクライアントには問題だったみたいで、マージ時にブランチを削除することにしたんだ。そうすると、いくつかのgit履歴も消えちゃうけど(何かがマージされたときに)。
すごくクールに見えるけど、CLIツールとしてgitを学んだ身としては、どんなUIもそのワークフローから俺を変えることはないと思う。例外はdiffingかな、そこでだけはmeldをdifftoolとして使ってる。
Gitラッパーには絶対手を出さないよ。前に騙されたことがあるし、gitはもう使えるからね。スピードアップできるものは、すでにzshの関数にまとめてあるし。
まさに自分の体験と同じだけど、同僚から学んだから、彼は成功したってことだね。 :)
Magitは、Vimユーザーの私がEmacsを羨ましく思う数少ないものの一つだね。それに、正直に言うとorg-modeも。
VimユーザーでもMagitは使えるよ。Emacs全体を使う必要はないし、EmacsをMagitを動かすための仮想マシンみたいに扱えばいいんだ。
Magitがあったからこそ、長い間Emacsを使ってたけど、今はneovimのクローンであるneogitが私の使い方には90%くらい合ってる。インターフェースも同じだし、全てが同じ感じ。
まだ見たことがなければ、vim用のfugitiveプラグインを試してみるといいよ。vimの中で合理的なレベルのgitマジックを提供してくれるみたい。Magitほどのマジックではないけど、インタラクティブリベースの処理も結構いい感じだよ。
jj/jjuiなら大丈夫だよ。
jjuiとjjの組み合わせはさらに良いよ。magitを何年も使ってきた俺からの意見ね。
Magit好きとしては、LazyGitは場合によってはさらに良い代替品だけど、全体的にはちょっと物足りないかな。でも、neovimの中でも外でも使いやすいよ。
https://github.com/jceb/vim-orgmode https://github.com/nvim-orgmode/orgmode
ちょっと脱線するけど、Emacsにパフォーマンスの復活があったらいいなと思ってる。ネイティブコンパイルは良い一歩だけど、EmacsはNeovimに比べてまだまだ遅い。例えば、何も設定せずに立ち上げてすぐに終了する場合でも、こんな感じだよ: $ time emacs -Q -e kill-emacs /Applications/Emacs.app/Contents/MacOS/Emacs -nw -Q -e kill-emacs 0.18s user 0.03s system 98% cpu 0.213 total $ time nvim -es --cmd 'vim.cmd("q")' nvim -es --cmd 'vim.cmd("q")' 0.02s user 0.01s system 82% cpu 0.034 total パッケージを最小限にしても、テキストの挿入などが遅いし、Magitを開くのも(まだ読み込まれていないとき)遅いから、約1秒かかる。Emacsは私のお気に入りのエディタだけど、NeovimやSublimeを開いて簡単な作業をすると、Emacsに戻ったときの速さが痛いほどわかるんだ。
/usr/bin/time emacs -Q -e kill-emacs 0.03 real 0.02 user 0.00 sys でも、Emacs.appは使ってないんだけどね。
速いEmacsがあればいいけど、基本的にはずっと動かしておくのが理想だと思う。だからemacsclientプログラムがあるんだよね。起動時間はそんなに大きな問題じゃないよ。
> EmacsはNeovimよりもまだまだ遅いよね、起動してすぐに終了する場合でも。確かにそうだけど、対策もあるよ。俺のマシンでは、Emacsデーモンはログインする前に準備ができてるし(残ってる状態)。Emacsやそのパッケージを更新するときだけデーモンを再起動するかな。確かにEmacsとSpacemacsは遅いけど、俺の作業は遅くならないよ。
Emacsは確かに遅くなることがあるけど、それがELispに起因するのか、同期的なシングルスレッドコードのせいなのか、特定のタスクに遅いアルゴリズムを選んでいるからなのかは分からないな。俺にとって一番のパフォーマンス改善は長い行の処理だった。例えば、Emacsは1MBくらいの行を与えると使い物にならなくなってた。シェルモードのバッファをたくさん使うから、これが結構イライラすることが多かった。俺の対策は、デフォルトのシェルをスクリプトにして、`bash`をGNU `fold`の軽量版でパイプして、特定の長さを超えたら改行を強制するようにしたことだ(下限を超えると次の空白で折り返し、上限を超えるとすぐに折り返す)。そのパイプのおかげでBashはインタラクティブじゃないと判断して、Expectを使った別の対策が必要になった。最近のEmacsのバージョンでは長い行の処理が改善されて、あのひどいルーブ・ゴールドバーグシェルを手放せるようになったよ!
M1 Mac Proでは0.13秒だから、君のMacよりは速くないね。i9-9900KのLinuxボックスでは0.04秒だ。M1のシングルコア性能は同等か、むしろ速いと思う。macOSやGatekeeperに関係してるのかもしれないな。CPUの使用率があまり高くないことに気づいた。$ gtime /opt/homebrew/bin/emacs --batch --eval '(princ (format "%s\n" emacs-version))' 30.2 0.07user 0.03system 0:00.13elapsed 78%CPU (0avgtext+0avgdata 46064maxresident)k $ /usr/bin/time ~/bin/emacs --batch -eval '(princ (format "%s\n" emacs-version))' 30.2 0.02user 0.01system 0:00.04elapsed 95%CPU (0avgtext+0avgdata 57728maxresident)k
どんなハードウェア使ってるの?俺の古いRyzen 3600XでArchを動かしてるときは、かなり速いよ。OSXではUIがそんなにパフォーマンスを食ってるの? $ time emacs -Q -e kill-emacs 実時間 0m0.076s ユーザー 0m0.058s システム 0m0.018s $ time nvim -es --cmd 'vim.cmd("q")' 実時間 0m0.028s ユーザー 0m0.005s システム 0m0.003s vimはまだまだ速いけどね。
Emacsの難しい問題は、全体にわたってグローバルな可変状態を使っていること。これがあると、並行性や並列性を適切に追加するのがすごく難しいんだ。エラーやバグの表面を少しずつ減らして、どのパッケージ作者でも使いやすい並列性の構造を追加するには、かなりの努力が必要だね。
Emacsは機能的にはエディタじゃなくてシェルみたいなもんだね。ファイルごとにEmacsを立ち上げるのは、開くウェブページごとにWaylandを立ち上げたり止めたりするのと同じ。だから、起動時間の微小な増加は全然問題じゃないよ。
コマンドラインじゃないGUI版のDoom Emacsを、いろんなパッケージを有効にして使ってるけど、完全に立ち上がるのに0.45秒しかかからないから、全然遅くないよ。確かにneovimよりは遅いけど、絶対的に見ても遅くはないし、Emacsデーモンを立ててないから、もっと速くなるはずだよ。
Emacsは閉じることがない。新しいEmacsを開くこともない。 emacsclientにどのファイルを読み込むか、どの行にジャンプするかを指示するだけ。 私の場合は、`e file.ext:200`がemacsclientの呼び出しに展開される感じ。
数年前にspacemacsの設定をいじってたとき、Magitが大好きだった!でも、年々、ほとんどのツールをもっとシンプルでUIベースのもの(org-modeにはLogSeqとか)に置き換えていったけど、Magitの代わりになるものは見つからなかった。1つのツールのためにspacemacsを丸ごと使うのはちょっと過剰かなって思うから、基本的なgitを使って、インタラクティブリベースを手動でやることにしてる。
Magit用にEmacs + Spacemacsのセットアップをしてるよ。基本のSpacemacsの設定はうまくいってるから、いじる必要がなかった。最近はEmacsの他の部分にはあまり興味がない。邪魔にならずに、Magitを楽しく使い続けてる。
Magitをやめたい。めっちゃ遅いから。6000ファイルのリポジトリで`git status`は100msだけど、Magitの同等のやつは2〜4秒かかるんだよね。
これ、役に立つかもね:;; magitのステータスを速くするためにいくつかの項目を削除する (remove-hook 'magit-status-sections-hook 'magit-insert-tags-header) (remove-hook 'magit-status-sections-hook 'magit-insert-status-headers) (remove-hook 'magit-status-sections-hook 'magit-insert-unpushed-to-pushremote) (remove-hook 'magit-status-sections-hook 'magit-insert-unpulled-from-pushremote) (remove-hook 'magit-status-sections-hook 'magit-insert-unpulled-from-upstream) (remove-hook 'magit-status-sections-hook 'magit-insert-unpushed-to-upstream-or-recent)
Magitは単なるステータス表示以上のことをやってるからだよ。表示したい情報を得るために、いくつかのgitコマンドを実行してるんだ。兄弟が言ったように、その多くを無効にすることもできるよ。
自分のリポジトリをプロファイリングして、必要に応じて調整(自動ステータス更新を無効にするかも)すれば、かなりのパフォーマンス向上が期待できるよ。私は100kファイル、数百万のコミットがある大きなリポジトリでmagitを使ってるけど、小さいリポジトリほど速くはないけど、CLIよりは改善されてると思う。私の設定では、git-statusで約13秒節約できるってメモしてるよ(remove-hook 'magit-status-headers-hook 'magit-insert-tags-header)。
俺は何年もmagitを使ってて、それが理由でjujutsu VCSを試すのを避けてたんだ。`jj`のワークフロー/UIは`git`のそれよりずっと良いらしいけど、俺はmagitを使うことが多いから、あんまり魅力を感じなかった。majutsuパッケージを見つけて、jujutsu用のmagitみたいなインターフェースを試してみたら、やっと試す気になったよ。`jj`を試したいEmacs/magitユーザーにはおすすめ!
jjui TUIが本当に好き。非emacsユーザーでも、jj用の素晴らしいTUIを探してるなら、ぜひチェックしてみて。
majutsuに何か目立って欠けてるものってある?
お気に入りのmagitトリックの一つ:cF(インスタントフィックスアップでコミット)。これを使うと、ログのどこかにあるコミットに一行の変更を追加できるんだよね。
これにはcFコマンドが必要だよ。
magitがあるおかげで、なんとかgitを使えるようになった。とはいえ、やっぱり難しい。確かに毎日何万人もの開発者が使ってるのは知ってるけど、俺はgitに対して何かメンタルブロックがあるみたい。MercurialやSubversionは問題なく使えてたのに。
関連がありそうな投稿: このLotus 1-2-3についての投稿ね。 Emacsのインターフェースは、Lotus 1-2-3とは大きくは違うけど、magitはちょっと似てるかな。上の投稿には詳しいことが書いてあるけど、1-2-3を使ってた頃の一番の思い出は、ショートカットがすごく覚えやすかったこと。だって、操作のたびに何かしらのプロンプトが出てたから。magitのプロンプトも似たような感じで、ここは良いところだね。(ただ、gitの使い方はちゃんと知っておかないとね。結局、これはgitだから。)Emacsとの一般的な重なりがあるとしたら、Lotus 1-2-3の目標の一つは、Emacsと同じようにユーザーが自動化できることだったみたい。しかも、操作に関する知識があれば、そんなに手間がかからないのが良かった。実際、ここはEmacsよりも優れてると思う。マクロが押すキーに基づいている感じだったから。対照的に、Emacsは特定のキーのシーケンスに対応するelispを見つけるのに、ちょっと面倒なことをしなきゃいけないからね。(その面倒なことはそんなに難しくないけど!でも、確かにある。)似たような話で言うと、AutodeskのMayaとか、ある程度3D Studio Maxもそうかな。ただ、Maxのスクリプト機能は、広範囲ではあるけど、浸透してる感じはしなかった。MaxScriptはMELよりもずっとマシだったけどね。
Vim/NeovimユーザーはLazyGITをチェックすべきだよ。 https://www.youtube.com/watch?v=CPLdltN7wgE 一番のポイントは、独立して使えるTUIプログラムで、しかもvimにうまく組み込めるってこと。