2010-08-06 12 views
21

Git ha il molto utile archive comando che mi permette di fare una copia di un particolare commettere in un archivio .zip in questo modo:Zip ultime modifiche impegnati

git archive -o ../latest.zip some-commit

Questa conterrà l'intero albero di lavoro per questo commettere. Di solito ho solo bisogno dei file modificati da una versione precedente. Attualmente io uso questo per ottenere i file in un lampo:

git diff --name-only previous-commit latest-commit | zip ../changes.zip [email protected]

Ciò però comprimere i file dalla mia copia di lavoro, che possono avere modifiche non. C'è un modo per ottenere solo i file modificati come sono stati commessi direttamente in un zip?

risposta

38

git archive accetta i percorsi come argomenti. Tutto quello che dovrebbe essere necessario fare è:

git archive -o ../latest.zip some-commit $(git diff --name-only earlier-commit some-commit) 

o se si dispone di file con spazi (o altri caratteri speciali) in loro, usare xargs:

git diff --name-only earlier-commit some-commit | xargs -d'\n' git archive -o ../latest.zip some-commit 

Se non si dispone di xargs correttamente installati , si potrebbe cucinare un'alternativa:

#!/bin/bash 

IFS=$'\n' 
files=($(git diff --name-only earlier-commit some-commit)) 

git archive -o ../latest.zip some-commit "${files[@]}" 

Scritto come uno script di shell, ma dovrebbe funzionare come un one-liner troppo. In alternativa, modifica earlier-commit, some-commit e ../latest.zip a $1$2 e $3 e ti sei procurato uno script riutilizzabile.

+0

Bello! Funziona alla grande. –

+5

Attenzione che l'estrazione di un tale archivio non cancellerà alcun file. Ciò potrebbe causare problemi di diagnosi difficili in seguito. – jilles

+0

@jilles: molto vero. Questo è il motivo per cui le patch sono grandi. @ Marnix van Valen: Forse potresti semplicemente generare la patch e poi avvolgerla con uno script (potresti persino usare un heredoc per conservare tutto in un unico file) - quindi sarebbe utilizzabile e, beh, corretto. – Cascabel

-1

perché non creare una patch git che è possibile applicare all'altra base di codice?

$ git format-patch HEAD^..HEAD 
+1

Non tutti sanno come lavorare con i file di patch, ho paura.Lo uso per fornire nuove versioni ai miei clienti. La decompressione di un archivio è qualcosa che anche i non sviluppatori possono fare. L'applicazione di una patch richiede abilità non acquisite da tutti i miei clienti (o addirittura da padroneggiare). –

4

Se la creazione di una patch non è un'opzione, poi come su qualcosa di simile:

git stash 
git checkout latest-commit 
git diff --name-only previous-commit | zip ../changes.zip [email protected] 
git checkout master 
git stash apply 

NOTA: Il git stash e git stash apply sono necessari solo se si dispone di lavoro le modifiche di copia che non sono stati commessi .

NOTA 2: git checkout latest-commit ti metterà su una testa staccata. Assicurati di git checkout master quando hai finito o potresti finire per avere problemi con i futuri commit.

+0

Speravo in una soluzione a comando singolo ... –

+0

@ Marnix van Valen Allora perché non trasformarlo in un semplice script (o file batch)? Il problema è che devi tradurre l'elenco dei nomi di file in versioni specifiche. L'unico altro modo in cui potrei pensare è usare 'git show latest-commit: file'. Tuttavia, non ero in grado di inventare un solo liner per farlo. Sembrerebbe qualcosa del genere: 'git diff --name-only previous-commit | xargs -I file git mostra latest-commit: file' ... ma ecco il problema. Questo stampa il file (senza il suo nome) in STDOUT. Come può essere tradotto nel file zip? –

2

Per implementare qualcosa di utile per risolvere una domanda del genere, ho implementato un semplice script bash. Lo script accetta un hash di revisione e crea un archivio tar.gz con tutti i file modificati, inclusa la gerarchia delle directory. Chiunque potrebbe usarlo o modificarlo, sarei felice se potesse aiutare qualcuno.

Basta eseguire lo script nella directory root del repository git e passare l'hash di revisione alla riga di comando argumens.

Link to the script on hithub

+0

L'esempio sembra simile a questo: #./do_delivery.sh -r a5ab48cdbb -n "vmeagt_delivery" ===> Nome file archivio: "vmeagt_delivery-20120430" ===> Revisioni interessate: "a5ab48cdbb -> HEAD" ===> Percorso di output: "/ Users/crible/Projects/ServerView_Agents/" ===> Git repository:"/Users/crible/Projects/ServerView_Agents/" ===> Creazione dell'archivio tar.gz ... ===> Fatto! –

+0

È solo la prima versione, che deve essere migliorata con forza :) –

1

ho comme una soluzione, una riga e abbastanza semplice:

zip archive.zip $(git diff-tree --no-commit-id --name-only -r latest-commit) 

si può anche usare qualsiasi altro metodo di archiviazione come tar con questo metodo.

Problemi correlati