เทียบเท่าในคอมไพล์ของ "hg cat" หรือ "svn cat"


84

ฉันต้องการแยกสำเนาของเวอร์ชันล่าสุดของไฟล์ที่อยู่ในที่เก็บ git และส่งไปยังสคริปต์สำหรับการประมวลผลบางอย่าง ด้วย svn หรือ hg ฉันใช้คำสั่ง "cat":

พิมพ์ไฟล์ที่ระบุตามที่มีอยู่ในการแก้ไขที่กำหนด หากไม่มีการแก้ไขจะใช้พาเรนต์ของไดเร็กทอรีการทำงานหรือให้คำแนะนำหากไม่มีการตรวจสอบการแก้ไข

(มาจากคำอธิบายของ hg cat ในเอกสาร hg)

คำสั่งที่เทียบเท่ากับ git คืออะไร?


4
ทางออกสุดท้ายของฉันคือใช้ "git ls-files --full-name <filepath>" ก่อนเพื่อรับเส้นทางแบบเต็มที่สัมพันธ์กับด้านบนของที่เก็บจากนั้น "git show HEAD: <full filepath>"
Richard Boulton


คำตอบ:


113
git show rev:path/to/file

ที่ไหนรอบคือการแก้ไข

ดูhttp://git.or.cz/course/svn.htmlสำหรับการเปรียบเทียบคำสั่ง git และ svn


1
สิ่งนี้ใช้ได้กับฉันเย้! (โดยใช้ HEAD เป็นการแก้ไข) ฉันคิดว่าฉันต้องใช้เส้นทางที่สัมพันธ์กับด้านบนของที่เก็บซึ่งค่อนข้างเจ็บ แต่ก็สามารถใช้งานได้
Richard Boulton

@Richard Boulton: เจ็บน้อยกว่าถ้าใช้ tab
complete

@pimlottc ทำงานได้ดีสำหรับฉันโดยไม่มี. / - อาจขึ้นอยู่กับเวอร์ชัน git
Trejkaz

9

มี "git cat-file" ซึ่งคุณสามารถเรียกใช้ดังนี้:

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

โดยที่คุณสามารถแทนที่ 'v1.0' ด้วย branch แท็กหรือคอมมิต SHA ที่คุณต้องการจากนั้น 'path / to / file' ด้วยพา ธ สัมพัทธ์ในที่เก็บ คุณยังสามารถส่ง '-s' เพื่อดูขนาดของเนื้อหาได้หากต้องการ

อาจใกล้เคียงกับคำสั่ง 'cat' ที่คุณคุ้นเคยแม้ว่า 'show' ที่กล่าวถึงก่อนหน้านี้จะทำสิ่งเดียวกันมาก


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.

ดูเหมือนจะใช้ไม่ได้: การเรียกใช้ "git show next ~ 1: README" ทำให้เกิดการโต้แย้งที่ไม่ชัดเจน 'next ~ 1: README': การแก้ไขที่ไม่รู้จักหรือเส้นทางที่ไม่อยู่ในโครงสร้างการทำงาน ใช้ '-' เพื่อแยกเส้นทางจากการแก้ไข
Richard Boulton

1
คุณมีสาขาชื่อ 'next' หรือไม่? หากคุณต้องการสาขาปัจจุบันให้ใช้ "HEAD" แทน
Andrew Aylett

3

ทำงานกับชื่อสาขาด้วย (เช่น HEAD ในหน้าแรก):

git show $branch:$filename



1

ดูเหมือนจะไม่มีสิ่งทดแทนโดยตรง รายการบล็อกนี้ให้รายละเอียดเกี่ยวกับวิธีการเทียบเท่าโดยการกำหนดคอมมิตล่าสุดจากนั้นกำหนดแฮชสำหรับไฟล์ในคอมมิตนั้นจากนั้นจึงทิ้งออก

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

(รายการบล็อกพิมพ์ผิดและใช้คำสั่งด้านบนsvn)


รายการบล็อกมีประโยชน์แม้จะพิมพ์ผิด
Richard Boulton

0

ไม่มี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 );
}

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.