相当于“hg cat”或“svn cat”的git

时间:2010-01-15 12:07:25

标签: git version-control

我想提取git存储库中保存的最新版本文件的副本,并将其传递给脚本进行一些处理。使用svn或hg,我只使用“cat”命令:

  

按指定的修订版打印指定的文件。如果   没有给出修改,使用工作目录的父级,   如果没有签出修改,则提示或提示。

(这是来自hg文档中hg cat的描述)

使用git执行此操作的等效命令是什么?

9 个答案:

答案 0 :(得分:109)

git show rev:path/to/file

rev 是修订版。

有关git和svn命令的比较,请参阅http://git.or.cz/course/svn.html

答案 1 :(得分:9)

有“git cat-file”,您可以这样运行:

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

您可以将“v1.0”替换为所需的分支,标记或提交SHA,然后使用存储库中的相对路径替换“path / to / file”。如果需要,您还可以传递'-s'来查看内容的大小。

可能更接近你习惯的'猫'命令,虽然前面提到的'show'会做同样的事情。

答案 2 :(得分:5)

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.

答案 3 :(得分:3)

还可以使用分支名称(如第1页中的HEAD):

git show $branch:$filename

答案 4 :(得分:2)

使用 git show ,如git show commit_sha_id:path/to/some/file.cs

答案 5 :(得分:2)

我写了一个git cat shell脚本,up on github

答案 6 :(得分:1)

似乎没有直接替代品。 This blog entry详细说明了如何通过确定最新提交来执行等效操作,然后确定该提交中文件的哈希值,然后将其转储出来。

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

(博客条目有拼写错误并使用上面的命令svn

答案 7 :(得分: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 );
}

答案 8 :(得分: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