のマニュアルページはgit-diff
かなり長く、初心者には必要のないケースが多数説明されています。たとえば、次のようになります。
git diff origin/master
ベストアンサー1
gitの履歴から高度な差分を表示する例を見てみましょう(git.git リポジトリのコミット 1088261f):
diff --git a/builtin-http-fetch.c b/http-fetch.c
similarity index 95%
rename from builtin-http-fetch.c
rename to http-fetch.c
index f3e63d7..e8f44ba 100644
--- a/builtin-http-fetch.c
+++ b/http-fetch.c
@@ -1,8 +1,9 @@
#include "cache.h"
#include "walker.h"
-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
+int main(int argc, const char **argv)
{
+ const char *prefix;
struct walker *walker;
int commits_on_stdin = 0;
int commits;
@@ -18,6 +19,8 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix)
int get_verbosely = 0;
int get_recover = 0;
+ prefix = setup_git_directory();
+
git_config(git_default_config, NULL);
while (arg < argc && argv[arg][0] == '-') {
このパッチを行ごとに分析してみましょう。
最初の行
diff --git a/builtin-http-fetch.cb/http-fetch.c
は、 という形式の「git diff」ヘッダーですdiff --git a/file1 b/file2
。a/
とb/
ファイル名は、名前変更/コピーが関係しない限り (このケースのように) 同じです。 は、--git
diff が「git」diff 形式であることを意味します。次に1つ以上の拡張ヘッダー行が続きます。最初の3行は
類似度指数95% builtin-http-fetch.cから名前を変更 http-fetch.c に名前を変更
は、ファイルがからに変更され、これら2つのファイルが95%同一であることを示していますbuiltin-http-fetch.c
(http-fetch.c
これは、この名前変更を検出するために使用されました)。
拡張された差分ヘッダーの最後の行は、インデックス f3e63d7..e8f44ba 100644
指定されたファイルのモード (100644
通常のファイルであり、シンボリックリンクなどではないこと、実行権限ビットがないことを意味します)、および、プリイメージ (指定された変更前のファイルのバージョン) とポストイメージ (変更後のファイルのバージョン) の短縮ハッシュについて通知します。この行は、git am --3way
パッチ自体を適用できない場合に 3 方向マージを試行するために使用されます。
次は2行の統合差分ヘッダーです
--- a/builtin-http-fetch.c +++ b/http-fetch.c
結果と比較すると、diff -U
ソース (プリイメージ) および宛先 (ポストイメージ) ファイル名の後に from-file-modification-time も to-file-modification-time もありません。ファイルが作成された場合、ソースは で/dev/null
、ファイルが削除された場合、ターゲットは です/dev/null
。構成変数を true に
設定すると、この 2 行のヘッダーのプレフィックスとの代わりに、それぞれ比較するプレフィックスとして 、 、を使用できます。詳細については、diff.mnemonicPrefix
a/
b/
c/
i/
w/
o/
git-config(1)次に、1つ以上の相違点のハンクが続きます。各ハンクは、ファイルが異なる1つの領域を示します。ユニファイド形式のハンクは、次のような行で始まります。
@@ -1,8 +1,9 @@
または@@ -18,6 +19,8 @@ int cmd_http_fetch(int argc, const char **argv, ...
形式は です@@ from-file-range to-file-range @@ [header]
。from-file-range は の形式で-<start line>,<number of lines>
、to-file-range は です+<start line>,<number of lines>
。start-line と number-of-lines は、それぞれ preimage と postimage の hunk の位置と長さを表します。number-of-lines が表示されていない場合は、1 であることを意味します。
オプションのヘッダーには、C ファイルの場合は各変更が発生した C 関数 ( -p
GNU diff のオプションなど) が表示され、他の種類のファイルの場合は同等のもの (存在する場合) が表示されます。
次に、ファイルの違いについて説明します。両方のファイルに共通する行は、スペース文字で始まります。2 つのファイル間で実際に異なる行には、左の印刷列に次のインジケーター文字のいずれかが表示されます。
'+' -- 最初のファイルにここで行が追加されました。
'-' -- 最初のファイルからここで行が削除されました。
例えば、最初のチャンク
#include "cache.h"
#include "walker.h"
-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
+int main(int argc, const char **argv)
{
+ const char *prefix;
struct walker *walker;
int commits_on_stdin = 0;
int commits;
cmd_http_fetch
はが に置き換えられmain
、行が追加されたことを意味しますconst char *prefix;
。
つまり、変更前は、「builtin-http-fetch.c」ファイルの適切なフラグメントは次のようになっていました。
#include "cache.h"
#include "walker.h"
int cmd_http_fetch(int argc, const char **argv, const char *prefix)
{
struct walker *walker;
int commits_on_stdin = 0;
int commits;
変更後、現在の 'http-fetch.c' ファイルのこのフラグメントは次のようになります。
#include "cache.h"
#include "walker.h"
int main(int argc, const char **argv)
{
const char *prefix;
struct walker *walker;
int commits_on_stdin = 0;
int commits;
- あるかもしれません
\ ファイル末尾に改行がありません
行が存在します (例の diff にはありません)。
としてドナル・フェローズは言った何を変更したかがわかる実際の例で diff を読む練習をするのが最適です。
参考文献:
- git-diff(1) マニュアルページ、セクション「-p によるパッチの生成」
- (diff.info)詳細統一ノード「統一形式の詳細な説明」。