magit v2.7 の操作メモ

　magit をバージョン2.7に更新したが、あまり日本語情報がなかった。そして、バージョン1と操作が違っているコマンドがあった。`?` で表示されるヒントだけではわかりにくかった部分、後で調べて発見した機能などを備忘録的にまとめる。バージョン2系といっても操作が微妙に違うので、あくまで 2.7 が対象。

# 2020/09/15 追記

- 検索に出てしまうので注意。この記事はこれ以上メンテナンスしません。
- 新しい記事は https://qiita.com/eggc/items/d49f49001cf0a7f1414c にあります。

# magit-refs (ブランチ一覧)

`magit-refs-mode` でブランチ一覧を表示する。 `magit-status` バッファでは `y` を叩くことでこのモードに移行できる。（注：旧バージョンでは magit-status バッファで `b v` を叩いていたが変更された）

全体的に at-point （カーソル位置にある要素に対して何らかの操作を行う）が働くのでとても便利。

## log

適当なブランチにカーソルを合わせて `RET` を押すと、そのブランチのログを見ることができる。

#### checkout

適当なブランチにカーソルを合わせて `RET` を押すと、そのブランチをチェックアウトすることができる。

　ブランチ作成はビューの状態に関係なく `b` `c` `RET` で実行できる。`b` `c` で引数を指定すると、枝分かれする元のブランチを与えることができる。

　ブランチを削除したいときは、ブランチ一覧で `k RET` でカーソル上のブランチを削除できる。RET を押す前に引数を与えれば、指定した名前のブランチを削除することもできるが、あまり使わない。範囲指定で複数のブランチをまとめて削除することもできる。マージ済みの不要ブランチがたくさんあるときに便利。この操作はリモートブランチにも行うことができる。

### log
　`l` `l` で現在のブランチのログを見ることができる。ブランチ一覧を表示している時 `l` `o` `RET` でカーソル上のブランチのログを見ることができる。 `l` `o` で引数を指定すると、任意のブランチのログを見ることができる。

　特定のファイルの変更だけが見たい場合はファイルを開いて `magit-log-buffer-file` コマンドを実行する。

### diff

- magit-log を表示している時、`RET` または `d` `d` を押すと、カーソル上のコミットの変更点を見ることができる。ログを数行範囲指定し同じ操作をすると、マークされた範囲の変更点をまとめてみることができる。
- ブランチを比較するには `y` でブランチ一覧を表示した後、比較したいブランチにカーソルを合わせて `d` `r` `RET` でまとめて差分を見ることができる。この時使われるコマンドは `git diff <WORKING_BRANCH>...<POINTER_BRANCH>` となる。ここで使われるトリプルドット（トリプルドットがわからない場合は[この記事](https://yakst.com/ja/posts/4116)を参照）は意図しない差分を出してしまうことがある。 ... を使わない単純な diff が見たい場合には at-point の機能を使わずにブランチ名を手入力する必要がある。つまり `d` `r` `<BRANCH_NAME>` `RET` のような操作を行う。
- 特定のコミットの時点と現在の状態を比べるには、 `d` `r` で引数を選択する。たとえば５個前のコミットとの比較は `d` `r` `HEAD~5..` で実行できる。もっと良い方法があるかもしれない。
- `+` を押すと diff の表示領域(hunk)を広くする。 `-` で逆に狭くする。 `0` で初期状態に戻す。
- `(setq magit-diff-refine-hunk t)` としておくと hunk の差分の中でも単語の差分がある箇所を強くハイライトする。

### rebase
　magit-log を表示している時、旧バージョンでは `E` で実行できた rebase -i は、 `r` `i` に変わっている。stage に変更があって rebase コマンドに失敗した時にはログが出ない。期待した反応が帰ってこないときは `$` を押して git-process バッファを見たほうが良い。

### push
　ローカルブランチと同じ名前のリモートブランチに push する場合は `P` `p` で実行できる。一度も push したことのないブランチを push するときは対象のリポジトリを選択する。普通は origin なので特に悩むこともなくすすめることができるはず。二回目以降は、origin を選択する必要はない。

　ローカルブランチと異なる名前のリモートブランチに push する場合は `P` `u` で実行できる。一度も push したことのないブランチを push するときは対象のブランチを選択する。二回目以降は選択する必要はない。

　`P` `u` で push する先のブランチを変更したい場合は `b` `u` で変更できる。変更後も magit-branch-popup が出たままなので `C-g` で消す。

### cherry-pick
　cherry-pick は他のブランチのログを見ているとき、取り出したいコミットにカーソルを合わせて `A` `A` で実行する。コンフリクトが起きてしまった時は、修正後に `A` `A` で continue する。放棄したい場合は `A` `a` で abort する。

### prune
　不要な tracking branch を全部削除するには `f` `-p` `u` を実行する。内部的には `git fetch orgin --prune` を実行する。

### reset
　既にコミットした変更を取り下げたいときには `X` `h` のあと戻りたいコミットを引数で与える。1個戻りたい場合は `HEAD^` を与えればよい。ブランチのマージを実行した後、マージ前に戻したい場合は `HEAD^` を `ORIG_HEAD` にする。

　ファイルの変更箇所はそのままにしたい場合は `X` `s` ... で以下同じように実行する。

### show
　他のブランチのファイルを見たいときは `M-x magit-find-file` のあと、ブランチ名、そしてパス付きのファイル名を与える。Refs モードなら、カーソルがあたっているところがデフォルトのブランチ名になる。内部的には `git show <branch>:<file>` を実行している。

### git sub command
　magit でどう実行したらよいかわからないコマンドは `!` `!` で直接実行できる。たとえば `git version` のようなコマンドを実行できる。

### magit-status がウィンドウ分割するのをやめる
magit status がデフォルトではウィンドウを分割するのが使いにくい。これをやめる方法として、古いバージョンでは `(setq magit-status-buffer-switch-function 'switch-to-buffer)` で対処できたが v2 からは効かない。 新しいバージョンでは下記の方法でやる。下記のコードは [magit Github Issues](https://github.com/magit/magit/issues/2541) から引用。

```.el
(setq magit-display-buffer-function
      (lambda (buffer)
        (display-buffer
         buffer (if (and (derived-mode-p 'magit-mode)
                         (memq (with-current-buffer buffer major-mode)
                               '(magit-process-mode
                                 magit-revision-mode
                                 magit-diff-mode
                                 magit-stash-mode
                                 magit-status-mode)))
                    nil
                  '(display-buffer-same-window)))))


```

**追記 (2017-11-22)**  @tkhsh-yt さんから、より簡潔な方法を教わりました。下記の一行で済ませることができます。

```.el
(setq magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1)
```

 ただし、この方法の場合はすでに分割しているウィンドウがある場合他を消してしまう(`C-x` `1` と同じ)効果があるようです。

[magit-fullscreen is gone · Issue #1953 · magit/magit](https://github.com/magit/magit/issues/1953#issuecomment-221134023)

### magit-commit 時に diff が開くのをやめる

commit するときにデフォルトで diff が開く。これが旧バージョンと動作が違ってありがためいわくなので、それを無効化する。下記のコードは [magit Github Issues](https://github.com/magit/magit/issues/1979) から引用


```.el
(remove-hook 'server-switch-hook 'magit-commit-diff)
```

[magit のドキュメント](http://magit.vc/manual/magit/Editing-commit-messages.html) にも下記のように書いてあるので間違いないはず。

> To show no diff while committing remove magit-commit-diff from server-switch-hook.