Usando Git, mostra tutti i commit che si trovano in un ramo, ma non gli altri


465

Ho un vecchio ramo, che vorrei eliminare. Tuttavia, prima di farlo, voglio verificare che tutti gli commit effettuati in questo ramo siano stati uniti in qualche altro ramo. Quindi, mi piacerebbe vedere tutti i commit fatti nel mio ramo corrente che non sono stati applicati a nessun altro ramo [o, se ciò non è possibile senza alcuni script, come si vedono tutti i commit in un ramo che non sono stati applicati in un altro ramo dato?].


Per elencare i commit mancanti tra due rami puoi usare compare-branches.py bitbucket.org/aakef/compare-git-branches
Bernd Schubert

Risposte:


321

Probabilmente vuoi solo

git branch --contains branch-to-delete

Questo elencherà tutti i rami che contengono i commit da "branch-to-delete". Se segnala più di un semplice "ramo da eliminare", il ramo è stato unito.

Le tue alternative sono davvero solo cose di sintassi di rev-list. ad esempio git log one-branch..another-branchmostra tutto ciò che one-branchdeve avere tutto ciò che another-branchha.

Potresti anche essere interessato a git show-branchcome vedere dove si trova.



1
La linea 'Se si riporta qualcosa, il ramo si è fusa' può essere male interpretato: se git branch --contains some-branchsolo i rendimenti some-branch, allora fa ritorno qualcosa, ma è non è stata fusa.
Confusione

5
Nota che git log foo..barmostrerà i commit tra l'ultimo e il più recente foo bar, ma non altri commit mancanti da più indietro nel tempo. Per vedere tutto in barra ma non in foo, dovresti usare la soluzione di @ jimmyorr.
Paul A Jungwirth,

557

Per vedere un elenco di quali commit sono su un ramo ma non su un altro, usa git log:

git log --no-merges oldbranch ^newbranch

... cioè, mostra i log di commit per tutti i commit su oldbranch che non sono su newbranch. È possibile elencare più rami da includere ed escludere, ad es

git log  --no-merges oldbranch1 oldbranch2 ^newbranch1 ^newbranch2

Nota: su Windows ^è una chiave di escape, quindi deve essere salvata con un'altra ^:

git log --no-merges oldbranch ^^newbranch

2
L'ho trovato alla ricerca di git compare commit di due rami.
Utente

25
Questo e 'esattamente quello che stavo cercando. Ma l'uso ^come prefisso qui mi ha confuso. In questo contesto significa escludere quel ramo. Usare ^come suffisso sarebbe un riferimento relativo al commit parent di quel ramo.
Joe Flynn,

4
grazie molto utile. Sono curioso, perché è necessaria la bandiera --no-merges? Sicuramente uno vuole vedere anche quei commit?
Max MacLeod

2
Ti piacerebbe usare Gitk con questo? Usa semplicemente gitk oldbranch ^newbranch --no-merges(Testato con git 1.8.1.1). Nota a margine, per me ^significa inclusione HEAD della filiale inclusiva newbranch.
Matt,

2
@NazariiGudzovatyi - sì, c'è: "-cherry-pick". C'è un ENORME numero di opzioni per accedere alla pagina
romeara

91

Per mostrare gli commit in oldbranch ma non in newbranch:

git log newbranch..oldbranch

Per mostrare il diff con questi commit (nota che ci sono tre punti):

git diff newbranch...oldbranch

Ecco il documento con un'illustrazione del diagramma https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#Commit-Ranges


Vedi il commento di Paul A Jungwirth sopra. Sembra che questo ci mancherà per alcuni vecchi commit?
Miserabile variabile

2
Non sono sicuro di cosa significhino i vecchi impegni. I punti doppi in sostanza chiedono a Git di risolvere una serie di commit raggiungibili da un commit ma non raggiungibili da un altro. Ecco il documento con un'illustrazione digram git-scm.com/book/en/v2/…
Xuan

1
e se siamo su uno newbrancho oldbranch, possiamo fare git log ..oldbrancho git log newbranch..rispettivamente
YakovL

La soluzione di Jimmyorr non ha funzionato per me, ma questa ha funzionato grazie ai due punti ..tra i nomi degli arbitri. Ho anche usato l' --cherry-pickopzione per nascondere i commit che sono presenti su entrambi i rami ma hanno un hash diverso perché sono stati scelti da un ramo all'altro.
flawyte

58

Per chi cerca ancora una risposta semplice, dai un'occhiata a git cherry . Confronta le differenze effettive anziché gli hash di commit. Ciò significa che accetta commesse che sono state raccolte o ridisegnate in ciliegio.

Per prima cosa controlla il ramo che desideri eliminare:

git checkout [branch-to-delete]

quindi usa git cherry per confrontarlo con il tuo ramo di sviluppo principale:

git cherry -v master

Esempio di output:

