Come vedere quali commit in un ramo non sono nell'altro?


180

Ho due rami devele next. In sviluppo ho una quantità più o meno grande di commit. Alcuni dei commit sono raccolti in ciliegio next. Inoltre ho aggiunto alcuni commit al prossimo che vengono uniti devel.

Ora vorrei vedere cosa manca next, in modo da poter testare i cambiamenti in dettaglio prima di portarli a next. La mia domanda è ora, come posso vedere in quali commit ci sono develma non in quelli successivi?



il tuo titolo è un po 'fuorviante, in quanto ciò che vuoi confrontare è la punta di entrambi i rami. e sono venuto qui alla ricerca di una soluzione due confronti specifici (diversi) di due rami
thebugfinder,

Risposte:


210

Il comando poco usato git cherryti mostra i commit che non sono ancora stati scelti con cura. La documentazione per git cherryè qui , ma, in breve, dovresti solo essere in grado di fare:

git checkout devel
git cherry next

... e vedi un output un po 'come questo:

+ 492508acab7b454eee8b805f8ba906056eede0ff
- 5ceb5a9077ddb9e78b1e8f24bfc70e674c627949
+ b4459544c000f4d51d1ec23f279d9cdb19c1d32b
+ b6ce3b78e938644a293b2dd2a15b2fecb1b54cd9

I commit con cui inizieranno +saranno quelli in cui non hai ancora scelto Cherry next. In questo caso, fino ad ora avevo selezionato solo un commit. È possibile che si desideri aggiungere il -vparametro al git cherrycomando, in modo che emetta anche la riga dell'oggetto di ciascun commit.


Fantastico, questo è quello di cui avevo bisogno. Sarebbe anche bello avere una breve descrizione dei test, ma posso scriverlo.
Sascha Effert,

29
Non è necessario git checkout devel, puoi semplicemente farlo git cherry next devel.
Robin Winslow,

21
"Potrebbe voler aggiungere il -v" ? Cherry senza a -vè come lssenza un -la. ; -J
Slipp D. Thompson,

1
E non sapresti un modo per arrivare cherrya contrassegnare o escludere commit equivalenti, vero? cherrysembra un comando idraulico, ma non sembra (sembra) offrire molte opzioni. Per quello che sono attualmente nel mezzo, git cherrymi dà falsi positivi, ma @ sehe's git log --cherry-pickesclude correttamente i commit precedentemente raccolti / riformulati.
Slipp D. Thompson,

La documentazione fornisce un esempio concreto: git-scm.com/docs/git-cherry#_concrete_example
ams

107

Inoltre, puoi usare

git log --left-right --graph --cherry-pick --oneline devel...next

per ottenere un buon elenco di diversi commit effettivi non condivisi tra le filiali.

La parola chiave è --cherry-pick

--cherry-pick

Omettere qualsiasi commit che introduce la stessa modifica di un altro commit sull'altro lato quando l'insieme di commit è limitato con una differenza simmetrica. Ad esempio, se hai due rami, A e B, un modo normale per elencare tutti i commit su un solo lato è con --left-right, come nell'esempio sopra nella descrizione di quell'opzione. Mostra comunque i commit che sono stati scelti dalla ciliegia dall'altro ramo (per esempio, "3a su b" può essere selezionata dalla ciliegia dal ramo A). Con questa opzione, tali coppie di commit sono escluse dall'output.

Aggiornamento Come menzionato in un commento, le versioni recenti di git hanno aggiunto --cherry-mark:

--cherry-mark

Come --cherry-pick (vedi sotto), ma contrassegna i commit equivalenti con = anziché ometterli, e quelli ineguagliabili con +.


1
Questo non ha funzionato per me. La mia versione di git non sa - una linea, quindi l'ho rimossa. Poi ho dovuto scambiare devel e successivo e ha funzionato. Molto bella!
Sascha Effert,

@SaschaEffert: non è stato necessario passare a sviluppo e successivo (notare TRE punti, non DUE). Detto questo, le cose potrebbero essere diverse se avessi usato una versione antica di git (?) Ma in quel caso avresti dovuto ottenere un errore rev-parse sui tre punti.
Visto il

2
Per divertimento, ho scoperto che la sintassi rev-parse "..." (differenza simmetrica) è stata aggiunta nel luglio 2006 e la documentazione è stata aggiornata nel giugno 2008 . La gioia dell'open source!
Visto il

