Come faccio a sapere se un ramo è già stato unito in master?


1140

Ho un repository git con più rami.

Come posso sapere quali rami sono già stati uniti nel ramo principale?

Risposte:


1793

git branch --merged masterelenca i rami uniti in master

git branch --mergedelenca i rami uniti in HEAD (ovvero la punta del ramo corrente)

git branch --no-merged elenca i rami che non sono stati uniti

Per impostazione predefinita, questo vale solo per le filiali locali. La -abandiera mostrerà sia i rami locali che remoti e la -rbandiera mostra solo i rami remoti.


2
Solo una nota a margine, quando ho provato a vedere se un ramo remoto era stato unito ho prima impostato un ramo di tracciamento locale, identificato lo stato con git branch --mergede quindi eliminato i rami locali e remoti.
Kenneth Kalmer,

83
Apparentemente, git branch -a --merged/no-mergedfunziona anche, senza creare un ramo di tracciamento locale nel processo.
fresskoma,

70
O solo git branch -r --merged/--no-mergedper trovare filiali remote.
Asfand Qazi,

5
Un modo per eliminare i rami non uniti che sono stati effettivamente uniti dopo la riformulazione?
Ashfame,

9
Si noti che --merged/--no-mergedaccetta un argomento di commit opzionale dopo di esso. Almeno nella mia versione di git (1.9.1), l'aggiunta del flag -ao -rdopo mi ha dato un errore fatale. Aggiungi il -ao -r prima --(no-)merged .
Jonathan Gawrych,

113

È possibile utilizzare il git merge-basecomando per trovare l'ultimo commit comune tra i due rami. Se quel commit è lo stesso della testa del tuo ramo, allora il ramo è stato completamente unito.

Nota che git branch -dfa già questo genere di cose perché rifiuterà di eliminare un ramo che non è già stato completamente unito.


3
La risposta di @ hari va più in dettaglio su come usarlo.
Muhd,

come possiamo farlo automaticamente / programmaticamente?
Alexander Mills,

1
"non è già stato completamente unito" ... completamente unito in quale ramo?
Alexander Mills,

@AlexanderMills: nel tuo ramo attuale.
Greg Hewgill,

2
@AlexanderMills: git branch -drifiuterà di eliminare un ramo che non è stato unito al ramo corrente. Non eliminare il ramo corrente .
Greg Hewgill,

27

Esiste anche una soluzione di interfaccia grafica. Basta digitare

gitk --all

Verrà visualizzata una nuova finestra dell'applicazione con una rappresentazione grafica dell'intero repository, in cui è molto facile capire se un ramo è già stato unito o meno


17
Che per essere chiari, richiede l'installazione di un'applicazione che non fa parte del gitclient. Su Ubuntu, apt-get install gitk.
Metame

Su macOS, se hai Homebrew installato, sarebbe brew install git-gui, per accedere gitkalla riga di comando.
programma247365

24

Sto usando la seguente funzione bash come: git-is-merged develop feature/new-feature

git-is-merged () {
  merge_destination_branch=$1
  merge_source_branch=$2

  merge_base=$(git merge-base $merge_destination_branch $merge_source_branch)
  merge_source_current_commit=$(git rev-parse $merge_source_branch)
  if [[ $merge_base = $merge_source_current_commit ]]
  then
    echo $merge_source_branch is merged into $merge_destination_branch
    return 0
  else
    echo $merge_source_branch is not merged into $merge_destination_branch
    return 1
  fi
}

3
questo in realtà non funziona. Se il ramo di origine è già stato unito al ramo di destinazione e quindi il ramo di destinazione riceve qualche altro commit, non funziona più ma non so perché
Alexander Mills


18

Usa git merge-base <commit> <commit>.

Questo comando trova i migliori antenati comuni tra due commit. E se l'antenato comune è identico all'ultimo commit di un "ramo", possiamo tranquillamente supporre che un "ramo" sia già stato unito al master.