+ 8a14709d08c99c36e907e47f9c4dacebeff46ecb Commit message
+ b30ccc3fb38d3d64c5fef079a761c7e0a5c7da81 Another commit message
- 85867e38712de930864c5edb7856342e1358b2a0 Yet another message

Nota: il -vflag deve includere il messaggio di commit insieme all'hash SHA.

Le linee con il '+' davanti sono nel ramo da cancellare, ma non nel ramo principale. Quelli con un "-" davanti hanno un commit equivalente in master.

Per JUST i commit che non sono in master, combina cherry pick con grep:

git cherry -v master | grep "^\+"

Esempio di output:

+ 8a14709d08c99c36e907e47f9c4dacebeff46ecb Commit message
+ b30ccc3fb38d3d64c5fef079a761c7e0a5c7da81 Another commit message

Ho provato questo, ma riporta ancora che ci sono molti commit nel fb (ramo delle caratteristiche) che non sono nel mb (ramo principale). Tuttavia, se sono nel fb e faccio un git diff mb, non vedo differenze. Ho usato rebase e schiacciato tutto. Sono quasi certo che sia per questo, ma voglio solo esserne certo. Se questo è il caso, allora eviterò di schiacciarlo se possibile; Sono nel "campo informativo senza smarrimento". Mi chiedo se sarebbe possibile aggiungere una modalità di visualizzazione del registro in grado di visualizzare le fusioni come se fossero rebase per mantenere pulita la cronologia e tuttavia non perdere informazioni.
Outis Von Nemo,

1
Non sono sicuro del tuo esatto scenario qui, ma se hai combinato più commit in uno e lo stai confrontando con un altro ramo in cui i commit sono separati, questo sicuramente non funzionerà. In tal caso, potresti semplicemente voler utilizzare l' diffutilità unix per confrontare i vari file. Oppure, potresti creare un ramo temporaneo e comprimere tutti i commit in quello simile a quello che hai fatto con il ramo originale, e quindi utilizzare questo, che penso funzionerebbe.
Tim S

50

Mentre alcune delle risposte pubblicate qui ti aiuteranno a trovare quello che cerchi, il seguente sottocomando di git branch è una soluzione più adatta per il tuo compito.

- unito viene utilizzato per trovare tutti i rami che possono essere eliminati in modo sicuro, poiché tali rami sono completamente contenuti da HEAD.

Mentre in masteruno è possibile eseguire il comando per enumerare i rami, è possibile rimuovere in modo sicuro, in questo modo:

git branch --merged
  develop
  fpg_download_links
* master
  master_merge_static

# Delete local and remote tracking branches you don't want
git branch -d fpg_download_links
git push origin :fpg_download_links
git branch -d master_merge_static
git push origin :master_merge_static

# There is also a flag to specify remote branches in the output
git branch --remotes --merged

16

La risposta di Jimmyorr non funziona su Windows. aiuta a usare --notinvece di ^così:

git log oldbranch --not newbranch --no-merges

4
È corretto, +1. Nota però che ^è supportato su Windows, ma deve essere sfuggito, che, in Windows, è (un altro) ^: git log oldbranch ^^newbranch --no-merges.
VonC

3
Per essere precisi, funziona in Windows nella console Powershell, ma richiede "^" extra in CMD.
Rod

7

Se è un (singolo) ramo che è necessario controllare, ad esempio se si desidera che quel ramo 'B' sia completamente unito al ramo 'A', è possibile semplicemente fare quanto segue:

$ git checkout A
$ git branch -d B

git branch -d <branchname> ha la sicurezza che "La filiale deve essere completamente unita in HEAD".

Attenzione : questo effettivamente cancella il ramo B se viene unito in A.


3

Puoi usare questo semplice script per vedere i commit che non sono stati uniti

#!/bin/bash
# Show commits that exists only on branch and not in current
# Usage:
#   git branch-notmerge <branchname>
#
# Setup git alias
#   git config alias.branch-notmerge [path/to/this/script]
grep -Fvf <(git log --pretty=format:'%H - %s') <(git log $1 --pretty=format:'%H - %s')

Puoi anche usare lo strumento git-wtf che mostrerà lo stato dei rami


0

Basta usare git cherryper selezionare tutti i commit nella filiale, newFeature42ad esempio:

git cherry -v master newFeature42


-5

Inizia a creare una richiesta pull tramite il servizio di hosting git che stai utilizzando. Se il ramo è stato completamente unito al ramo di base, non sarà possibile creare il nuovo PR.

Non è necessario effettuare effettivamente la richiesta pull, basta usare il primo passo in cui si scelgono i rami.

Ad esempio, su GitHub:

Non c'è niente da confrontare

Impossibile creare un PR per le filiali che sono state unite.

Questo non usa git dalla riga di comando, ma trovo spesso utile usare gli altri strumenti a tua disposizione con un modello mentale chiaro piuttosto che tentare di ricordare un altro comando arcano git.

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.