gitのdiffを使いこなしたい

公式:
https://git-scm.com/docs/git-diff

git diffで差分を比較できる。

git diff <base> <compare>
compareの方が新しいやつ.


表示については、git logに関する記事に記載する。

比較対象例

今のワーキング vs. 直前のコミット

git diff
git diff -- hoge-file.txt fuga-file.txt

今のワーキングが新しいものとして表示(+/-が付与)される。
特定のファイルのみ比較したい場合は、-- の後に指定する。複数指定可能。

今のワーキング vs. 特定のコミット

git diff tokute-no-commitID
git diff tokute-no-commitID -- bla-file.txt

特定のファイルのみ比較したい場合は、-- の後に指定する。複数指定可能。



ファイルA vs. ファイルB

git diff --no-index fileA fileB


3つ目のファイルを渡すとエラーになる。
a → bとして表示(+/-が付与)される。


今のcommit vs. 別のブランチを比較する

例えば、developブランチにいて、別のブランチをマージする前に確認したいなどの場合

git diff betsu-no-branch


ただし、これは今のブランチが新しいものとして表示(i.e. +/-が付与)される。
例:betsu-no-branchで、新しいクラスを追加した場合、
- class NewClass(object):
のように、-が付与される。



オプション

変更したファイル名のみを表示する

git diff --name-only


新旧の扱いを入れ替える

git diff -R

-の表記と、+の表記が入れ替わる。

表示される形式を変える

コマンドを実行すると、次のような形式の文が表示される。

diff --git a/a.txt b/a.txt
index 2e65efe..286f312 100644
--- a/a.txt
+++ b/a.txt
@@ -1 +1,2 @@
以降、差分


indexを略さずに表示する

git diff --full-index


'a/', 'b/'の部分を変更する

git diff --src-prefix a-nobubunn/
git diff --dst-prefix b-nobubunn/

なお、日本語は文字化けする。
/の部分も含むので、最後に入れてあげた方がいい。(ないとつながって表示される。b-nobubunsample.txtみたいになる。)

'a/', 'b/'の部分を表示しない

git diff --no-prefix






別のツールを設定する

差分ツール(ソフト)を設定しておくことができる。
ツールを設定しておけばgit difftool のコマンドで外部ツールで確認できる。差分がないと何も起こらない。

差分ツールで設定する項目

https://git-scm.com/docs/git-difftool/2.31.0

diff.tool

デフォの差分ツール

difftool.<tool>.cmd

差分ツールを呼び指すコマンド。

difftool.prompt

差分ツールを呼び出す際にプロンプトを表示するか。
プロンプトを表示する必要ない場合に、これも設定する。

なお、差分ツール以外でもプロンプトが表示されることがあるので、全てで無効にするには次のようにする。

git config --global --replace-all core.pager "leff -F- -X"


すでにある設定を上書きするとき、あるオプション(--repalce-all たぶん??)をつけて設定すればよい。

差分ツール:p4merge

git config --global diff.tool p4merge
git config --global difftool.p4merge.path /Applications/p4merge.app/Contents/MacOS/p4merge
git config --global difftool.prompt false


差分ツール:WinMerge

git config --global diff.tool winmerge
git config --global difftool.winmerge.cmd "\"C:\Program Files\WinMerge\WinMergeU.exe\" -e -u  \"$LOCAL\" \"$REMOTE\"
git config --global difftool.prompt false


~/.gitconfigファイルに設定が追加されているはず。



ーーメモ
解読していくもの。日本語にしたら消す。

git diff -h

usage: git diff [<options>] [<commit>] [--] [<path>...]
  or: git diff [<options>] --cached [--merge-base] [<commit>] [--] [<path>...]
  or: git diff [<options>] [--merge-base] <commit> [<commit>...] <commit> [--] [<path>...]
  or: git diff [<options>] <commit>...<commit> [--] [<path>...]
  or: git diff [<options>] <blob> <blob>
  or: git diff [<options>] --no-index [--] <path> <path>

common diff options:
 -z      output diff-raw with lines terminated with NUL.
 -p      output patch format.
 -u      synonym for -p.
 --patch-with-raw
        output both a patch and the diff-raw format.
 --stat    show diffstat instead of patch.
 --numstat   show numeric diffstat instead of patch.
 --patch-with-stat
        output a patch and prepend its diffstat.
 --name-status show names and status of changed files.
 --full-index show full object name on index lines.
 --abbrev=<n> abbreviate object names in diff-tree header and diff-raw.
 -B      detect complete rewrites.
 -M      detect renames.
 -C      detect copies.
 --find-copies-harder1
        try unchanged files as candidate for copy detection.
 -l<n>     limit rename attempts up to <n> paths.
 -O<file>   reorder diffs according to the <file>.
 -S<string>  find filepair whose only one side contains the string.
 --pickaxe-all
        show all files diff when -S is used and hit is found.
 -a --text  treat all files as text.

共通のdiffオプション:


