Gitの特定のリビジョンから単一のファイルを取得するにはどうすればよいですか?


832

Gitリポジトリーがあり、数か月前にいくつかのファイルがどのように表示されたかを確認したいと思います。私はその日付で改訂を見つけました。それはです27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8。1つのファイルがどのように見えるかを確認し、それを(「新しい」)ファイルとして保存する必要があります。

でファイルを確認gitkできましたが、保存するオプションがありません。私はコマンドラインツールを試してみました、私が得た最も近いものは:

git-show 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8 my_file.txt

ただし、このコマンドはファイルの内容ではなく差分を表示します。私は後でのようなものを使用してPAGER=cat出力をファイルにリダイレクトできることを知っていますが、実際のファイルのコンテンツに到達する方法がわかりません。

基本的に、私はsvn catのようなものを探しています。


73
ここでのキー:(git show役に立たない)コロン付きの異なる構文を使用します。git show 2c7cf:my_file.txt
スティーブベネット

4
さらに明確にするために、上記のコマンドはgitに2つの個別のオブジェクト、リビジョンとファイルを表示するように要求しています。2つの項目の間にコロンを使用する以下の受け入れられた回答は、特定のリビジョンの特定のファイルを要求しています。
jhclark

2
* nixではPAGERは不要で、シェル出力リダイレクト>
Konstantin Pelepelin 2013年


Checatには、コンテンツをファイルにエクスポートしたい人のための重要なコメントがあります。次のようなものが必要です:git show {sha}:my_file.txt> old_my_file.txt
ormurin

回答:


744

あなた自身の答えを完成させるために、構文は確かに

git show object
git show $REV:$FILE
git show somebranch:from/the/root/myfile.txt
git show HEAD^^^:test/test.py

