@Mark Longair l'ha inchiodato nella sua risposta qui , ma mi piacerebbe aggiungere ulteriori approfondimenti.
Correlato e rispondere alla domanda su come suddividere una grande richiesta pull (PR), specialmente quando schiacciare i tuoi commit è impraticabile a causa di una o più fusioni di master nel tuo feature_branch
La mia situazione:
ho fatto un grande feature_branch
con 30 commit e ho aperto una richiesta pull (PR) su GitHub per unirlo master
. La filiale ha master
cambiato una tonnellata sotto di me e ha ricevuto 200 impegni che il mio feature_branch
non aveva. Per risolvere i conflitti che ho fatto git checkout feature_branch
e git merge master
per fondere master
i cambiamenti nel mio feature_branch
. Ho scelto merge
piuttosto che l' rebase
ultimo master, quindi avrei dovuto risolvere i conflitti solo una volta invece che potenzialmente 30 volte (una volta per ciascuno dei miei commit). Non volevo prima schiacciare i miei 30 commit in 1 e poi tornare all'ultimomaster
perché ciò potrebbe cancellare la cronologia dei commenti delle recensioni di GitHub nel PR. Quindi, ho unito master nel mio ramo delle funzionalità e risolto i conflitti 1 volta. Tutto andava bene. Il mio PR, tuttavia, era troppo grande per essere esaminato dai miei colleghi. Ho dovuto dividerlo. Sono andato a schiacciare i miei 30 commit e OH NO! DOVE SONO LORO? SONO TUTTI INTERMINGATI CON master
I 200 recenti impegni ora perché mi sono unito master
al mio feature_branch
! COSA FACCIO?
git cherry
utilizzo nel caso in cui si desideri provare a eseguire git cherry-pick
singoli commit:
git cherry
in soccorso (una specie di)!
Per vedere tutti i commit che sono dentro feature_branch
ma NON in master
posso fare:
git checkout feature_branch
git cherry master
OPPURE, posso verificare i commit da QUALSIASI filiale senza assicurarmi di essere il feature_branch
primo a farlo git cherry [upstream_branch] [feature_branch]
, in questo modo. Ancora una volta, questo controlla per vedere quali commit SONO in, feature_branch
ma NON in upstream_branch
( master
in questo caso):
git cherry master feature_branch
L'aggiunta -v
mostra anche le righe dell'oggetto del messaggio di commit:
git cherry -v master
Piping su "conteggio parole" "-lines" ( wc -l
) conta quanti commit ci sono:
git cherry master | wc -l
Puoi confrontare questo conteggio con il numero di commit mostrato nel tuo PR GithHub per sentirti meglio nel sapere git cherry
che funziona davvero. Puoi anche confrontare gli hash di Git uno per uno e vedere che corrispondono tra loro git cherry
e GitHub. Si noti che git cherry
non conterà alcun commit di unione in cui si sono fuse master
in feature_branch
, ma GitHub VOLONTÀ. Quindi se vedi una piccola discrepanza nel conteggio, cerca nella pagina di commit di GitHub PR la parola "unisci" e probabilmente vedrai che è il colpevole che non si presenta git cherry
. Esempio: un commit intitolato "Unisci ramo 'master' in feature_branch" verrà visualizzato nel PR GitHub ma non durante l'esecuzione git cherry master feature_branch
. Questo va bene e previsto.
Quindi, ora ho un modo per scoprire quali differenze potrei voler scegliere su una nuova diramazione delle funzioni per dividere questa differenza: posso usare git cherry master feature_branch
localmente o guardare i commit nel GitHub PR.
In che modo lo schiacciamento potrebbe aiutare - se solo potessimo schiacciare:
Un'alternativa, tuttavia, per dividere la mia grande differenza è quella di comprimere tutti e 30 i miei commit in uno, patch che su un nuovo ramo di funzionalità, soft reset del commit della patch, quindi utilizzare git gui
per aggiungere pezzi file per file, pezzo per pezzo, o linea per linea. Una volta ottenuta una funzionalità secondaria, posso eseguire il commit di ciò che ho aggiunto, quindi controllare un nuovo ramo, aggiungerne un altro, eseguire il commit, estrarre un nuovo ramo, ecc. . Il problema è che i miei 30 commit sono mescolati con gli altri 200 commit di altre persone a causa del mio git merge master
in my feature_branch
, quindi il rebasing è quindi poco pratico, dato che dovrei setacciare 230 commit per riordinare e schiacciare i miei 30 commit.
Come utilizzare un file patch come sostituto molto più semplice per lo schiacciamento:
Una soluzione è semplicemente ottenere un file di patch contenente un "equivalente squash" di tutti i miei 30 commit, patch su un nuovo fork di master
(un nuovo ramo di sub-feature), e lavorare da lì, come segue:
git checkout feature_branch
# ensure I have the latest changes from master merged into feature_branch
git merge master
# Obtain a patch file, which is the equivalent of a squash of my 30 commits into 1 commit:
git diff master..feature_branch > ~/mypatch.patch
git checkout master
# Create a new, sub-feature branch
git checkout -b feature_branch2
# Patch the 30 commit patch file onto it:
git apply ~/mypatch.patch
Ora ho la mia patch con 30 commit applicata localmente, ma non messa in scena e non impegnata.
Ora usa git gui
per aggiungere file, blocchi e / o linee e spezzare il tuo grande PR o "diff":
Nota che se non lo hai git gui
, puoi facilmente installarlo su Ubuntu con sudo apt install git-gui
.
Ora posso eseguire git gui
e iniziare ad aggiungere file, blocchi e / o linee (facendo clic con il pulsante destro del mouse sul programma Git GUI) e suddividere il ramo della funzione di commit 30 in rami secondari come descritto sopra, aggiungere ripetutamente, impegnare, quindi biforcare un nuovo ramo di funzionalità e ripetendo questo ciclo fino a quando tutte le modifiche non sono state aggiunte a un ramo di funzionalità secondaria e la mia funzione di 30 commit viene suddivisa correttamente in 3 o 4 funzioni secondarie. Ora posso aprire un PR separato per ognuna di queste funzioni secondarie e saranno più facili da esaminare per il mio team.
Riferimenti:
- Crea patch o file diff dal repository git e applicalo a un altro repository git diverso