1
'gls - first-parent --cherry-mark --left-only only ... next' dove gls è il mio alias log git con tutta la formattazione carina. cherry-mark mostra che sia la ciliegia selezionata che la ciliegia non selezionata si impegnano a svilupparsi, ma le contrassegnano diversamente.
angularsen,

1
aggiungere --no-fusioni forse meglio
MervynYang

51

Potresti provare a fare sottoinsiemi di log git:

git log --oneline devel ^next

4
Questa è la migliore soluzione secondo me (la risposta di @ sehe mostra anche in questo momento dei commit che non sono in via di sviluppo - nel contesto del PO non ce ne sono, ma nel mio ci sono - usare --left-onlysarebbe stato meglio). Tuttavia, questo può essere migliorato un po 'aggiungendo --no-mergesper omettere qualsiasi commit di unione (ad es. Se una funzionalità o un ramo di hotfix è stato unito (separatamente) in entrambi gli sviluppi e successivo). A rigor di termini, naturalmente, la risoluzione dei conflitti nelle fusioni può creare altre differenze, ma di solito non è così. L' --no-mergesopzione può essere utilmente applicata anche alle altre risposte.
Alex Dupuy,

27

Che ne dite di

git log next..devel

Il risultato è simile alla risposta di Byran (diverso ordine di commit) ma entrambe le nostre risposte produrranno commit diversi tra i rami, piuttosto mostrando semplicemente cosa c'è in un ramo e non nell'altro.


4
Puoi anche omettere il secondo ramo se sei attualmente su quel ramo. vale a diregit log next..
jmaxyz,

tra 'git log next..devel' è diverso da 'git log devel..next'
Eugene Kaurov,

1

Per ottenere l'elenco dei commit che non sono stati integrati nel ramo di rilascio (successivo) è possibile utilizzare:

git rev-list --reverse --pretty="TO_TEST %h (<%ae>) %s" --cherry-pick --right-only origin/release_branch...origin/development_branch | grep "^TO_TEST " > NotIntegratedYet.txt

Controlla git-rev-list per maggiori informazioni.


al comando di questa risposta mancano gli attuali rami in questione, vale a direnext...devel
Alex Dupuy,

@AlexDupuy Yah, è una risposta piuttosto stupida. Dal momento che non è anche la risposta più semplice e non spiega perché questo approccio sarebbe migliore, lo sto -1 .
Slipp D. Thompson,

-1

@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_branchcon 30 commit e ho aperto una richiesta pull (PR) su GitHub per unirlo master. La filiale ha mastercambiato una tonnellata sotto di me e ha ricevuto 200 impegni che il mio feature_branchnon aveva. Per risolvere i conflitti che ho fatto git checkout feature_branche git merge masterper fondere masteri cambiamenti nel mio feature_branch. Ho scelto mergepiuttosto che l' rebaseultimo 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'ultimomasterperché 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 masterI 200 recenti impegni ora perché mi sono unito masteral mio feature_branch! COSA FACCIO?

git cherryutilizzo nel caso in cui si desideri provare a eseguire git cherry-picksingoli commit:

git cherry in soccorso (una specie di)!

Per vedere tutti i commit che sono dentro feature_branchma NON in masterposso fare:

git checkout feature_branch
git cherry master

OPPURE, posso verificare i commit da QUALSIASI filiale senza assicurarmi di essere il feature_branchprimo a farlo git cherry [upstream_branch] [feature_branch], in questo modo. Ancora una volta, questo controlla per vedere quali commit SONO in, feature_branchma NON in upstream_branch( masterin questo caso):

git cherry master feature_branch

L'aggiunta -vmostra 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 cherryche funziona davvero. Puoi anche confrontare gli hash di Git uno per uno e vedere che corrispondono tra loro git cherrye GitHub. Si noti che git cherrynon conterà alcun commit di unione in cui si sono fuse masterin 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_branchlocalmente 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 guiper 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 masterin 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 guiper 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 guie 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:

  1. Crea patch o file diff dal repository git e applicalo a un altro repository git diverso

Ho dovuto fare riferimento a questa risposta oggi, ma non sono riuscito a trovarla rapidamente. Fortunatamente, aveva un downvote per aiutarmi a trovarlo più facilmente, quindi un semplice clic sull'icona della coppa dei premi in alto a destra dello schermo ha mostrato dove recentemente ho perso 2 punti, e facendo clic su quello mi ha riportato qui dove posso ora fai riferimento alla mia risposta qui! Spero di non ottenere più voti negativi, ma al downvoter, grazie per il servizio che mi ha aiutato accidentalmente!
Gabriel Staples il
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.