¿Cómo puedo saber si una rama ya se ha fusionado con master?

1140

Tengo un repositorio git con múltiples ramas.

¿Cómo puedo saber qué ramas ya están fusionadas en la rama maestra?

hectorsq
fuente

Respuestas:

1793

git branch --merged masterenumera ramas fusionadas en maestro

git branch --mergedenumera las ramas fusionadas en HEAD (es decir, la punta de la rama actual)

git branch --no-merged enumera las ramas que no se han fusionado

Por defecto, esto se aplica solo a las sucursales locales. La -abandera mostrará ramas locales y remotas, y la -rbandera solo muestra las ramas remotas.

hectorsq
fuente
2
Solo una nota al margen, cuando intenté ver si una rama remota se había fusionado, primero configuré una rama de seguimiento local, identifiqué el estado git branch --mergedy luego eliminé las ramas locales y remotas.
Kenneth Kalmer
83
Aparentemente, git branch -a --merged/no-mergedtambién funciona, sin crear una rama de seguimiento local en el proceso.
fresskoma
70
O simplemente git branch -r --merged/--no-mergedpara encontrar sucursales remotas.
Asfand Qazi
55
¿Alguna forma de eliminar ramas no fusionadas que realmente se fusionaron después de rebase?
Ashfame
99
Tenga en cuenta que --merged/--no-mergedtoma un argumento de confirmación opcional después de él. Al menos en mi versión de git (1.9.1), agregar el indicador -ao -rdespués de esto me da un error fatal. Agregue el -ao -r antes --(no-)merged .
Jonathan Gawrych
113

Puede usar el git merge-basecomando para encontrar la última confirmación común entre las dos ramas. Si esa confirmación es la misma que la de su jefe, entonces la rama se ha fusionado por completo.

Tenga en cuenta que ya git branch -dhace este tipo de cosas porque se negará a eliminar una rama que aún no se ha fusionado por completo.

Greg Hewgill
fuente
3
La respuesta de @ hari entra en más detalles sobre cómo usar esto.
Muhd
¿Cómo podemos hacer esto automática / programáticamente?
Alexander Mills
1
"no ha sido completamente fusionado" ... ¿completamente fusionado en qué rama?
Alexander Mills
@AlexanderMills: en su sucursal actual.
Greg Hewgill
2
@AlexanderMills: git branch -dse negará a eliminar una rama que no se haya fusionado con la rama actual. No se elimina la rama actual .
Greg Hewgill
27

También hay una solución de interfaz gráfica. Sólo tipo

gitk --all

Se abrirá una nueva ventana de aplicación con una representación gráfica de todo su repositorio, donde es muy fácil darse cuenta de si una rama ya se fusionó o no.

iberbeu
fuente
17
Para que quede claro, requiere la instalación de una aplicación que no sea parte del gitcliente. En Ubuntu, apt-get install gitk.
metame
En macOS, si tiene instalado Homebrew, sería brew install git-gui, para entrar gitken la línea de comandos.
program247365
24

Estoy usando la siguiente función bash como: 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
}
Carl G
fuente
3
Esto en realidad no funciona. Si la rama de origen ya se ha fusionado con la rama de destino, y luego la rama de destino obtiene algunas confirmaciones más, ya no funciona, pero no sé por qué
Alexander Mills
1
vea la pregunta aquí: stackoverflow.com/questions/51355331/…
Alexander Mills
18

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

Este comando encuentra los mejores ancestros comunes entre dos confirmaciones. Y si el ancestro común es idéntico al último commit de una "rama", entonces podemos asumir con seguridad que una "rama" ya se ha fusionado con el maestro.

Aquí están los pasos.

  1. Encuentra el último hash de confirmación en la rama maestra
  2. Encuentra el último hash de confirmación en una "rama"
  3. Orden de marcha git merge-base <commit-hash-step1> <commit-hash-step2>.
  4. Si la salida del paso 3 es igual a la salida del paso 2, entonces una "rama" ya se ha fusionado en el maestro.

Más información sobre git merge-base https://git-scm.com/docs/git-merge-base .

Hari
fuente
2
Creo que esto solo te dirá si los consejos se fusionan. Por ejemplo, esto no le dirá si masterse fusionó branchy luego se agregaron 4 confirmaciones más branch.
mkobit
¿Por qué no git log -1 $(git merge-base base-branch feature-branch)y si ves feature-branchen la salida, entonces sabes que están fusionados?
Carl G
12

Sobre el tema de limpiar ramas remotas

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

Esto enumera cada rama remota seguida de qué ramas remotas están dentro de sus últimos SHA.

