2010-01-15 4 views
80

Ich möchte eine Kopie der neuesten Version einer Datei in einem Git-Repository extrahieren und für einige Bearbeitungen in ein Skript übergeben. Mit svn oder hg verwende ich einfach den "cat" -Befehl:Entspricht in git von "hg cat" oder "svn cat"

Drucken Sie die angegebenen Dateien so, wie sie bei der angegebenen Revision waren. Wenn keine Revision angegeben ist, wird das übergeordnete Element des Arbeitsverzeichnisses verwendet, oder Tipp, wenn keine Revision ausgecheckt ist.

(das ist aus der Beschreibung der hg Katze in der hg Dokumentation)

Was ist der entsprechende Befehl dieses mit git zu tun?

+3

Meine letzte Lösung war zum ersten "git ls-files --full-name " verwenden, um den vollständigen Pfad relativ zum oberen Rand des Repository, und dann „git show HEAD: " –

+1

mögliches Duplikat von [Wie kann eine einzelne Datei von einer bestimmten Revision in Git abgerufen werden?] (http://stackoverflow.com/questions/610208/how-to-retrieve-a-single-file -from-specific-revision-in-git) – ks1322

+1

mögliches Duplikat von [Gibt es einen schnellen Git-Befehl, um eine alte Version einer Datei anzuzeigen?] (http://stackoverflow.com/questions/338436/is-there-a -quick-git-command-zu-sehen-eine-alte-Version-of-a-fil e) –

Antwort

106
git show rev:path/to/file 

Wo rev ist die Revision.

Siehe http://git.or.cz/course/svn.html für einen Vergleich der Befehle git und svn.

+1

Das funktioniert für mich, yay! (Ich benutze HEAD als Revision) Ich denke, ich muss den Pfad relativ zum Anfang des Repository verwenden, was ein bisschen mühsam, aber praktikabel ist. –

+1

Geringes Problem, das sollte git show rev sein: ./ Pfad/zu/Datei – pimlottc

+0

@Richard Boulton: Dies ist weniger schmerzhaft, wenn Tab completition – ks1322

1

Es scheint kein direkter Ersatz zu sein. This blog entry Details wie das Äquivalent zu tun, indem Sie die neuesten Commit, dann bestimmen den Hash für die Datei in diesem Commit, und dann dumping out.

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

(der Blog-Eintrag hat Tipp- und verwendet die oben mit dem Befehl svn)

+0

Blogeintrag war hilfreich, trotz der Tippfehler. –

2

Verwenden , wie in git show commit_sha_id:path/to/some/file.cs.

5

git show ist der Befehl, den Sie suchen. Aus der Dokumentation:

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. 
+0

Das scheint nicht zu funktionieren: Ausführen von "git show next ~ 1: README" erzeugt fatal: mehrdeutiges Argument 'next ~ 1: README': unbekannte Revision oder Pfad nicht im Arbeitsbaum. Verwenden Sie '-', um Pfade von Revisionen zu trennen –

+1

Haben Sie eine Verzweigung namens 'next'? Wenn Sie den aktuellen Zweig möchten, verwenden Sie stattdessen 'HEAD'. –

2

schrieb ich ein git cat Shell-Skript, das up on github

+1

Der Code dafür war hilfreich, obwohl ich ein eigenständiges Python-Skript wollte und nicht alle Funktionen von git cat brauchte. Vielen Dank. –

9

es ist "git cat-Datei", die Sie wie folgt ausführen können:

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

Hier können Sie "v1.0" durch die Verzweigung ersetzen, die gewünschte SHA markieren oder committieren und dann "path/to/file" mit dem relativen Pfad im Repository. Sie können auch "-s" übergeben, um die Größe des Inhalts anzuzeigen, wenn Sie möchten.

könnte näher an den "cat" -Befehlen sein, an die Sie gewöhnt sind, obwohl die zuvor erwähnte "show" sehr ähnlich ist.

3

Auch mit Zweig Namen arbeiten (wie HEAD im 1. p):

git show $branch:$filename 
0

Keine der git show Vorschläge wirklich befriedigen, weil (versuchen Sie, wie ich könnte), kann ich nicht einen Weg finden, nicht die bekommen Metadaten kommen von der Spitze der Ausgabe. Der Geist von Katze (1) ist nur um den Inhalt zu zeigen. Dies (unten) nimmt einen Dateinamen und eine optionale Nummer. Die Nummer gibt an, wie oft Sie zurückgehen möchten. (Commits, die diese Datei geändert haben. Commits, die die Zieldatei nicht ändern, werden nicht gezählt.)

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

zeigt den Inhalt des filename.txt ab spätestens vor dem von filename.txt und den Inhalt von 3 Commits begehen.

#!/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

Für die bash mit dem folgenden ist eine nützliche Funktion:

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

es Setzen Sie in Ihrem .bashrc-Datei (Sie einen beliebigen Namen ein anderer als gcat verwenden können

Beispiel zur Nutzung.:

> gcat 
Usage: gcat [rev] file 

oder

> gcat subdirectory/file.ext 

oder

> gcat rev subdirectory/file.ext