日本語 ▾ トピック ▾ 最新バージョン ▾ gitrevisions は 2.42.0 で最終更新されました

名前

gitrevisions - Gitのリビジョンと範囲の指定

概要

gitrevisions

説明

多くのGitコマンドは引数としてリビジョンパラメータを取ります。コマンドによって、それらは特定のコミットを示すか、またはリビジョン履歴グラフを辿るコマンド(例:git-log[1])の場合、そのコミットから到達可能なすべてのコミットを示します。リビジョン履歴グラフを辿るコマンドでは、リビジョンの範囲を明示的に指定することもできます。

さらに、一部のGitコマンド(例:git-show[1]git-push[1])は、コミット以外のオブジェクト、例えばBLOB(「ファイル」)やツリー(「ファイルのディレクトリ」)を示すリビジョンパラメータを取ることもできます。

リビジョンの指定

リビジョンパラメータ <rev> は、通常はコミットオブジェクトを指しますが、必ずしもそうであるとは限りません。これは拡張SHA-1構文と呼ばれるものを使用します。以下にオブジェクト名を指定する様々な方法を示します。このリストの後半に挙げられているものは、コミットに含まれるツリーやBLOBを指します。

注記
このドキュメントはGitが認識する「生の」構文を示しています。シェルや他のUIでは、特殊文字を保護し、単語の分割を避けるために追加の引用符が必要になる場合があります。
<sha1>、例:dae86e1950b1277e545cee180551750029cfe735dae86e

完全なSHA-1オブジェクト名(40バイトの16進数文字列)、またはリポジトリ内で一意な先頭部分文字列。例:dae86e1950b1277e545cee180551750029cfe735 と dae86e は、あなたのリポジトリに dae86e で始まる他のオブジェクト名がない場合、同じコミットオブジェクトを指します。

<describeOutput>、例:v1.7.4.2-679-g3bee7fb

git describe の出力。すなわち、最も近いタグにオプションでダッシュとコミット数、さらにダッシュと *g*、そして省略されたオブジェクト名が続く形式です。

<refname>、例:masterheads/masterrefs/heads/master

シンボリックリファレンス名。例:master は通常、refs/heads/master によって参照されるコミットオブジェクトを意味します。もし偶然にも heads/mastertags/master の両方がある場合、どちらを意図しているかをGitに伝えるために明示的に heads/master と指定できます。曖昧な場合、<refname> は以下の規則で最初に一致するものによって解決されます。

  1. $GIT_DIR/<refname> が存在する場合、それが意図するものです(これは通常、HEADFETCH_HEADORIG_HEADMERGE_HEADREBASE_HEADREVERT_HEADCHERRY_PICK_HEADBISECT_HEADAUTO_MERGEに対してのみ有用です)。

  2. それ以外の場合、refs/<refname> が存在すればそれを使用します。

  3. それ以外の場合、refs/tags/<refname> が存在すればそれを使用します。

  4. それ以外の場合、refs/heads/<refname> が存在すればそれを使用します。

  5. それ以外の場合、refs/remotes/<refname> が存在すればそれを使用します。

  6. それ以外の場合、refs/remotes/<refname>/HEAD が存在すればそれを使用します。

    HEAD

    ワーキングツリーの変更の基点としたコミットを指します。

    FETCH_HEAD

    前回の git fetch 呼び出しでリモートリポジトリからフェッチしたブランチを記録します。

    ORIG_HEAD

    HEAD を大幅に移動させるコマンド(git amgit mergegit rebasegit reset)によって作成され、それらの操作前の HEAD の位置を記録します。これにより、コマンド実行前の状態にブランチの先端を簡単に戻すことができます。

    MERGE_HEAD

    git merge を実行したときに、あなたのブランチにマージしようとしているコミットを記録します。

    REBASE_HEAD

    リベース中に、競合のため、または対話型リベースの edit コマンドのために、操作が現在停止しているコミットを記録します。

    REVERT_HEAD

    git revert を実行したときに、あなたが元に戻そうとしているコミットを記録します。

    CHERRY_PICK_HEAD

    git cherry-pick を実行したときに、あなたがチェリーピックしようとしているコミットを記録します。

    BISECT_HEAD

    git bisect --no-checkout を実行したときに、現在テストされるべきコミットを記録します。

    AUTO_MERGE

    マージ操作が競合を起こしたときに、ort マージ戦略がワーキングツリーに書き込んだ状態に対応するツリーオブジェクトを記録します。

