"Hg cat" veya "svn cat" in git ile eşdeğerdir


84

Git deposunda tutulan bir dosyanın en son sürümünün bir kopyasını çıkarmak ve bazı işlemler için bir komut dosyasına aktarmak istiyorum. Svn veya hg ile sadece "cat" komutunu kullanıyorum:

Belirtilen dosyaları, verilen revizyonda olduğu gibi yazdırın. Herhangi bir revizyon verilmemişse, çalışma dizininin üstü kullanılır veya revizyon teslim alınmazsa bahşiş verilir.

(bu, hg belgelerinde hg cat tanımından gelmektedir)

Bunu git ile yapmak için eşdeğer komut nedir?


4
Son çözümüm, deponun tepesine göre tam yolu elde etmek için önce "git ls-files --full-name <dosya yolu>" ve ardından "git show HEAD: <tam dosya yolu>" kullanmaktı
Richard Boulton


Yanıtlar:


113
git show rev:path/to/file

Nerede devir revizyon olduğunu.

Git ve svn komutlarının karşılaştırması için http://git.or.cz/course/svn.html adresine bakın .


1
Bu benim için çalışıyor, yaşasın! (Revizyon olarak HEAD'i kullanarak) Sanırım yolu deponun tepesine göre kullanmam gerekiyor, bu biraz acı verici ama uygulanabilir.
Richard Boulton

@Richard Boulton: Sekme tamamlama kullanılırsa bu daha az acı verici
ks1322

@pimlottc benim için ./ olmadan iyi çalıştı - git sürümüne bağlı olabilir
Trejkaz

9

şu şekilde çalıştırabileceğiniz "git cat-file" vardır:

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

burada 'v1.0'ı istediğiniz dal, etiket veya yürütme SHA ile ve ardından' yol / dosya / arşiv'i göreceli yol ile değiştirebilirsiniz. İsterseniz içeriğin boyutunu görmek için '-s' de geçebilirsiniz.

daha önce bahsedilen 'show' aynı şeyi yapsa da, alışkın olduğunuz 'kedi' komutlarına daha yakın olabilir.


6

git showaradığınız komuttur. Belgelerden:

   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.

Bu işe yaramıyor gibi görünüyor: "git show next ~ 1: README" komutunu çalıştırmak ölümcül: belirsiz bağımsız değişken 'next ~ 1: README': bilinmeyen revizyon veya çalışma ağacında olmayan yol. Yolları revizyonlardan ayırmak için '-' kullanın
Richard Boulton

1
'Sonraki' adında bir şubeniz var mı? Mevcut dalı istiyorsanız, bunun yerine 'HEAD' kullanın.
Andrew Aylett

3

Ayrıca şube adlarıyla da çalışın (1. p'deki HEAD gibi):

git show $branch:$filename


2

Ben ise bir git kedi kabuk komut dosyası yazdı github üzerinde


1
Bunun için koda bakmak yardımcı oldu, ancak bağımsız bir python betiği istedim ve git cat'in tüm özelliklerine ihtiyacım yoktu. Teşekkürler.
Richard Boulton

1

Doğrudan bir ikame gibi görünmüyor . Bu blog girişi , en son yürütmeyi belirleyerek, ardından bu işlemedeki dosyanın karmasını belirleyerek ve ardından dökümünü alarak eşdeğerin nasıl yapılacağını ayrıntılarıyla anlatıyor .

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

(blog girişinde yazım hataları vardır ve yukarıdaki komutla birlikte kullanılır svn)


Yazım hatalarına rağmen blog girişi yardımcı oldu.
Richard Boulton

0

git showÖnerilerin hiçbiri gerçekten tatmin etmiyor çünkü (elimden geldiğince deneyin), meta veriyi çıktının tepesinden almamanın bir yolunu bulamıyorum. Kedinin ruhu (1) sadece içeriği göstermektir. Bu (aşağıda) bir dosya adı ve isteğe bağlı bir numara alır. Numara, geri dönmek istediğiniz işlemlerin nasıl olduğudur. (Bu dosyayı değiştiren işlemeler. Hedef dosyayı değiştirmeyen işlemeler sayılmaz.)

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

filename.txt dosyasının en son işleminden itibaren dosyaadı.txt içeriğini ve bundan önceki 3 işlemin içeriğini gösterir.

#!/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 kullananlar için aşağıdaki yararlı bir işlevdir:

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

.bashrcDosyanıza koyun (dışında istediğiniz adı kullanabilirsiniz gcat.

Örnek kullanım:

> gcat
Usage: gcat [rev] file

veya

> gcat subdirectory/file.ext

veya

> gcat rev subdirectory/file.ext
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.