Come selezionare solo le modifiche per un solo file, non per l'intero commit


Risposte:


137

Hai diverse opzioni in base a ciò che vuoi ottenere:

Se vuoi che il contenuto del file sia lo stesso del ramo di destinazione, puoi usare git checkout <branch> -- <filename>. Questo tuttavia non "selezionerà" le modifiche avvenute in un singolo commit, ma prenderà semplicemente lo stato risultante di detto file. Quindi, se hai aggiunto una riga in un commit, ma i commit precedenti sono cambiati di più e vuoi solo aggiungere quella riga senza quelle altre modifiche, allora un checkout non è quello che vuoi.

Altrimenti, se vuoi applicare la patch introdotta in un commit a un solo file, hai più opzioni. È possibile eseguire git cherry-pick -n, ovvero senza eseguire il commit, modificare il commit (ad esempio ripristinare tutti i file utilizzando git reset -- .e aggiungere solo il file che si desidera effettivamente modificare utilizzando git add <filename>). Oppure puoi creare il diff per il file e applicare il diff quindi:

git diff <branch>^..<branch> -- <filename> | git apply

22

Crea un patch filee applicalo.

git diff branchname -- filename > patchfile
git apply patchfile

MODIFICARE:

Dato che devi prendere le modifiche da un commit, crea la patch in questo modo:

git show sha1 -- filename > patchfile

1
git diff sha1(oppure git diff branch- è lo stesso se il ramo punta allo stesso hash) produrrà solo un diff della directory di lavoro corrente in relazione a quell'hash, ma non ciò che cambia un commit introdotto da solo.
colpisci il

Corretta. Ha modificato la risposta. Grazie.
Sailesh

1
-1 git checkoutcon un nome di file è il martello giusto per questo chiodo. Entrambe queste opzioni sono inutilmente complesse.
Rein Henrichs

7
Per questo caso particolare, sì. Ma in generale, se vuoi scegliere le modifiche da un commit fatto a un particolare file, allora checkoutnon funzionerà, poiché potrebbe coinvolgere altre modifiche precedenti indesiderate e potrebbe non contenere modifiche apportate nel ramo corrente.
Sailesh

11

Un'altra cosa utile da fare è ottenere la patch localmente e quindi utilizzare:

git checkout {<name_of_branch>, commit's SHA} <path to the file> 

Tuttavia, non è una scelta di ciliegie.


2
Attenzione: come dice @poke nella sua risposta, questo non copia le modifiche; copia l'intero stato del file. Quindi, se vuoi aggiungere le modifiche di un commit al file, controllando in questo modo finisci per sovrascrivere le modifiche più recenti che non vanno bene.
Alexander Bird

7

Git ha tutto pronto :)

Basta usare git checkout <sha> <path-to-file>


4
Non è una scelta eccezionale: controlla il file per intero. L'obiettivo è apportare una modifica particolare da un commit. Spesso sono la stessa cosa, ma a volte non lo sono.
AndrewF

6
git checkout the_branch_with_the_change the/path/to/the/file/you/want.extension

funziona se vuoi che un singolo file da un altro ramo venga copiato nel ramo di lavoro corrente


1
Fai attenzione, le modifiche apportate nel file che non sono nella versione dell'altro ramo andranno perse.
Patrick Schlüter

D'accordo con quello. questo è utile se ti serve solo una copia del file e vuoi modificarlo sul ramo corrente
Ismail Iqbal

1
Si può usare glob (percorso / *) e specificare più di un percorso / file
Todd

1

Questo è quello che stai cercando:

git checkout target-branch sha1 path/to/file

sha1 è facoltativo


11
no, "seleziona le modifiche nel commit" non è "seleziona l'intero file"
Abyx

1

Quello che tendo a fare è usare git ls-tree

basta fare:

git ls-tree -r <commit-id> |grep 'your filename'
# there will be output that shows a SHA1 of your file
git show ${SHA1 of your file} > 'your filename'

Questo stamperà tutti i nomi di file che corrispondono al tuo grep e fornirà le chiavi SHA1 dei file nel commit.

Git show può essere utilizzato anche su file al di fuori del tuo ramo. l'utilizzo >dalla shell per incanalare l'output in un file ti dà il risultato che stai cercando.


0

Puoi provare a farlo:

git show COMMIT_ID -- path/to/specific-file | git apply

Per esempio:

git show 3feaf20 -- app/views/home/index.html | git apply

-9
git reset HEAD~1

sposta i file nella fase di pre-commit

git stash

rimuove dalla memoria

Ora il tuo ramo è abbastanza pulito (ripristinato al commit precedente)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.