git diff --no-index
Diff output format options
  -p, --patch      generate patch
  -s, --no-patch    suppress diff output
  -u          generate patch
  -U, --unified[=<n>]  generate diffs with <n> lines context
  -W, --function-context
             generate diffs with <n> lines context
  --raw         generate the diff in raw format
  --patch-with-raw   synonym for '-p --raw'
  --patch-with-stat   synonym for '-p --stat'
  --numstat       machine friendly --stat
  --shortstat      output only the last line of --stat
  -X, --dirstat[=<param1,param2>...]
             output the distribution of relative amount of changes for each sub-directory
  --cumulative     synonym for --dirstat=cumulative
  --dirstat-by-file[=<param1,param2>...]
             synonym for --dirstat=files,param1,param2...
  --check        warn if changes introduce conflict markers or whitespace errors
  --summary       condensed summary such as creations, renames and mode changes
  --name-only      show only names of changed files
  --name-status     show only names and status of changed files
  --stat[=<width>[,<name-width>[,<count>]]]
             generate diffstat
  --stat-width <width> generate diffstat with a given width
  --stat-name-width <width>
             generate diffstat with a given name width
  --stat-graph-width <width>
             generate diffstat with a given graph width
  --stat-count <count> generate diffstat with limited lines
  --compact-summary   generate compact summary in diffstat
  --binary       output a binary diff that can be applied
  --full-index     show full pre- and post-image object names on the "index" lines
  --color[=<when>]   show colored diff
  --ws-error-highlight <kind>
             highlight whitespace errors in the 'context', 'old' or 'new' lines in the diff
  -z          do not munge pathnames and use NULs as output field terminators in --raw or --numstat
  --abbrev[=<n>]    use <n> digits to display object names
  --line-prefix <prefix>
             prepend an additional prefix to every line of output
  --default-prefix   use default prefixes a/ and b/
  --inter-hunk-context <n>
             show context between diff hunks up to the specified number of lines
  --output-indicator-new <char>
             specify the character to indicate a new line instead of '+'
  --output-indicator-old <char>
             specify the character to indicate an old line instead of '-'
  --output-indicator-context <char>
             specify the character to indicate a context instead of ' '

Diff rename options
  -B, --break-rewrites[=<n>[/<m>]]
             break complete rewrite changes into pairs of delete and create
  -M, --find-renames[=<n>]
             detect renames
  -D, --irreversible-delete
             omit the preimage for deletes
  -C, --find-copies[=<n>]
             detect copies
  --find-copies-harder use unmodified files as source to find copies
  --no-renames     disable rename detection
  --rename-empty    use empty blobs as rename source
  --follow       continue listing the history of a file beyond renames
  -l <n>        prevent rename/copy detection if the number of rename/copy targets exceeds given limit

Diff algorithm options
  --minimal       produce the smallest possible diff
  -w, --ignore-all-space
             ignore whitespace when comparing lines
  -b, --ignore-space-change
             ignore changes in amount of whitespace
  --ignore-space-at-eol
             ignore changes in whitespace at EOL
  --ignore-cr-at-eol  ignore carrier-return at the end of line
  --ignore-blank-lines ignore changes whose lines are all blank
  -I, --ignore-matching-lines <regex>
             ignore changes whose all lines match <regex>
  --indent-heuristic  heuristic to shift diff hunk boundaries for easy reading
  --patience      generate diff using the "patience diff" algorithm
  --histogram      generate diff using the "histogram diff" algorithm
  --diff-algorithm <algorithm>
             choose a diff algorithm
  --anchored <text>   generate diff using the "anchored diff" algorithm
  --word-diff[=<mode>] show word diff, using <mode> to delimit changed words
  --word-diff-regex <regex>
             use <regex> to decide what a word is
  --color-words[=<regex>]
             equivalent to --word-diff=color --word-diff-regex=<regex>
  --color-moved[=<mode>]
             moved lines of code are colored differently
  --color-moved-ws <mode>
             how white spaces are ignored in --color-moved

Other diff options
  --relative[=<prefix>]
             when run from subdir, exclude changes outside and show relative paths
  -a, --text      treat all files as text
  -R          swap two inputs, reverse the diff
  --exit-code      exit with 1 if there were differences, 0 otherwise
  --quiet        disable all output of the program
  --ext-diff      allow an external diff helper to be executed
  --textconv      run external text conversion filters when comparing binary files
  --ignore-submodules[=<when>]
             ignore changes to submodules in the diff generation
  --submodule[=<format>]
             specify how differences in submodules are shown
  --ita-invisible-in-index
             hide 'git add -N' entries from the index
  --ita-visible-in-index
             treat 'git add -N' entries as real in the index
  -S <string>      look for differences that change the number of occurrences of the specified string
  -G <regex>      look for differences that change the number of occurrences of the specified regex
  --pickaxe-all     show all changes in the changeset with -S or -G
  --pickaxe-regex    treat <string> in -S as extended POSIX regular expression
  -O <file>       control the order in which files appear in the output
  --rotate-to <path>  show the change in the specified path first
  --skip-to <path>   skip the output to the specified path
  --find-object <object-id>
             look for differences that change the number of occurrences of the specified object
  --diff-filter [(A|C|D|M|R|T|U|X|B)...[*]]
             select files by diff type
  --output <file>    output to a specific file