Supponiamo di aver apportato modifiche non confermate nella mia directory di lavoro. Come posso fare una patch da quelli senza dover creare un commit?
Supponiamo di aver apportato modifiche non confermate nella mia directory di lavoro. Come posso fare una patch da quelli senza dover creare un commit?
Risposte:
git diff
per modifiche non messe in scena. git diff --cached
per modifiche graduali.
git format-patch
include anche diff binari e alcune meta info. In realtà sarebbe la soluzione migliore per la creazione di una patch, ma questo funziona solo per fonti / modifiche registrate, giusto?
git diff --relative
Se non hai ancora eseguito il commit delle modifiche, allora:
git diff > mypatch.patch
Ma a volte capita che parte delle cose che stai facendo siano nuovi file che non sono tracciati e non saranno nel tuo git diff
output. Quindi, un modo per fare una patch è mettere in scena tutto per un nuovo commit ( git add
ogni file o solo git add .
) ma non eseguire il commit, quindi:
git diff --cached > mypatch.patch
Aggiungi l'opzione 'binary' se vuoi aggiungere file binari alla patch (es. File mp3):
git diff --cached --binary > mypatch.patch
È possibile applicare successivamente la patch:
git apply mypatch.patch
Nota: è anche possibile utilizzare --staged
come sinonimo di --cached
.
git diff --no-color
. Altrimenti, sembra un problema di codifica.
git diff
e git apply
funzionerà per i file di testo, ma non funzionerà per i file binari.
Puoi facilmente creare una patch binaria completa, ma dovrai creare un commit temporaneo. Una volta effettuati i tuoi commit temporanei, puoi creare la patch con:
git format-patch <options...>
Dopo aver creato la patch, esegui questo comando:
git reset --mixed <SHA of commit *before* your working-changes commit(s)>
Questo ripristinerà i tuoi commit temporanei. Il risultato finale lascia la tua copia di lavoro (intenzionalmente) sporca con le stesse modifiche che avevi originariamente.
Sul lato ricevente, è possibile utilizzare lo stesso trucco per applicare le modifiche alla copia di lavoro, senza avere la cronologia di commit. Basta applicare le patch e git reset --mixed <SHA of commit *before* the patches>
.
Tieni presente che potresti dover essere ben sincronizzato affinché l'intera opzione funzioni. Ho visto alcuni errori nell'applicazione delle patch quando la persona che le stava realizzando non aveva annullato tutti i cambiamenti che avevo. Probabilmente ci sono modi per farlo funzionare, ma non ho studiato molto.
Ecco come creare le stesse patch in Tortoise Git (non che consiglio di usare questo strumento):
Tortoise Git
->Create Patch Serial
Since
: FETCH_HEAD
funzionerà se sei ben sincronizzato)Tortise Git
->Show Log
reset "<branch>" to this...
Mixed
opzioneE come applicarli:
Tortoise Git
->Apply Patch Serial
Tortise Git
->Show Log
reset "<branch>" to this...
Mixed
opzionePer creare una patch con entrambi i file modificati e nuovi (messi in scena) è possibile eseguire:
git diff HEAD > file_name.patch
git diff --cached > mypatch.patch
non funziona.
file_name.patch
essere utilizzata dal patch
comando? Sono compatibili tra loro?
Mi piace:
git format-patch HEAD~<N>
dove <N>
è il numero degli ultimi commit da salvare come patch.
I dettagli su come usare il comando sono nel DOC
UPD
Qui puoi trovare come applicarli allora.
UPD Per coloro che non hanno avuto l'idea di format-patch
Aggiungi alias:
git config --global alias.make-patch '!bash -c "cd ${GIT_PREFIX};git add .;git commit -m ''uncommited''; git format-patch HEAD~1; git reset HEAD~1"'
Quindi, in qualsiasi directory del repository del progetto, eseguire:
git make-patch
Questo comando verrà creato 0001-uncommited.patch
nella directory corrente. Patch conterrà tutte le modifiche e i file non tracciati visibili al comando successivo:
git status .
Potremmo anche specificare i file, per includere solo i file con relative modifiche, in particolare quando si estendono su più directory ex
git diff ~/path1/file1.ext ~/path2/file2.ext...fileN.ext > ~/whatever_path/whatever_name.patch
Ho trovato che questo non era specificato nelle risposte o nei commenti, che sono tutti pertinenti e corretti, quindi ho scelto di aggiungerlo. Esplicito è meglio che implicito!