fugitive.vim と tig による git 生活
GWの出だしから熱を出して寝込んでいて,そういえば普段 fugitive.vim と tig をあんまりちゃんと使い分けてないなとぼんやり考えた.
fugitive.vim
GitHub - tpope/vim-fugitive: fugitive.vim: a Git wrapper so awesome, it should be illegal
vim から git を呼べるようにするラッパープラグイン.
dein.vim
で以下のように入れている.
[[plugins]] repo = "tpope/vim-fugitive" hook_add = 'source ~/.config/nvim/userautoload/plugins/plugins-vim-fugitive.vim'
dein については以下を参照.
dein.vimにお引越し - 藻ログ
使い方は :h fugitive
を読めばだいたいわかる気がする.pushとかpullは手でやることが多いので頻繁に使うのは以下.
:Gstatus | git status | git status をサブウィンドウで開いていろいろできる |
:Gcommit | git commit | 今開いてるファイルをコミット |
:Gwrite | git add | 今開いてるファイルを git add |
:Gdiff | git diff | 今開いてるファイルを前のコミットとvimdiff |
:Gblame | git blame | 今開いてるファイルを git blame |
:Gmerge | git merge | git merge [args] を呼ぶ.コンフリクト時に:Gmergeするとconflictをquickfixに流す |
キーマップ
nnoremap [fugitive] <Nop> nmap <space>g [fugitive] nnoremap <silent> [fugitive]s :Gstatus<CR><C-w>T nnoremap <silent> [fugitive]a :Gwrite<CR> nnoremap <silent> [fugitive]c :Gcommit-v<CR> nnoremap <silent> [fugitive]b :Gblame<CR> nnoremap <silent> [fugitive]d :Gdiff<CR> nnoremap <silent> [fugitive]m :Gmerge<CR>
Space-gをfugitiveの専用キーのきもちで割り当てている. コミットは常にgit commit -v
で行いたいので:Gcommit
は-vをつけている.:Gmerge
はコンフリクト時の呼び出しのみで使ってる.quickfixでコンフリクト箇所にジャンプできて良い.
:Gstatus
git status
を実行してサブウィンドウで開いてくれる.自分の場合,サブウィンドウはせまいので新しいタブで開くように割り当てている*1.開かれた画面内では以下のマッピングで操作ができる. 選択ファイル上で-
すれば git add/reset
をtoggleして, D
すれば git diff %{file}
, U
でgit checkout
という感じ.
g? show this help <C-N> next file <C-P> previous file <CR> |:Gedit| - |:Git| add - |:Git| reset (staged files) cA |:Gcommit| --amend --reuse-message=HEAD ca |:Gcommit| --amend cc |:Gcommit| cva |:Gcommit| --amend --verbose cvc |:Gcommit| --verbose D |:Gdiff| ds |:Gsdiff| dp |:Git!| diff (p for patch; use :Gw to apply) dp |:Git| add --intent-to-add (untracked files) dv |:Gvdiff| O |:Gtabedit| o |:Gsplit| p |:Git| add --patch p |:Git| reset --patch (staged files) q close status r reload status S |:Gvsplit| U |:Git| checkout U |:Git| checkout HEAD (staged files) U |:Git| clean (untracked files) U |:Git| rm (unmerged files)
tig
端末で動作する有名なgitブラウザ.
GitHub - jonas/tig: Text-mode interface for git
Introduction · Tig - Text-mode interface for Git
vimから呼ぶ
fugitive.vim とできることが被ってる*2 のは承知なのだが,メインはfugitive.vimを使っていてちょっと複雑なことをやりたいときは tigの方で追ってる気がする.tigはneovim のターミナルで呼んでいる*3.
nnoremap tig :<C-u>w<CR>:te tig<CR>
manual
tig を立ち上げて h
をタイプするとヘルプと現在設定されているキーバインドがまとめて表示されるので,ここを読むと大体なんとかなる.
移動とか検索はvimのような気持ちで触るとなんとなく動く.
view switching
tigには12種類ぐらいのviewがあり,viewごとにキーバインドや操作をカスタマイズできる.詳しくはmanualを参照されたい.
Manual · Tig - Text-mode interface for Git
左のキーで各viewの切り替えができる.
m | main view |
d | diff view |
b | blame viewl |
r | refs view |
s,S | status view |
y | stash view |
main view
tigを立ち上げると main view がデフォルトで表示される.main viewではコミットを選択すると,そのコミットの中身が見られる.
status view
ここでは :Gstatus と大体同じことができる.
ファイル選択 | git diff |
u | git add/reset |
C | git commit |
refs view
ref-view からはcheckout やブランチ削除も普通にできる. *4
C | git checkout %(branch) |
! | git branch -D %(branch) |
ブランチ選択後のmain view
C | git cherry-pick %(commit) |
カスタマイズ
~/.tigrc
にカスタムキーバインドとかを記述できる.
bind {view} {key} {action}
のように指定する.たとえば以下のようなマクロ(もっとある)が使える. {view} に generic を指定すると全view共有でのバインディングになる.
%(head) | The currently viewed head ID. Defaults to HEAD |
%(commit) | The currently selected commit ID. |
%(branch) | The currently selected branch name. |
%(remote) | The currently selected remote name. For remote branches %(branch) will contain the branch name. |
%(file) | The currently selected file. |
%(lineno) | The currently selected line number. Defaults to 0. |
変な操作が走ると困るので,actionでは !(確認なし実行)と?(確認あり実行)を使い分けることができる.
例えばデフォルトのcherry-pick は
bind main C ?git cherry-pick %(commit)
となっていて,実行時にgit cherry-pick %(commit id) ? [Yy/Nn]
みたいに聞いてくれるので安心.
commit の挙動を変える
常に git commit -v
したすぎるのでデフォルトのC
のバインドを上書きしておく.
bind status C !git commit -v
ファイルcheckoutしたい
satus ビューで指定ファイルを直前のコミットに戻す.*5
間違って押すので ?モードで定義しておく.
bind status R ?git checkout %(file)
コミットIDにcheckoutしたい
これも間違って押すので?モードで定義しておく.
bind main c ?git checkout %(commit)