「hgcat」または「svncat」のgitに相当


84

gitリポジトリに保持されているファイルの最新バージョンのコピーを抽出し、それをスクリプトに渡して処理したいと思います。svnまたはhgでは、「cat」コマンドを使用するだけです。

指定されたリビジョンのファイルをそのまま印刷します。リビジョンが指定されていない場合は、作業ディレクトリの親が使用されます。リビジョンがチェックアウトされていない場合は、ヒントが使用されます。

(これは、hgドキュメントのhg catの説明からのものです)

gitでこれを行うための同等のコマンドは何ですか?


4
私の最終的な解決策は、最初に「git ls-files --full-name <filepath>」を使用してリポジトリの先頭を基準にしたフルパスを取得し、次に「git show HEAD:<fullfilepath>」を使用することでした
Richard Boulton


回答:


113
git show rev:path/to/file

ここで、revはリビジョンです。

gitコマンドとsvnコマンドの比較については、http://git.or.cz/course/svn.htmlを参照してください


1
これは私にとってはうまくいきます、イェーイ!(リビジョンとしてHEADを使用)リポジトリの先頭を基準にしたパスを使用する必要があると思います。これは少し面倒ですが、実行可能です。
リチャードボールトン2010年

@Richard Boulton:タブ補完を使用すると、これはそれほど苦痛ではありません
ks1322 2013

@pimlottcは./なしで問題なく
動作しました-git

9

次のように実行できる「gitcat-file」があります。

$ git cat-file blob v1.0:path/to/file

ここで、「v1.0」を必要なブランチ、タグ付け、またはコミットSHAに置き換えてから、「path / to / file」をリポジトリ内の相対パスに置き換えることができます。必要に応じて、「-s」を渡してコンテンツのサイズを確認することもできます。

前述の「show」でもほとんど同じことができますが、慣れている「cat」コマンドに近いかもしれません。


6

git showあなたが探しているコマンドです。ドキュメントから:

   git show next~10:Documentation/README
          Shows the contents of the file Documentation/README as they were
          current in the 10th last commit of the branch next.

それは機能していないようです。「gitshownext〜1:README」を実行すると、致命的です:あいまいな引数 'next〜1:README':不明なリビジョンまたはパスが作業ツリーにありません。'-'を使用して、パスをリビジョンから分離します
Richard Boulton 2010年

1
'next'というブランチはありますか?現在のブランチが必要な場合は、代わりに「HEAD」を使用してください。
Andrew Aylett 2010年

3

ブランチ名も操作します(最初のpのHEADなど):

git show $branch:$filename



1

直接的な代替手段はないようです。このブログエントリでは、最新のコミットを決定し、そのコミット内のファイルのハッシュを決定し、それをダンプすることによって、同等の方法を詳しく説明しています。

git log ...
git ls-tree ...
git show -p ...

(ブログエントリにはタイプミスがあり、コマンドで上記を使用しますsvn


タイプミスにもかかわらず、ブログエントリは役に立ちました。
リチャードボールトン2010年

0

git show(私がそうするかもしれないが)、出力の上部からメタデータの断片を取得しない方法を見つけることができないので、提案のどれも本当に満足しません。cat(1)の精神は、内容を表示することだけです。これ(以下)は、ファイル名とオプションの番号を取ります。数は、どのようにコミットを戻したいかです。(そのファイルを変更したコミット。ターゲットファイルを変更しないコミットはカウントされません。)

gitcat.pl filename.txt
gitcat.pl -3 filename.txt

は、filename.txtの最新のコミット時点でのfilename.txtの内容と、それ以前の3つのコミットの内容を示しています。

#!/usr/bin/perl -w

use strict;
use warnings;
use FileHandle;
use Cwd;

# Have I mentioned lately how much I despise git?

(my $prog = $0) =~ s!.*/!!;
my $usage = "Usage: $prog [revisions-ago] filename\n";

die( $usage ) if( ! @ARGV );
my( $revision, $fname ) = @ARGV;

if( ! $fname && -f $revision ) {
    ( $fname, $revision ) = ( $revision, 0 );
}

gitcat( $fname, $revision );

sub gitcat {
    my( $fname, $revision ) = @_;

    my $rev = $revision;
    my $file = FileHandle->new( "git log --format=oneline '$fname' |" );

    # Get the $revisionth line from the log.
    my $line;
    for( 0..$revision ) {
        $line = $file->getline();
    }

    die( "Could not get line $revision from the log for $fname.\n" ) 
        if( ! $line );

    # Get the hash from that.
    my $hash = substr( $line, 0, 40 );
    if( ! $hash =~ m/ ^ ( [0-9a-fA-F]{40} )/x ) {
        die( "The commit hash does not look a hash.\n" );
    }

    # Git needs the path from the root of the repo to the file because it can
    # not work out the path itself.
    my $path = pathhere();
    if( ! $path ) {
        die( "Could not find the git repository.\n" );
    }

    exec( "git cat-file blob $hash:$path/'$fname'" );
}


# Get the path from the git repo to the current dir.
sub pathhere {
    my $cwd = getcwd();
    my @cwd = split( '/', $cwd );
    my @path;

    while( ! -d "$cwd/.git" ) {
        my $path = pop( @cwd );
        unshift( @path, $path );
        if( ! @cwd ) {
            die( "Did not find .git in or above your pwd.\n" );
        }
        $cwd = join( '/', @cwd );
    }
    return join( '/', map { "'$_'"; } @path );
}

0

bashを使用している場合、以下は便利な関数です。

gcat () { if [ $# -lt 1 ]; then echo "Usage: $FUNCNAME [rev] file"; elif [ $# -lt 2 ]; then git show HEAD:./$*; else git show $1:./$2; fi }

それを.bashrcファイルに入れます(gcat。以外の好きな名前を使用できます。

使用例:

> gcat
Usage: gcat [rev] file

または

> gcat subdirectory/file.ext

または

> gcat rev subdirectory/file.ext
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.