このコマンドは通常のスタイルのリビジョンを使用します。つまり、次のいずれかを使用できます。

  1. ブランチ名(ashによって提案れる
  2. HEAD+ x ^文字数
  3. 特定のリビジョンのSHA1ハッシュ
  4. 特定のSHA1ハッシュの最初の数文字(おそらく5文字)

ヒント " git show" を使用する場合は、現在のディレクトリの位置ではなく、常にリポジトリのルートからのパスを指定することに注意してください。

Mike Moreartyによると、少なくともgit 1.7.5.4では./、パスの先頭に" "を置くことで相対パスを指定できます-たとえば、

git show HEAD^^:./test.py


Git 2.23以降(2019年8月)では、紛らわしいコマンドのgit restore 代わりに使用することもできます。git checkout

git restore -s <SHA1>     -- afile
git restore -s somebranch -- afile

これは、「ソース」(-sコミットSHA1またはブランチに存在するファイルのみを作業ツリーに復元しますsomebranch
インデックスも復元するには:

git restore -s <SHA1> -SW -- afile

-SW:の略--staged --worktree


git1.5.x以前は、それはいくつかの配管で行われていました:

git ls-tree <rev>
コミット内の1つ以上の「blob」オブジェクトのリストを表示する

git cat-file blob <file-SHA1>
特定のリビジョン内でコミットされたファイルをcatします(svn catと同様)。git ls-treeを使用して、指定されたfile-sha1の値を取得します

git cat-file -p $(git-ls-tree $REV $file | cut -d " " -f 3 | cut -f 1)::

git-ls-treeはリビジョン$ REVの$ fileのオブジェクトIDをリストします。これは出力から切り取られ、git-cat-fileへの引数として使用されます。これは実際にはgit-cat-objectと呼ばれ、単純にダンプされます。そのオブジェクトを標準出力に。


注:Git 2.11(2016年第4四半期)以降、コンテンツフィルターをgit cat-file出力に適用できます!

参照してください。3214594コミット7bcf341コミット、(2016年9月9日)を7bcf341コミット(2016年9月9日)、およびb9e62f6コミット16dcc29コミットすることにより(2016年8月24日)ヨハネスSchindelinを(dscho
(合併によりJunio C浜野- gitster-7889ed2コミットし、2016年9月21日)を

cat-file:サポート--textconv/ --filtersバッチモード

git hash-objects」はファイルシステム上のデータストリームを取得してGitオブジェクトストアに配置するツールですが、「outside-world-to-Git」変換(行末変換やアプリケーションなど)を実行できますクリーンフィルター)の機能であり、非常に早い時期からデフォルトで機能がオンになっていたためgit cat-file、Gitオブジェクトストアからオブジェクトを取得して外部からの消費のために外部化するその逆の操作 " "には、同等のメカニズムがありませんでした。 「Git-to-outside-world」を実行する

git config diff.txt.textconv "tr A-Za-z N-ZA-Mn-za-m <"
git cat-file --textconv --batch

注:「git cat-file --textconv」は最近(2017年)segfaultingを開始しましたが、Git 2.15(2017年第4四半期)で修正されました。

Jeff King()によるcommit cc0ea7c(2017年9月21日)を参照してください。(による合併Junio C浜野- -コミットbfbc2fc、2017年9月28日)peff
gitster


することを注意上書き/置き換え過去のコンテンツを持つファイル、あなたは使用しないでください混乱git checkoutコマンドをもうが、git restore(Gitの2.23+、2019年8月)

git restore -s <SHA1> -- afile

これは、「ソース」(-s)コミットSHA1に存在するファイルのみを作業ツリーに復元します。
インデックスも復元するには:

git restore -s <SHA1> -SW -- afile

-SW:の略--staged --worktree


6
@Oscarはgit show基本的にstdout(標準出力)にコンテンツをダンプするため、その出力を任意のファイル(tldp.org/LDP/abs/html/io-redirection.html)にリダイレクトできます。
VonC、2012年

8
git checkout [branch | revision] filepath正しいコマンドです
Gaui

12
@Gaui git checkoutは、ファイルを別のバージョンで上書きしますがgit show、これを別の名前で保存して、両方(現在のバージョンと古いバージョン)を取得して表示することができます。OPが現在のバージョンを古いバージョンに置き換えたいかどうかは、質問からは明らかではありません。
VonC 2013

9
私は^^^より一般的に、~~~またはより良いように書くこともできることに注意したいと思い~3ます。チルダを使用することには、一部のシェル(たとえば、zsh)のファイル名マッチングをトリガーしないという利点もあります。
Eric O Lebigot 2013年

2
チェックするのに十分古いgitがありません:1.5.x以前のバージョンは構文をgit rev-parse処理しrev:pathますか?(より最近のgitでは、次のことができgit cat-file -p $REV:pathます。ただし、git showディレクトリパスでも機能するため、短いだけでなく、通常は望んでいるものに近くなります。)
torek

510

現在のブランチのファイルのコンテンツを、以前のコミットまたは別のブランチのファイルのコンテンツで置換/上書きしたい場合は、次のコマンドで行うことができます。

git checkout 08618129e66127921fbfcbc205a06153c92622fe path/to/file.txt

または

git checkout mybranchname path/to/file.txt

これらの変更を現在のブランチで有効にするために、それらをコミットする必要があります。


4
最も簡単なソリューションであり、これがgit-checkoutの設計です。パス名を指定すると、一致するファイルのみがチェックアウトされます。git-checkoutのmanページから:git checkout
master〜2

1
次に、このコマンドを実行する前に、どのように前の状態に戻るのですか?
Flint

@Flint HEAD状態から来ている場合は、git checkout HEAD-[フルパス]と同じくらい簡単です。
Tiago Espinha 2013年

72
これにより、そのパスにある既存のファイルが上書きされますが、 git show SHA1:PATHソリューションはstdoutにのみ出力する。
Flimm 2014年

いいね!私はこれを見ることでこれを理解することができなかっただろうgit help checkout。私は、特定の日付のようにサブディレクトリをチェックアウトしなければならなかったし、このアプローチを使用して、私が働いてこの構文を得ることができる:git checkout @{YYYY-MM-DD} sub-dir
haridsv

150

ファイルへのフルパスを提供する必要があります:

git show 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8:full/repo/path/to/my_file.txt

7
フルパスである必要はありません。gitルートディレクトリからのパス(来た人でgit show --name-onlyも十分です
Mohsen 2013年

7
えーっと、リポジトリのルートからのフルパス。私が与えた例をよく見てください。「完全」の前にスラッシュはありません。
ミラノバブスコフ2013年

7
参考までに、サブディレクトリにいる場合は、。/ filename.extも正常に使用できます。
トラベラー

ポイントは、あなたが入っfull/repo/path/toて試してみると:のgit show 27cf8e84:my_file.txtようなメッセージで報われるでしょう: fatal:Path 'full / repo / path / to / my_file.txt'は存在しますが 'my_file.txt'は存在しません。 「27cf8e84:full / repo / path / to / my_file.txt」または「27cf8e84:./ my_file.txt」という意味ですか?それは、Gitが直接手助けしたかもしれないようなものですが、ここでは独創的であることにしました。
Ed Randall

101

最も簡単な方法は、書き込みにあります:

git show HASH:file/path/name.ext > some_new_name.ext

どこ:

  • HASHはGitリビジョンのSHA-1ハッシュ番号です
  • file / path / name.extは、探しているファイルの名前です
  • some_new_name.extは、古いファイルを保存するパスと名前です

git show 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8:my_file.txt > my_file.txt.OLD

これは、保存されますmy_file.txtリビジョンから27cf8eを名前で新しいファイルとしてmy_file.txt.OLD

Git 2.4.5でテストされています。

削除したファイルを取得したい場合は、使用できますHASH~1(指定したHASHの前に1回コミットします)。

例:

git show 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8~1:deleted_file.txt > deleted_file.txt

1
追加情報:git logを使用して
ハッシュ

@xotixありがとう。特定のファイルのすべてのHASH履歴を取得しましたgit log file/path/name.ext
Sriram Kannan

11

WindowsでGit Bashを使用する場合:

  • ワークスペースで、dirをファイルが存在するフォルダーに変更します。
  • git show cab485c83b53d56846eb883babaaf4dff2f2cc46:./your_file.ext > old.ext

8

そして、それをファイルにうまくダンプするには(少なくともWindowsでは)-Git Bash:

$ echo "`git show 60d8bdfc:src/services/LocationMonitor.java`" >> LM_60d8bdfc.java

"それは改行を維持するように、引用符が必要です。


良いですね。+1。上でgit show述べた構文の良い追加。
VonC、2014年

23
引用符の有無にかかわらず、なぜechoを使用するのか本当に理解できません。また、出力リダイレクトの追加形式が必要な理由がわかりません。単純に次のように記述した方がよいでしょう:git show 60d8bdfc:src / services / LocationMonitor.java> LM_60d8bdfc.java何らかの理由で実際にdosスタイルの行末を強制したい場合は、unix2dosを介してパイプできます。しかし、私がWindowsで使用したメモ帳以外のテキストツールはunixスタイルの行をうまく処理するので、Windowsでdos行末を保持することが最も有用であることに気づきませんでした。
sootsnoot 2014年

4
git show 60d8bdfc:src / services / LocationMonitor.java >> LM_60d8bdfc.javaがうまくいきました。
Mike6679

@マイク:あなたはウィンドウズですか?
Mr_and_Mrs_D 2015年

2
シェル変数のように見えるファイル文字、つまり$ LANGは置換されるため、二重引用符は使用しないでください。@LưuVĩnhPhúcはセーバーです。また、使用しない>>ファイルが存在する場合はファイルを追加し、エラーが発生する可能性があります
theguy

3

これにより、パスを指定せずにコミット間ですべての削除済みファイルを取得できます。削除されたファイルが多数ある場合に役立ちます。

git diff --name-only --diff-filter=D $commit~1 $commit | xargs git checkout $commit~1

1
git checkout {SHA1} -- filename

このコマンドは、特定のコミットからコピーされたファイルを取得します。


-2

以前のコミットをチェックアウトしてファイルをコピーすることにより、以前のコミットからファイルを取得します。

  • 現在のブランチに注意してください:git branch
  • 必要な以前のコミットをチェックアウトします。 git checkout 27cf8e84bb88e24ae4b4b3df2b77aab91a3735d8
  • 必要なファイルを一時的な場所にコピーします
  • 開始したブランチをチェックアウトします。 git checkout theBranchYouNoted
  • 一時的な場所に配置したファイルをコピーします
  • 変更をgitにコミットします。 git commit -m "added file ?? from previous commit"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.