Эквивалент в git "hg cat" или "svn cat"

Я хочу извлечь копию последней версии файла, хранящейся в репозитории git, и передать его в script для некоторой обработки. С помощью svn или hg я просто использую команду "cat":

Распечатайте указанные файлы так, как они были в данной ревизии. Если никакая ревизия не указана, используется родительский элемент рабочего каталога, или наконечник, если ревизия не проверена.

(что из описания hg cat в документации hg)

Что эквивалентная команда для этого с помощью git?

Ответ 1

git show rev:path/to/file

Где rev - это ревизия.

См. http://git.or.cz/course/svn.html для сравнения команд git и svn.

Ответ 2

есть "git cat-file", который вы можете запустить следующим образом:

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

где вы можете заменить "v1.0" на ветку, тег или скопировать SHA, а затем "path/to/file" с относительным путем в репозитории. Вы также можете передать '-s', чтобы увидеть размер содержимого, если хотите.

может быть ближе к командам 'cat', к которым вы привыкли, хотя ранее упомянутое "шоу" будет делать то же самое.

Ответ 3

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.

Ответ 4

Также работайте с именами ветвей (например, HEAD в 1-м p):

git show $branch:$filename

Ответ 5

Используйте git show, как в git show commit_sha_id:path/to/some/file.cs.

Ответ 6

Я написал оболочку git cat script, которая на github

Ответ 7

Кажется, что нет прямой замены. В этой записи в блоге подробно описывается, как сделать эквивалент, определив последнюю фиксацию, затем определив хэш для файла в этом коммите, а затем сбросив его из.

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

(запись в блоге имеет опечатки и использует вышеуказанное с помощью команды svn)

Ответ 8

Ни один из предложений git show действительно не удовлетворяет, потому что (попробуйте, как я мог бы), я не могу найти способ не получить метаданные с вершиной выхода. Дух кошки (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 );
}

Ответ 9

Для тех, кто использует 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