Ho due repository. In uno, apporto le modifiche al file ./hello.test
. Applico le modifiche e creo una patch da tale commit con git format-patch -1 HEAD
. Ora, ho un secondo repository che contiene un file che ha lo stesso contenuto di hello.test ma è collocato in una directory diversa con un nome diverso: ./blue/red/hi.test
. Come faccio ad applicare la patch summenzionata al file hi.test
? Ho provato con lo git am --directory='blue/red' < patch_file
ma questo ovviamente si lamenta che i file non hanno lo stesso nome (che pensavo che a Git non interessasse?). So che probabilmente potrei modificare il diff da applicare a quel file specifico, ma sto cercando una soluzione di comando.Come applicare una patch Git a un file con un nome e un percorso diverso?
risposta
È possibile creare la patch utilizzando git diff
e quindi applicarla utilizzando l'utilità patch
, che consente di specificare il file a cui si desidera applicare la differenza.
Ad esempio:
cd first-repo
git diff HEAD^ -- hello.test > ~/patch_file
cd ../second-repo
patch -p1 blue/red/hi.test ~/patch_file
Ah, bello, non ci pensavo. Tuttavia, esiste un modo per farlo con i comandi Git in modo che i dati di commit (data e ora, autore commit, messaggio di commit) siano mantenuti gli stessi? – mart1n
È possibile che ci sia qualcosa che puoi fare con 'am' o' apply', ma non riesco a trovarlo. Se ti ritrovi a duplicare molto le modifiche, potrebbe esserci una soluzione migliore utilizzando i sottomoduli o qualunque altra lingua prescelta fornisca per condividere il codice (ad esempio in Ruby potresti estrarre il codice duplicato come una gemma). – georgebrock
Questo è in realtà correlato alla documentazione (i file di origine sono XML). I sottomoduli non sono davvero un'opzione, dato che dovrei fare un caso forte per loro nella nostra infrastruttura esistente. – mart1n
Rispondendo alla mia domanda con uno script che fa proprio questo: https://github.com/mprpic/apply-patch-to-file
Invece di modificare il file di patch manualmente, richiede all'utente per il file di destinazione, modifica il patch e lo applica al repository al momento.
Esiste una soluzione semplice che non prevede la modifica manuale delle patch né uno script esterno.
Nel primo repository (questo può anche esportare un intervallo di commit, utilizzare -1
se si desidera selezionare solo un commit):
git format-patch --relative <committish> --stdout > ~/patch
Nel secondo repository:
git am --directory blue/red/ ~/patch
Invece di utilizzare --relative
in git format-patch
, un'altra soluzione è utilizzare l'opzione -p<n>
in git am
per rimuovere le directory n
dal percorso delle patch, come indicato in un answer to a similar question.
È inoltre possibile eseguire git format-patch --relative <committish>
senza il --stdout
e genera un set di file .patch
. Questi file possono quindi essere inviati direttamente a git am
con git am --directory blue/red/ path/to/*.patch
.
Questo si basa ancora sul fatto che i nomi dei file sono gli stessi, giusto? – mart1n
salvato il mio giorno :) – tuxinaut
Si noti che l'opzione '--directory' sembra richiedere di specificare il percorso completo della directory relativo alla root del repository; qualcosa come '--directory =. /' mentre chdir'd in una sottodirectory nel repository non funzionerà. – Reid
Correlato a: https://stackoverflow.com/q/3367254/1959808 –