Esto es útil para discernir qué ramas remotas se han fusionado pero no se han eliminado, y cuáles no se han fusionado y, por lo tanto, están en descomposición.

Si está usando 'tig' (es como gitk pero basado en terminal), entonces puede

tig origin/feature/someones-decaying-feature

para ver el historial de confirmación de una sucursal sin tener que pasar por caja

xxjjnn
fuente
3
¡Bien hecho ese hombre! ¡Muy útil una vez que entiendes lo que realmente está mostrando! ¡La aplicación GitHub necesita incorporar esto en una visualización de sus ramas, en lugar de una lista alfabetizada sin jerarquía!
CMash
12

Para verificar qué ramas se fusionan en master, debe usar estos comandos:

  • git branch <flag[-r/-a/none]> --merged master lista de todas las ramas fusionadas en master.
  • git branch <flag[-r/-a/none]> --merged master | wc -l cuenta el número de todas las ramas fusionadas en maestro.

Las banderas son:

  • -abandera - (todos) mostrando sucursales remotas y locales
  • -rbandera - (remoto) que muestra solo ramas remotas
  • <emptyFlag>- mostrando solo sucursales locales

por ejemplo: git branch -r --merged master le mostrará todos los repositorios remotos combinados en maestro.

avivamg
fuente
5

Estas son mis técnicas cuando necesito averiguar si una rama se ha fusionado, incluso si se ha modificado para actualizarse con nuestra rama principal, que es un escenario común para las ramas de características.

Ninguno de estos enfoques es infalible, pero los he encontrado útiles muchas veces.

1 Mostrar registro para todas las sucursales

Usando una herramienta visual como gitk o TortoiseGit, o simplemente git log con --todos, recorra el historial para ver todas las fusiones en la rama principal. Debería poder detectar si esta rama de característica particular se ha fusionado o no.

2 Elimine siempre la rama remota cuando se fusione en una rama de características

Si tiene el buen hábito de eliminar siempre tanto la rama local como la remota cuando se fusiona en una rama de funciones, simplemente puede actualizar y podar los controles remotos en su otra computadora y las ramas de funciones desaparecerán.

Para ayudar a recordar hacer esto, ya estoy usando extensiones de flujo de git (edición AVH) para crear y fusionar mis ramas de características localmente, así que agregué el siguiente enlace de flujo de git para preguntarme si también quiero eliminar automáticamente la rama remota.

Ejemplo de creación / finalización de la rama característica

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 / ganchos / post-flow-feature-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 Búsqueda por mensaje de confirmación

Si no siempre elimina la rama remota, aún puede buscar confirmaciones similares para determinar si la rama se ha fusionado o no. El problema aquí es si la rama remota se ha modificado para volverse irreconocible, como aplastar confirmaciones o cambiar mensajes de confirmación.

  • Busca y poda todos los controles remotos
  • Encuentra el mensaje de la última confirmación en la rama de características
  • Vea si se puede encontrar una confirmación con el mismo mensaje en la rama maestra

Comandos de ejemplo en la rama maestra:

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

En mi bash .profile config

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

findCommitByMessage() {
    git log -i --grep="$1"
}
angularsen
fuente
@anjdeas - paso 1 - ¿cómo sabes qué ramas se han fusionado en main? He estado mirando los registros y las herramientas de interfaz gráfica de usuario, y no puedo encontrar ningún lugar donde explícitamente muestre esto.
The Huff
@TheHuff Pruebe esto: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 En TortoiseGit, si está en la rama principal, debería mostrar todas las fusiones en main.
angularsen
Gracias, pero ¿cómo sé qué es una fusión? Supongo que todos son commits, ¿es esto correcto?
The Huff
@TheHuff: Debería ver visualmente dos secuencias / rutas de confirmaciones fusionadas en una única confirmación "en sentido descendente" (más arriba en la vista de registro). Ese commit es un commit de fusión. Además, en git logpuede agregar --mergessolo mostrar confirmaciones de fusión. stackoverflow.com/a/25986615/134761
angularsen
4

Aquí hay una pequeña frase que le permitirá saber si su sucursal actual incorpora o no tiene datos de una sucursal de origen / maestro remota:

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

Me encontré con esta pregunta cuando trabajaba en una rama de características y con frecuencia quería asegurarme de tener el trabajo más reciente incorporado en mi propia rama de trabajo separada.

Para generalizar esta prueba, he agregado el siguiente alias a mi ~ / .gitconfig:

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

Entonces puedo llamar:

$ git current origin/master

para verificar si estoy al día.

radke
fuente