2011-01-06 10 views
123

Sto facendo qualcosa di molto semplice sbagliato. Sto cercando di preparare un file di patch normale, in modo da poter riapplicare alcune modifiche:È possibile ottenere un output compatibile con patch da git-diff?

$ git diff > before 
$ git diff something_here > save.patch 
$ git checkout . 
$ patch < save.patch 
$ git diff > after 
$ diff before after 
$ 

Con something_herevuoto quasi funziona, ma i nomi dei file non sono giuste. Penso di essere solo che mi manca qualche opzione.

Nella vita reale, ho intenzione di fare un'unione dopo il checkout, quindi la patch potrebbe fallire lì, ma si vede quello che sto ottenendo.

Modifica La mia colpa è qui per aver fatto la domanda sbagliata. La vera domanda è, voglio salvare le mie modifiche, fare una fusione, quindi riapplicare le modifiche, se possibile? L'ho chiesto nel modo sbagliato perché io sono utilizzato per utilizzare la patch per risolvere questo tipo di problemi e git diff sembrava che fosse quello che voleva che io facessi.

Charles Bailey's commento ha avuto la risposta giusta. Per me, git-apply è la cosa giusta da fare (git-stash sembra più pesante di quanto io abbia bisogno e la ridefinizione e il bundle è decisamente al di fuori del mio attuale livello di abilità.) Accetterò la risposta che Charles ha dato (perché tu non posso accettare un commento). Grazie per tutti i suggerimenti.

Modifica, 6 anni dopo Come chiunque abbia familiarità con il soggetto sa, ho sopravvalutato la difficoltà di git stash. Praticamente tutti i giorni o giù di lì, ho userà la seguente sequenza:

$ git stash 
$ git merge 
$ git stash pop 
+7

C'è qualche ragione che specificamente vuole utilizzare 'patch' piuttosto che' git apply'? –

+2

E anche allora, hai davvero bisogno di patch piuttosto che qualcosa come 'git stash' o altri strumenti git? –

+2

Post-edit, penso che 'git stash' è la soluzione più semplice per quello che stai cercando di fare, ma ci sono molti approcci che funzionano. –

risposta

104

Se si desidera utilizzare delle patch è necessario rimuovere le a/b/ prefissi che git utilizza per impostazione predefinita. È possibile farlo con l'opzione --no-prefix (si può anche fare questo con l'opzione di patch di -p):

git diff --no-prefix [<other git-diff arguments>] 

Di solito, però, è più facile da usare dritto git diff e quindi utilizzare l'uscita per alimentare a git apply.

La maggior parte delle volte cerco di evitare l'uso di patch testuali. Di solito uno o più commit temporanei combinati con rebase, git stash e bundle sono più facili da gestire.

Per il tuo caso di utilizzo, penso che sia stash più appropriato.

# save uncommitted changes 
git stash 

# do a merge or some other operation 
git merge some-branch 

# re-apply changes, removing stash if successful 
# (you may be asked to resolve conflicts). 
git stash pop 
+3

'git diff --no-prefisso master> diff.patch' e poi' git checkout master' 'patch -p0 Natim

+0

@Natim Per la massima sicurezza, mi raccomando di usare' patch --dry-run

+1

@ ᴠɪɴᴄᴇɴᴛ quale sarebbe il vantaggio di farlo? Dato che stiamo usando git, è improbabile che perderanno qualcosa, vero? – Natim

15

Le differenze di git hanno un segmento di percorso aggiuntivo anteposto ai percorsi dei file.È possibile togliere la voce nel percorso specificando -p1 con la patch, in questo modo:

patch -p1 < save.patch 
175

Basta usare -p1: dovrete utilizzare -p0 nel caso --no-prefix in ogni caso, in modo da poter lasciare il --no-prefix e utilizzare -p1:

$ git diff > save.patch 
$ patch -p1 < save.patch 

$ git diff --no-prefix > save.patch 
$ patch -p0 < save.patch 
+0

Se ti stai chiedendo perché, [the man docs] (http://www.gnu.org/software/diffutils/manual/diffutils.html#patch-Directories) lo riassume bene - [fonte] (http://unix.stackexchange.com/a/26502/17836). – tutuDajuju

7

Un trucco utile per evitare di creare file di patch temporanei:

git diff | patch -p1 -d [DST-dir]

+0

Esattamente quello che volevo. Funziona perfettamente anche con le casse! 'git stash show -p stash @ {3} | patch -p1 -d [dst-dir] ' – dtmland

7
  1. risparmio il diff della directory corrente (inclusi i file non impegnati) contro l'attuale capo.
  2. Quindi è possibile trasportare il file save.patch ovunque (compresi i file binari).
  3. Sul computer di destinazione, applicare la patch utilizzando git apply <file>

Nota: il diff è attualmente in scena i file troppo.

$ git diff --binary --staged HEAD > save.patch 
$ git reset --hard 
$ <transport it> 
$ git apply save.patch 
+0

Hahaha. È divertente. Ho fatto questa domanda quasi quattro anni fa e il modo in cui lo sto facendo si è evoluto, ma se mi avessi chiesto ieri come farlo, avrei dato la tua risposta e ho detto che avevo ottenuto da una risposta a questa domanda. (In realtà probabilmente userei un semplice 'git diff> save.patch' e' git checkout .' invece di un reset, ma si ... – Malvolio

+0

Oh non ho notato i suoi 4 anni: P. Btw, il reset è solo per dimostrare che funziona ..Inoltre non vedo nessuno che usi 'git apply 'o che faccia il diff rilevante al tuo stato e il puntatore all'ultima commit disponibile. Fare semplicemente 'git diff' non ha fatto nulla –

+0

Sì, ora mi chiedo come ho scoperto' git apply'. La cosa con 'git diff' è (penso) dall'uso di' git reset' - le relazioni tra il repository, l'indice e l'area di lavoro sono il problema. – Malvolio

Problemi correlati