2010-01-15 14 views
80

Quiero extraer una copia de la última versión de un archivo en un repositorio de git, y pasarla a un script para su procesamiento. Con svn o hg, solo uso el comando "cat":Equivalente en git de "hg cat" o "svn cat"

Imprime los archivos especificados como estaban en la revisión dada. Si no se proporciona ninguna revisión, se utiliza el padre del directorio de trabajo, o consejo si no se revisa ninguna revisión.

(eso es de la descripción de gato Hg en la documentación Hg)

¿Cuál es el comando equivalente a hacer esto con git?

+3

Mi solución final fue usar primero "git ls-files---full nombre " para obtener la ruta completa en relación con la parte superior del depósito, y luego "git show HEAD: " –

+1

posible duplicado de [¿Cómo recuperar un único archivo de una revisión específica en Git?] (http://stackoverflow.com/questions/610208/how-to-retrieve-a-single-file -from-specific-revision-in-git) – ks1322

+1

posible duplicado de [¿Hay un comando rápido de git para ver una versión anterior de un archivo?] (http://stackoverflow.com/questions/338436/is-there-a -quick-git-command-to-see-an-old-version-of-a-fil e) –

Respuesta

106
git show rev:path/to/file 

Dónde rev es la revisión.

Consulte http://git.or.cz/course/svn.html para una comparación de los comandos git y svn.

+1

Esto funciona para mí, ¡yay! (Usando HEAD como la revisión) Creo que necesito usar la ruta relativa a la parte superior del repositorio, lo cual es un poco molesto, pero viable. –

+1

Objeción menor, que debería ser git show rev: ./ ruta/a/archivo – pimlottc

+0

@Richard Boulton: esto es menos doloroso si se usa tab tab completition – ks1322

1

No parece haber un sustituto directo. This blog entry detalla cómo hacer el equivalente determinando el último commit, luego determina el hash para el archivo en ese commit, y luego lo elimina.

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

(la entrada de blog tiene errores tipográficos y utiliza lo anterior con el comando svn)

+0

Entrada de blog fue útil, a pesar de los errores tipográficos. –

2

Uso , como en git show commit_sha_id:path/to/some/file.cs.

5

git show es el comando que está buscando. A partir de la documentación:

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

Eso no parece funcionar: al ejecutar "git show next ~ 1: README" produce fatal: argumento ambiguo 'next ~ 1: README': revisión desconocida o ruta no en el árbol de trabajo. Use '-' para separar las rutas de las revisiones –

+1

¿Tiene una rama llamada 'siguiente'? Si desea la rama actual, use 'HEAD' en su lugar. –

2

escribí un script de shell cat git, que es up on github

+1

Ver el código fue útil, aunque quería un script python independiente, y no necesitaba todas las características de git cat. Gracias. –

9

hay "git gato-archivo" que se puede ejecutar la siguiente manera:

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

donde puede reemplazar 'v1.0' con la rama, etiquetar o confirmar SHA que desee y luego 'ruta/a/archivo' con la ruta relativa en el repositorio. También puede pasar '-s' para ver el tamaño del contenido si lo desea.

podría estar más cerca de los comandos 'cat' a los que está acostumbrado, aunque el 'show' mencionado anteriormente hará más o menos lo mismo.

3

también trabajan con los nombres de rama (como cabeza en la primera p):

git show $branch:$filename 
0

Ninguno de los git show sugerencias satisfacer verdaderamente porque (mucho que lo intentaba), no puedo encontrar una manera de no obtener el metadata cruft desde la parte superior de la salida. El espíritu de cat (1) es solo para mostrar los contenidos. Esto (abajo) toma un nombre de archivo y un número opcional. El número es cómo se compromete a volver. (Confirma que se modificó ese archivo. No se cuentan los errores que no cambian el archivo de destino).)

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

muestra el contenido de filename.txt al cierre del último cometer de filename.txt y los contenidos a partir de 3 confirmaciones antes de eso.

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

Para aquellos que utilizan fiesta de la siguiente es una función útil:

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

ponerlo en su archivo .bashrc (puede usar cualquier nombre que al igual que otros que gcat

Ejemplo de uso.:

> gcat 
Usage: gcat [rev] file 

o

> gcat subdirectory/file.ext 

o

> gcat rev subdirectory/file.ext 
Cuestiones relacionadas