GitのサイトにはPro Git 2nd ed. Editionという本が全文無償公開されていて、日本語訳も公開されています。
なのでGitの使い方についてはこの本を読めば概ね事足ります。
ちなみに最新版はGitHubにあります。
それはいいのですが、なにげに意外なことにリファレンスは日本語訳が、というか英語以外の言語がないみたいです。
以下は、諸事情でgit diff --break-rewrites
について知りたかったのだけど日本語解説が一件たりとも存在しなかったので調べたついでに全オプションについて軽く調べてみたメモです。
マニュアルのバージョンは2.20.0。
git diff
SYNOPSIS
書式。
基本的にgit diff
、オプション、対象コミット、--
、対象ファイル名の順に書く。
git diff [<options>] [<commit>] [--] [<path>…]
git diff [<options>] --cached [<commit>] [--] [<path>…]
git diff [<options>] <commit> <commit> [--] [<path>…]
git diff [<options>] <blob> <blob>
git diff [<options>] --no-index [--] <path> <path>
DESCRIPTION
git diff [<options>] [--] [<path>…]
最新インデックスから現在までの差分を表示する。
addするとインデックスが更新されるので出てこなくなる。
git diff [<options>] --no-index [--] <path> <path>
Git管理外のファイルも--no-index
を付ければ対象にできる。
付けなければGit管理下にあるファイルのみが対象となる。
git diff [<options>] --cached [<commit>] [--] [<path>…]
最新コミットから最新インデックスまでの差分を表示する。
要するに最後のaddまでの差分。addした後の変更は出てこない。
--staged
も同じ。
git diff [<options>] <commit> [--] [<path>…]
現在のブランチ(HEAD)と指定のコミットとの差分を比較する。
git diff [<options>] <commit> <commit> [--] [<path>…]
指定のふたつのコミットの差分を比較する。
片方を省略するとHEADを指定したものとなる(上と同じ)。
git diff [<options>] <commit>..<commit> [--] [<path>…]
スペース区切りと同じ。
片方省略もできる。
git diff [<options>] <commit>...<commit> [--] [<path>…]
指定のふたつのコミットについて、共通の祖先まで遡ってそこから後者への差分を比較する。
言葉だとわかりにくいが、画像を見れば一発だろう。
画像はWhat are the differences between double-dot ".." and triple-dot "..." in Git diff commit ranges?より拝借。
git diff [<options>] <blob> <blob>
コミットではなくBLOBオブジェクト同士の差分を比較する。
オプション一覧
-p
-u
--patch
パッチを作成する。デフォルトの動作。
-s
--no-patch
差分を標準出力に出さないようにする。
git show
などと一緒に使うとよいが、git diff
に使うと何も出ない。
-U<n>
--unified=<n>
変更された行の前後に出力する、変更されていない行の行数を変更する。
デフォルト3。
0にすると変更された行しか出さない。
--raw
diffをRawフォーマットで出力する。
RawフォーマットはGitの内部形式らしい。
--patch-with-raw
-p --raw
と同じ。
なのだが、-p --raw
より長い。
--indent-heuristic
意図しているだろう感じで差分がうまく出るよう判定を改善する。
デフォルトでオン。
--no-indent-heuristic
--indent-heuristic
を使わない。
--minimal
できるだけ差分が少なくなるように比較する。
そのぶん処理に時間がかかる。
--patience
patience diffアルゴリズムを使って差分を生成する。
--histogram
histogram diffアルゴリズムを使って差分を生成する。
--anchored=<text>
anchored diffアルゴリズムを使って差分を生成する。
ということらしいのだが結果を見てもよくわからない。
--diff-algorithm={patience|minimal|histogram|myers}
任意のアルゴリズムを使って差分を生成する。
値を指定しない場合はmyers
が使われる。
値を--diff-algorithm=default
とすると、設定ファイルに書かれているdiff.algorithm
が使われる。
--stat[=<width>[,<name-width>[,<count>]]]
diffstat形式で出力する。diffstatは↓のような形式。
path/to/hoge,html | 5000 +++--
path/to/fuga,html | 1234 -------
カンマ区切りで3つまで指定可能な引数で出力範囲を指定できる。
第1引数widthは全体の横幅。
第2引数name-widthはそのうちファイル名部分の横幅。
第3引数countは行数。指定行数を超えるとそれ以降は省略される。
--stat-width=<width>
--stat-name-width=<name-width>
--stat-count=<count>
↑の--stat
をそれぞれ個別に設定する。
--compact-summary
diffstat形式に、ファイル作成・削除などのサマリを追加表示する。
new、gone、+l
(シンボリックリンク)、+x
(実行権限追加)など。
表示内容はstatのファイル名とグラフの間に出力される。
--numstat
statと似ているがより省力で、追加行数、削除行数、ファイルパスだけを出力する。
100 50 path/to/hoge,html
--shortstat
statの最後の行、変更されたファイル数、追加行数、削除行数の合計だけを出力する。
999 files changed, 765 insertions(+), 573 deletions(-)
--dirstat[=<param1,param2,…>]
ファイルの差分がどのディレクトリに多いかをパーセンテージで表示する。
ディレクトリ内のファイルが変更された割合ではない。
パラメータをカンマ区切りで追加することで動作を変更できる。例:git diff --dirstat=files,10,cumulative
changes
はコードの移動はカウントせず、追加削除された行のみを計算する。
lines
は行数でカウントする。通常のカウント。
files
は変更されたファイル数をカウントする。中身は見ない。
cumulative
はサブディレクトリも集計に入れる。合計は100%を超える。
数値は足切り。それ以下のディレクトリは親にまとめられる。
--summary
ファイル追加削除、権限変更など拡張ヘッダ情報のみを表示する。
--patch-with-stat
-p --stat
と同じ。
-p --stat
より長い。
-z
--name-only
や--numstat
などと一緒に使うと、区切りが改行ではなくNULになる。
--stat
などには効かない。
--name-only
変更されたファイル名のみを表示する。
--name-status
変更されたファイル名とステータスを表示する。
--submodule[=<format>]
サブモジュールのdiffの表示形式を指定する。
short
はサブモジュール内のcommitは最初と最後しか表示しない。
log
はサブモジュール内のcommitを全て一覧表示する。
diff
は普通にdiffを表示する。
--color[=<when>]
カラー表示をどうするか指定する。
デフォルト設定はcolor.ui
およびcolor.diff
で変更できる。
always
はdiffをカラー表示する。
never
は必ず白黒表示する。
auto
はよくわからない。
--no-color
--color=never
と同じ。
--color-moved[=<mode>]
移動したコードの色をどうするか指定する。
指定可能な値はno
、default
、zebra
、plain
、blocks
、dimmed-zebra
。
--color-moved-ws=<modes>
--color-moved
を検出する際に空白を取り扱う方法を指定する。
デフォルト設定はdiff.colorMovedWS
で変更できる。
ignore-space-at-eol
は改行を無視する。
ignore-space-change
はスペースの量の変化を無視する。スペース数0→1や1→0は検出するが1→10などは無視。
ignore-all-space
はスペースの変化を完全に無視する。
allow-indentation-change
は、スペースの変化量が全て同じブロックをグループ化する。
--word-diff[=<mode>]
行単位ではなくワード単位でdiffを表示する。
color
は色だけで表示する。コピペすると区切りがわからなくなる。
plain
は追加を{+ +}
で、削除を[- -]
で括って表示する。中のテキストをエスケープしないので、同じ文字が入っていると区切りがわからなくなる。
porcelain
は区切りを改行で表す。元々の改行は~で表す。正直わかりにくい。
none
は何もしない、未指定と同じ。
--word-diff-regex=<regex>
ワード単位でdiffを表示する際のワードの区切りを正規表現で指定する。
--color-words[=<regex>]
--word-diff=color -word-diff-regex
と同じ。
--no-renames
ファイル名を変更しただけのファイルは検出しない。
--check
スペースの次にタブ、および末尾スペースがあったときに警告メッセージを出す。
動作はcore.whitespace
で変更できる。
--ws-error-highlight=<kind>
行末の空白をエラー表示するか否か。引数は,区切りで複数指定可能。
old
は変更前をエラーとして表示する。
new
は変更後をエラーとして表示する。
all
はold,new,context
に同じ。
表示色はcolor.diff.whitespace
で設定する。
--full-index
commitハッシュを省略形ではなくフル表示する。
--binary
--full-index
に加え、git apply
で使えるバイナリのdiffも出力する。
と書いてあるのだが手元では--full-index
の効果はなかった。
--abbrev[=<n>]
diff --raw
などに出力するハッシュの桁数を指定する。
-B[<n>][/<m>]
--break-rewrites[=[<n>][/<m>]]
diffを書き換えではなく、削除と挿入のペアとして表す。
引数を-B/70%
とか-B100%/0%
のように渡すことで、ファイルが編集ではなく完全な書き換えと判断する基準を変更することができる。
となっているみたいなのだが正直よくわからなかった。
-M[<n>]
--find-renames[=<n>]
リネームを検出する。
-M90%
とすると、中身の90%以上が同じファイルは削除+追加ではなく名前変更とみなす。
デフォルトは50%。
-C[<n>]
--find-copies[=<n>]
コピーを検出する。
オプションの指定方法はリネームと同じ。
コピー元の候補になるのは、中身が変更されたファイルのみ。
--find-copies-harder
--find-copies
と同じだが、全てのファイルをコピー元の候補として調べる。
そのためとても重い。
-D
--irreversible-delete
削除されたファイルは差分を表示しない。
-l<num>
-M
および-C
を使用した際、この制限を超えたら処理を打ち切る。
理由としてはそれらの処理時間がO(n^2)
オーダーであるため。
--diff-filter=[(A|C|D|M|R|T|U|X|B)…[*]]
diffの出力をフィルタリングする。
A
は追加されたファイルのみ、D
は削除されたファイルのみ、C
はコピーされたファイルのみ、R
はリネームされたファイルのみ、M
は変更されたファイルのみ。
TUXB
はサブモジュールなど。
複数のオプションを--diff-filter=ACDM
のように指定可能。
*
を入れると、該当の差分がないときは何も表示せず、該当の差分があれば全ての差分を表示する。
小文字にすると逆になる。
--diff-filter=a
であれば追加された以外の変更があったファイルを全て検出する。
-S<string>
差分で引数の文字の出現回数が変更されたファイルを検出する。
-f"hoge"
とすると、hoge
の出現回数が変わったファイルを差分出力する。
100行目でhoge
を追加し、200行目から削除したような場合は出力されない。
-G<regex>
差分で引数の文字が出現したファイルを検出する。
文字列には正規表現を使用可能。
100行目でhoge
を追加し、200行目から削除した場合でも出力される。
--find-object=<object-id>
指定のオブジェクトの出現回数が変更されたファイルを検出する。
使い方は-S
と同じ。
--pickaxe-all
-S
と-G
において、ひとつでも変更が見つかったら全ファイルの差分を表示する。
--pickaxe-regex
-S
において正規表現を使えるようになる。
-O<orderfile>
diffの出力ファイルの順番を、引数のファイルの設定に変更する。
ファイルの書式はfnmatchで.gitignore
と同じ。
引っかかった上から順に表示するとなっているのだが、手元ではどうやっても順番が変わらなかった。
-R
diff
の元ブランチと先ブランチを入れ替える。
つまりdiff AAAAAA BBBBBB
とdiff -R BBBBBB AAAAAA
は同じ。
--relative[=<path>]
--relative
だけだと、サブディレクトリからdiffを実行した際にカレントディレクトリ以下のファイルしか見ない。
--relative="foo/bar/"
とすると、foo/bar/
ディレクトリでdiff --relative
を実行したかのような出力になる。
サブディレクトリから実行する場合でも、パスの指定はgitルートからの指定になる。
-a
--text
全てのファイルをテキストファイルとみなして扱う。
--ignore-cr-at-eol
改行の前にあるCRを無視する。
--ignore-space-at-eol
改行の前にあるスペースを無視する。
-b
--ignore-space-change
スペースの個数だけの変更は無視する。
0から1になった、1から0になった場合は無視しない。
function
→func tion
は無視しない。
-w
--ignore-all-space
0から1を含め、あらゆるスペースの変更を無視する。
function
→func tion
でも無視される。
--ignore-blank-lines
空行のみの追加削除を無視する。
空行以外の変更があった場合は無視しない。
--inter-hunk-context=<lines>
1ファイルに変更箇所が複数ある場合、デフォルトでは8行くらい離れているとdiff出力が別に分かれる。
この数値を大きくすると、離れた行もひとつの変更とみなす。
-W
--function-context
変更があったファイルは全てを表示する。
--exit-code
差分があれば終了ステータス1、なければ終了ステータス0で終了する。
--quiet
標準出力しない。--exit-code
を含む。
--ext-diff
外部diffヘルパーを使用する。
ということらしいが実際はgit config
等で指定が必要なので、単に↓と揃えただけと思われる。
--no-ext-diff
外部diffヘルパーを使用しない。
デフォルトで外部diffヘルパーを使っている場合にそれをキャンセルする。
--textconv
--no-textconv
バイナリファイルのテキスト変換フィルタを指定している場合に、それを使って差分を表示する、もしくは使用しないでバイナリのまま比較する。
--ignore-submodules[=<when>]
サブモジュールへの変更をどうするか。
none
はサブモジュールの変更を全て取得する。
untracked
は、変更は追跡する、新規ファイルは追跡しない。
dirty
はサブモジュールで管理されているファイルは無視され、親プロジェクトで管理されているファイルは追跡する。
all
はサブモジュール内の変更は全て無視する。
デフォルトはall
。1.7.0まではdirty
。
--src-prefix=<prefix>
変更元ファイルのプレフィックスをa/
ではなく指定した値にする。
--dst-prefix=<prefix>
変更後ファイルのプレフィックスをb/
ではなく指定した値にする。
--no-prefix
両方のファイルからプレフィックスを表示しない。
--line-prefix=<prefix>
出力の全行にこのプレフィックスを表示する。
--ita-invisible-in-index
--ita-visible-in-index
git add -N
で追加したファイルは、git diff
では登録済みの空ファイルとして、git diff --cached
では未登録のファイルとして表示される。
--ita-invisible-in-index
オプションを入れるとgit diff
では未登録の新規ファイルとして表示し、git diff --cached
では何も出てこない。
--ita-visible-in-index
は未指定と同じ。
-1 --base
-2 --ours
-3 --theirs
merge
時のコンフリクトなど、3状態を比較する際に使用する。
-o
マージされていないエントリについては出力を省略して、単にUnmerged
とだけ出す。
<path>…
パスを与えると、そのディレクトリ以下のファイルに対してのみdiffを実行する。
感想
なんだこりゃ。
何も考えず節操なく付け加えていった結果にしか見えない、
指定しても出力が変わらなくて何を意味するのか全くわからないオプションとかあって、少し整理したほうがいい気がする。