Come si impegna a squash in una patch con git format-patch?
-
03-07-2019 - |
Domanda
Ho otto commit su una filiale che mi piacerebbe inviare per e-mail ad alcune persone che non sono ancora illuminate. Finora, tutto ciò che faccio o mi dà 8 file di patch, o inizia a darmi file di patch per ogni commit nella storia del ramo, dall'inizio del tempo. Ho usato git rebase - interattivo per eliminare i commit, ma ora tutto ciò che provo mi dà miliardi di patch dall'inizio del tempo. Cosa sto sbagliando?
git format-patch master HEAD # yields zillions of patches, even though there's
# only one commit since master
Soluzione
Consiglierei di farlo su un ramo usa e getta come segue. Se i tuoi commit sono in "newline" e sei tornato al tuo " master " ramo già, questo dovrebbe fare il trucco:
[adam@mbp2600 example (master)]$ git checkout -b tmpsquash
Switched to a new branch "tmpsquash"
[adam@mbp2600 example (tmpsquash)]$ git merge --squash newlines
Updating 4d2de39..b6768b2
Fast forward
Squash commit -- not updating HEAD
test.txt | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
[adam@mbp2600 example (tmpsquash)]$ git commit -a -m "My squashed commits"
[tmpsquash]: created 75b0a89: "My squashed commits"
1 files changed, 2 insertions(+), 0 deletions(-)
[adam@mbp2600 example (tmpsquash)]$ git format-patch master
0001-My-squashed-commits.patch
Spero che questo aiuti!
Altri suggerimenti
Solo per aggiungere un'altra soluzione al piatto: Se lo usi invece:
git format-patch master --stdout > my_new_patch.diff
Quindi saranno ancora 8 patch ... ma saranno tutte in un singolo file di patch e si applicheranno come una con:
git am < my_new_patch.diff
Uso sempre git diff, quindi nel tuo esempio, qualcosa come
git diff master > patch.txt
Questo è un adattamento della risposta di Adam Alexander, nel caso in cui le tue modifiche siano nel ramo principale. In questo modo:
- Crea un nuovo ramo usa e getta "tmpsquash" dal punto che vogliamo (cerca il tasto SHA che esegue " git --log " o con gitg. Seleziona il commit che vuoi essere tmpsquash head, i commit che seguono dopo nel master saranno i commit schiacciati).
- Unisce le modifiche da master a tmpsquash.
- Commette le modifiche schiacciate a tmpsquash.
- Crea la patch con i commit schiacciati.
- Torna al ramo principale
laura@rune:~/example (master)$ git branch tmpsquash ba3c498878054e25afc5e22e207d62eb40ff1f38
laura@rune:~/example (master)$ git checkout tmpsquash
Switched to branch 'tmpsquash'
laura@rune:~/example (tmpsquash)$ git merge --squash master
Updating ba3c498..40386b8
Fast-forward
Squash commit -- not updating HEAD
[snip, changed files]
11 files changed, 212 insertions(+), 59 deletions(-)
laura@rune:~/example (tmpsquash)$ git commit -a -m "My squashed commits"
[test2 6127e5c] My squashed commits
11 files changed, 212 insertions(+), 59 deletions(-)
laura@rune:~/example (tmpsquash)$ git format-patch master
0001-My-squashed-commits.patch
laura@rune:~/example (tmpsquash)$ git checkout master
Switched to branch 'master'
laura@rune:~/example (master)$
Come già sai, un git format-patch -8 HEAD
ti darà otto patch.
Se vuoi che i tuoi 8 commit vengano visualizzati come uno e non ti dispiaccia riscrivere la storia della tua filiale ( o-o-X-A-B-C-D-E-F-G-H
), potresti:
git rebase -i
// squash A, B, C, D, E ,F, G into H
oppure, e sarebbe una soluzione migliore, riproduci tutti i tuoi 8 commit da X
(il commit prima dei tuoi 8 commit) su una nuova filiale
git branch delivery X
git checkout delivery
git merge --squash master
git format-patch HEAD
In questo modo, hai un solo commit sulla " consegna " branch e rappresenta tutti gli ultimi 8 commit
Formato-patch tra due tag:
git checkout <source-tag>
git checkout -b <tmpsquash>
git merge --squash <target-tag>
git commit -a -m "<message>"
git format-patch <source-tag>
Il modo più semplice è usare git diff
e aggiungere git log
se vuoi il messaggio di commit combinato che il metodo squash produrrebbe. Ad esempio, per creare la patch tra commit abcd
e 1234
:
git diff abcd..1234 > patch.diff
git log abcd..1234 > patchmsg.txt
Quindi quando si applica la patch:
git apply patch.diff
git add -A
git reset patch.diff patchmsg.txt
git commit -F patchmsg.txt
Non dimenticare l'argomento --binary
su git diff
quando si tratta di file non di testo, ad es. immagini o video.
Basato sulla risposta di Adam Alexander:
git checkout newlines
## must be rebased to master
git checkout -b temporary
# squash the commits
git rebase -i master
git format-patch master