Ecco i passaggi

  1. Trova l'ultimo hash di commit sul ramo principale
  2. Trova l'ultimo hash di commit su un "ramo"
  3. Esegui comando git merge-base <commit-hash-step1> <commit-hash-step2>.
  4. Se l'output del passaggio 3 è uguale all'output del passaggio 2, un "ramo" è già stato unito al master.

Maggiori informazioni su git merge-base https://git-scm.com/docs/git-merge-base .


2
Penso che questo ti dirà solo se i suggerimenti vengono uniti. Ad esempio, questo non ti dirà se è masterstato unito branche quindi sono stati aggiunti altri 4 commit branch.
mkobit,

Perché no git log -1 $(git merge-base base-branch feature-branch)e se vedi feature-branchnell'output, sai che sono uniti?
Carl G,

12

Sul tema della pulizia dei rami remoti

git branch -r | xargs -t -n 1 git branch -r --contains

Questo elenca ogni ramo remoto seguito da quali rami remoti si trovano i loro ultimi SHA.

Ciò è utile per discernere quali filiali remote sono state unite ma non eliminate e quali non sono state unite e quindi stanno decadendo.

Se stai usando 'tig' (è come gitk ma basato su terminale) allora puoi

tig origin/feature/someones-decaying-feature

per visualizzare la cronologia di commit di una filiale senza dover eseguire il checkout


3
Ben fatto quell'uomo! Molto utile una volta che hai la testa su ciò che viene effettivamente visualizzato! L'app GitHub deve incorporare questo in una visualizzazione visiva dei tuoi rami, piuttosto che in un elenco alfabetico senza gerarchia!
CMash

12

Per verificare quali rami vengono uniti in master, è necessario utilizzare questi comandi:

  • git branch <flag[-r/-a/none]> --merged master elenco di tutti i rami uniti in master.
  • git branch <flag[-r/-a/none]> --merged master | wc -l contare il numero di tutti i rami uniti nel master.

Le bandiere sono:

  • -aflag - (tutti) mostra filiali remote e locali
  • -rflag - (remoto) mostra solo i rami remoti
  • <emptyFlag>- mostra solo le filiali locali

ad esempio: git branch -r --merged master ti mostrerà tutti i repository remoti uniti in master.


5

Ecco le mie tecniche quando ho bisogno di capire se un ramo è stato unito, anche se potrebbe essere stato riformulato per essere aggiornato con il nostro ramo principale, che è uno scenario comune per i rami delle caratteristiche.

Nessuno di questi approcci è infallibile, ma li ho trovati utili molte volte.

1 Mostra registro per tutti i rami

Usando uno strumento visivo come gitk o TortoiseGit, o semplicemente git log con --all, scorrere la cronologia per vedere tutte le fusioni con il ramo principale. Dovresti essere in grado di individuare se questo particolare ramo di funzionalità è stato unito o meno.

2 Rimuovere sempre il ramo remoto quando si unisce in un ramo della funzione

Se hai la buona abitudine di rimuovere sempre sia il ramo locale che quello remoto quando ti unisci in un ramo di funzionalità, puoi semplicemente aggiornare e potare i telecomandi sull'altro computer e i rami di funzione scompaiono.

Per ricordare di fare questo, sto già usando le estensioni git flow (edizione AVH) per creare e unire localmente i miei rami di funzionalità, quindi ho aggiunto il seguente hook di git flow per chiedermi se desidero anche rimuovere automaticamente il ramo remoto.

Esempio di creazione / fine del ramo della funzione

554 Andreas:MyRepo(develop)$ git flow start tmp
Switched to a new branch 'feature/tmp'

Summary of actions:
- A new branch 'feature/tmp' was created, based on 'develop'
- You are now on branch 'feature/tmp'

Now, start committing on your feature. When done, use:

     git flow feature finish tmp

555 Andreas:MyRepo(feature/tmp)$ git flow finish
Switched to branch 'develop'
Your branch is up-to-date with 'if/develop'.
Already up-to-date.