上記の refs/* のケースは、$GIT_DIR/refs ディレクトリまたは $GIT_DIR/packed-refs ファイルのいずれかから来る可能性があることに注意してください。リファレンス名のエンコーディングは指定されていませんが、一部の出力処理ではリファレンス名がUTF-8であると仮定する場合があるため、UTF-8が推奨されます。

@

@ 単独は HEAD のショートカットです。

[<refname>]@{<date>}、例:master@{yesterday}HEAD@{5 minutes ago}

リファレンスの後に、日付指定を括弧で囲んだサフィックス @(例:*{yesterday}*、*{1 month 2 weeks 3 days 1 hour 1 second ago}* または *{1979-02-26 18:30:00}*)を付けると、過去の時点でのそのリファレンスの値を指定します。このサフィックスはリファレンス名の直後にのみ使用でき、そのリファレンスには既存のログ(*$GIT_DIR/logs/<ref>*)が必要です。これは、特定の時点での**ローカル**リファレンスの状態、例えば先週のローカルの *master* ブランチに何があったかを確認するものです。特定の期間中に作成されたコミットを確認したい場合は、--since--until を参照してください。

<refname>@{<n>}、例:master@{1}

リファレンスの後に、序数指定を括弧で囲んだサフィックス @(例:*{1}*、*{15}*)を付けると、そのリファレンスの n 番目の以前の値を指定します。例えば、*master@{1}* は *master* の直前の値であり、*master@{5}* は *master* の5番目の以前の値です。このサフィックスはリファレンス名の直後にのみ使用でき、そのリファレンスには既存のログ(*$GIT_DIR/logs/<refname>*)が必要です。

@{<n>}、例:@{1}

空のリファレンス部を持つ @ 構造体を使用して、現在のブランチのreflogエントリにアクセスできます。例えば、ブランチ *blabla* にいる場合、*@{1}* は *blabla@{1}* と同じ意味です。

@{-<n>}、例:@{-1}

構造体 @{-<n>} は、現在のブランチ/コミットの前にチェックアウトされた n 番目のブランチ/コミットを意味します。

[<branchname>]@{upstream}、例:master@{upstream}@{u}

ブランチ B は、リモート R(branch.<name>.remote で設定)にあるブランチ X(branch.<name>.merge で設定)の上に構築されるように設定できます。B@{u} は、リモート R から取得したブランチ X のリモート追跡ブランチを指し、通常は refs/remotes/R/X にあります。

[<branchname>]@{push}、例:master@{push}@{push}

サフィックス @{push} は、branchname がチェックアウトされている場合(またはブランチ名が指定されていない場合は現在の HEAD)、git push を実行した場合に「プッシュする先」のブランチを報告します。*@{upstream}* と同様に、リモートのそのブランチに対応するリモート追跡ブランチを報告します。

より明確にするための例を以下に示します

$ git config push.default current
$ git config remote.pushdefault myfork
$ git switch -c mybranch origin/master

$ git rev-parse --symbolic-full-name @{upstream}
refs/remotes/origin/master

$ git rev-parse --symbolic-full-name @{push}
refs/remotes/myfork/mybranch

この例では、ある場所からプルし、別の場所にプッシュする三角ワークフローを設定しています。三角ワークフローではない場合、*@{push}* は *@{upstream}* と同じであり、必要ありません。

このサフィックスは大文字で表記しても受け入れられ、大文字小文字を問わず同じ意味です。

<rev>^[<n>]、例:HEAD^, v1.5.1^0

リビジョンパラメータへのサフィックス ^ は、そのコミットオブジェクトの最初の親を意味します。*^<n>* は n 番目の親を意味します(つまり、*<rev>^* は *<rev>^1* と同等です)。特別なルールとして、*<rev>^0* はコミット自体を意味し、*<rev>* がコミットオブジェクトを参照するタグオブジェクトの名前である場合に使用されます。

<rev>~[<n>]、例:HEAD~, master~3

リビジョンパラメータへのサフィックス ~ は、そのコミットオブジェクトの最初の親を意味します。リビジョンパラメータへのサフィックス *~<n>* は、指定されたコミットオブジェクトの n 世代前の祖先であるコミットオブジェクトを意味し、最初の親のみを辿ります。つまり、*<rev>~3* は *<rev>^^^* と同等であり、*<rev>^1^1^1* と同等です。この形式の使用例については、以下を参照してください。

<rev>^{<type>}、例:v0.99.8^{commit}

サフィックス ^ の後にブレースで囲まれたオブジェクトタイプ名を続けると、*<rev>* にあるオブジェクトを再帰的に逆参照し、*<type>* 型のオブジェクトが見つかるか、オブジェクトがこれ以上逆参照できなくなるまで(その場合はエラー)、逆参照します。例えば、*<rev>* がコミット風であれば、*<rev>^{commit}* は対応するコミットオブジェクトを記述します。同様に、*<rev>* がツリー風であれば、*<rev>^{tree}* は対応するツリーオブジェクトを記述します。*<rev>^0* は *<rev>^{commit}* の短縮形です。

<rev>^{object} は、*<rev>* がタグである必要なく、また *<rev>* を逆参照することなく、*<rev>* が既存のオブジェクトを指すことを確認するために使用できます。タグはすでにオブジェクトであるため、オブジェクトに到達するために一度も逆参照する必要がありません。

<rev>^{tag} は、*<rev>* が既存のタグオブジェクトを識別することを保証するために使用できます。

<rev>^{}、例:v0.99.8^{}

サフィックス ^ の後に空のブレースを続けると、そのオブジェクトがタグである可能性があり、タグではないオブジェクトが見つかるまでタグを再帰的に逆参照することを意味します。

<rev>^{/<text>}、例:HEAD^{/fix nasty bug}

リビジョンパラメータへのサフィックス ^ の後に、スラッシュで始まるテキストを含むブレースを続けると、以下の *:/fix nasty bug* 構文と同じですが、^ の前の *<rev>* から到達可能な、最も新しい一致するコミットを返します。

:/<text>、例::/fix nasty bug

コロンの後にスラッシュ、そしてテキストが続く形式は、指定された正規表現にコミットメッセージが一致するコミットを指します。この名前は、HEADを含む任意のリファレンスから到達可能な、最も新しい一致するコミットを返します。正規表現はコミットメッセージの任意の部分に一致させることができます。文字列で始まるメッセージに一致させるには、例えば *:/^foo* を使用できます。特殊なシーケンス *:/!* は、一致対象への修飾子として予約されています。*:/!-foo* は否定マッチを実行し、*:/!!foo* はリテラルの *!* 文字の後に *foo* が続くものに一致します。*:/!* で始まる他のシーケンスは現在予約されています。指定されたテキストによっては、シェルの単語分割規則により追加の引用符が必要になる場合があります。

<rev>:<path>、例:HEAD:READMEmaster:./README

サフィックス : の後にパスを続けると、コロンの前の部分で指定されたツリー状のオブジェクト内の、指定されたパスにあるBLOBまたはツリーを指します。*./* または *../* で始まるパスは、現在のワーキングディレクトリからの相対パスです。指定されたパスは、ワーキングツリーのルートディレクトリからの相対パスに変換されます。これは、ワーキングツリーと同じツリー構造を持つコミットやツリーからBLOBまたはツリーを指定する際に最も便利です。

:[<n>:]<path>、例::0:README:README

コロンの後にオプションでステージ番号(0から3)とコロン、そしてパスが続く形式は、指定されたパスのインデックス内のBLOBオブジェクトを指します。ステージ番号が省略されている場合(およびそれに続くコロンも)、ステージ0のエントリを指します。マージ中、ステージ1は共通の祖先、ステージ2はターゲットブランチのバージョン(通常は現在のブランチ)、ステージ3はマージされるブランチのバージョンです。

Jon Loeligerによる図を以下に示します。コミットノードBとCはどちらもコミットノードAの親です。親コミットは左から右へ順序付けられています。

G   H   I   J
 \ /     \ /
  D   E   F
   \  |  / \
    \ | /   |
     \|/    |
      B     C
       \   /
        \ /
         A
A =      = A^0
B = A^   = A^1     = A~1
C =      = A^2
D = A^^  = A^1^1   = A~2
E = B^2  = A^^2
F = B^3  = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2  = B^^2    = A^^^2  = A~2^2
I = F^   = B^3^    = A^^3^
J = F^2  = B^3^2   = A^^3^2

範囲の指定

git log のような履歴を辿るコマンドは、単一のコミットだけでなく、一連のコミットに対して操作を行います。

これらのコマンドでは、前のセクションで説明した表記法を使用して単一のリビジョンを指定すると、指定されたコミットから到達可能なコミットのセットを意味します。

複数のリビジョンを指定すると、指定されたいずれかのコミットから到達可能なコミットのセットを意味します。

コミットの到達可能なセットとは、コミット自体とその祖先チェーン内のコミットです。

連結されたコミットのセット(「リビジョン範囲」と呼ばれる)を指定するためのいくつかの表記法があり、以下に示します。

コミットの除外

^<rev>(キャレット)表記

コミットから到達可能なコミットを除外するには、プレフィックス ^ 表記を使用します。例:*^r1 r2* は、*r2* から到達可能だが *r1* から到達可能なコミット(つまり *r1* とその祖先)を除くことを意味します。

ドット範囲表記

..(2ドット)範囲表記

*^r1 r2* という集合演算は頻繁に現れるため、そのショートハンドが存在します。*r1* と *r2* という2つのコミット(上記の「リビジョンの指定」で説明されている構文に従って命名されたもの)がある場合、*r1* から到達可能なコミットを除いて *r2* から到達可能なコミットを *^r1 r2* で要求でき、これは *r1..r2* と記述できます。

...(3ドット)対称差分表記

類似の表記 *r1...r2* は *r1* と *r2* の対称差分と呼ばれ、*r1 r2 --not $(git merge-base --all r1 r2)* と定義されます。これは、*r1*(左側)または *r2*(右側)のいずれか一方から到達可能であるが、両方からは到達可能ではないコミットのセットです。

これら2つのショートハンド表記では、片方の端を省略してHEADをデフォルトにすることができます。例えば、*origin..* は *origin..HEAD* のショートハンドであり、「originブランチからフォークして以来、私が何をしたか?」を尋ねます。同様に、*..origin* は *HEAD..origin* のショートハンドであり、「私が彼らからフォークして以来、originは何をしたか?」を尋ねます。*..* は *HEAD..HEAD* を意味し、これはHEADから到達可能でも到達不可能でもある空の範囲であることに注意してください。

2つの異なる範囲を取るように特別に設計されたコマンド(例:「git range-diff R1 R2」で2つの範囲を比較)は存在しますが、これらは例外です。特に明記されていない限り、一連のコミットを操作するすべての「git」コマンドは単一のリビジョン範囲で動作します。言い換えれば、2つの「2ドット範囲表記」を並べて記述しても、例えば

$ git log A..B C..D

ほとんどのコマンドでは2つのリビジョン範囲を**指定しません**。代わりに、単一の連結されたコミットのセット、つまりBまたはDのいずれかから到達可能だが、AまたはCのどちらからも到達可能ではないコミットを指します。このような線形履歴の場合

---A---B---o---o---C---D

AとBはCから到達可能であるため、これら2つの点付き範囲で指定されるリビジョン範囲は単一のコミットDです。

その他の <rev>^ 親の短縮表記

特にマージコミットに有用な、コミットとその親コミットで構成されるセットを指定するための3つの他のショートハンドが存在します。

r1^@ 表記は *r1* のすべての親を意味します。

r1^! 表記はコミット *r1* を含みますが、そのすべての親を除外します。それ自体では、この表記は単一のコミット *r1* を示します。

<rev>^-[<n>]* 表記は *<rev>* を含みますが、n 番目の親を除外します(つまり、*<rev>^<n>..<rev>* のショートハンドで、*<n>* が指定されない場合は 1)。これは、マージコミット *<commit>* でマージされたブランチ内のすべてのコミット(*<commit>* 自体を含む)を取得するために、単に *<commit>^-* を渡すことができるマージコミットで通常役立ちます。

<rev>^<n> が単一のコミット親を指定するものであったのに対し、これら3つの表記法はその親も考慮します。例えば、*HEAD^2^@* と言うことはできますが、*HEAD^@^2* と言うことはできません。

リビジョン範囲の概要

<rev>

<rev> から到達可能なコミットを含めます(つまり、<rev> とその祖先)。

^<rev>

<rev> から到達可能なコミットを除外します(つまり、<rev> とその祖先)。

<rev1>..<rev2>

<rev2> から到達可能なコミットを含めますが、<rev1> から到達可能なコミットを除外します。<rev1> または <rev2> のいずれかが省略された場合、デフォルトは HEAD になります。

<rev1>...<rev2>

<rev1> または <rev2> のいずれかから到達可能なコミットを含めますが、両方から到達可能なコミットを除外します。<rev1> または <rev2> のいずれかが省略された場合、デフォルトは HEAD になります。

<rev>^@、例:HEAD^@

アットサインが続くサフィックス ^ は、*<rev>* のすべての親をリストするのと同じです(つまり、親から到達可能なものはすべて含みますが、コミット自体は含みません)。

<rev>^!、例:HEAD^!

感嘆符が続くサフィックス ^ は、コミット *<rev>* とそのすべての親を *^ でプレフィックスして除外する(およびその祖先)のと同じです。

<rev>^-<n>、例:HEAD^-, HEAD^-2

<rev>^<n>..<rev> と同等で、*<n>* が指定されない場合は 1 です。

上に示したLoeligerの図を使用したいくつかの例を以下に示します。各表記の展開と選択の各ステップは慎重に説明されています。

   Args   Expanded arguments    Selected commits
   D                            G H D
   D F                          G H I J D F
   ^G D                         H D
   ^D B                         E I J F B
   ^D B C                       E I J F B C
   C                            I J F C
   B..C   = ^B C                C
   B...C  = B ^F C              G H D E B C
   B^-    = B^..B
	  = ^B^1 B              E I J F B
   C^@    = C^1
	  = F                   I J F
   B^@    = B^1 B^2 B^3
	  = D E F               D G H E F I J
   C^!    = C ^C^@
	  = C ^C^1
	  = C ^F                C
   B^!    = B ^B^@
	  = B ^B^1 ^B^2 ^B^3
	  = B ^D ^E ^F          B
   F^! D  = F ^I ^J D           G H D F

関連項目

GIT

git[1] スイートの一部

scroll-to-top