[post-flow-feature-finish] Delete remote branch? (Y/n)
Deleting remote branch: origin/feature/tmp.

Deleted branch feature/tmp (was 02a3356).

Summary of actions:
- The feature branch 'feature/tmp' was merged into 'develop'
- Feature branch 'feature/tmp' has been locally deleted
- You are now on branch 'develop'

556 Andreas:ScDesktop (develop)$

.git / ganci / post-flow-funzione-finish

NAME=$1
ORIGIN=$2
BRANCH=$3

# Delete remote branch
# Allows us to read user input below, assigns stdin to keyboard
exec < /dev/tty

while true; do
  read -p "[post-flow-feature-finish] Delete remote branch? (Y/n) " yn
  if [ "$yn" = "" ]; then
    yn='Y'    
  fi
  case $yn in
      [Yy] ) 
        echo -e "\e[31mDeleting remote branch: $2/$3.\e[0m" || exit "$?"
        git push $2 :$3; 
        break;;
      [Nn] ) 
        echo -e "\e[32mKeeping remote branch.\e[0m" || exit "$?"
        break;;
      * ) echo "Please answer y or n for yes or no.";;
  esac
done

# Stop reading user input (close STDIN)
exec <&-
exit 0

3 Ricerca per messaggio di commit

Se non rimuovi sempre il ramo remoto, puoi comunque cercare commit simili per determinare se il ramo è stato unito o meno. La trappola qui è se il ramo remoto è stato ridisegnato in irriconoscibile, come schiacciare i commit o cambiare i messaggi di commit.

  • Recupera e pota tutti i telecomandi
  • Trova il messaggio dell'ultimo commit sul ramo della funzione
  • Verifica se è possibile trovare un commit con lo stesso messaggio sul ramo master

Comandi di esempio sul ramo principale:

gru                   
gls origin/feature/foo
glf "my message"

Nella mia configurazione di bash .profile

alias gru='git remote update -p'
alias glf=findCommitByMessage

findCommitByMessage() {
    git log -i --grep="$1"
}

@anjdeas - passaggio 1 - come fai a sapere quali rami sono stati uniti in main. Ho esaminato i registri e gli strumenti della GUI - e non riesco a trovare da nessuna parte dove lo mostra esplicitamente ???
The Huff,

@TheHuff Prova questo:git log --all --color --graph --decorate --topo-order --date=relative --abbrev-commit --pretty=format:"%C(green)%h %C(red bold)[%<(14)%ad] %Creset%s%Cred%d%C(blue) [%an]"
angularsen,

@TheHuff In TortoiseGit, se sei nel ramo principale, dovrebbe mostrare tutte le fusioni nel principale.
angularsen,

Grazie - ma come faccio a sapere cos'è un'unione? Suppongo che siano tutti impegnati - giusto?
The Huff,

@TheHuff: dovresti vedere visivamente due flussi / percorsi di commit uniti in un unico commit "downstream" (più in alto nella vista del registro). Tale commit è un commit di unione. Inoltre, git logpuoi aggiungere --mergessolo per mostrare i commit di unione. stackoverflow.com/a/25986615/134761
angularsen,

4

Ecco un piccolo one-liner che ti farà sapere se il tuo ramo corrente incorpora o è fuori dai dati da un ramo di origine / master remoto:

$ git fetch && git branch -r --merged | grep -q origin/master && echo Incorporates origin/master || echo Out of date from origin/master

Mi sono imbattuto in questa domanda quando ho lavorato su un ramo di funzioni e spesso volevo assicurarmi di avere il lavoro più recente incorporato nel mio ramo di lavoro separato.

Per generalizzare questo test ho aggiunto il seguente alias al mio ~ / .gitconfig:

[alias]
   current = !git branch -r --merged | grep -q $1 && echo Incorporates $1 || echo Out of date from $1 && :

Quindi posso chiamare:

$ git current origin/master

per verificare se sono attuale.

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.