¿Cómo obtener la rama predeterminada de Git?

9 minutos de lectura

avatar de usuario de lfender6445
lfender6445

Mi equipo alterna entre el uso de dev y master como rama predeterminada para varios repositorios y me gustaría escribir un script que verifique la rama predeterminada al ingresar a un directorio.

Cuando se abren solicitudes de incorporación de cambios en algunos de estos repositorios, se establecen de forma predeterminada en ‘dev’ o ‘master’ como destino de combinación.

Entiendo cómo configurar esta información pero no recuperarla:
https://help.github.com/articles/estableciendo-la-rama-predeterminada/

¿Hay un comando git disponible para determinar la rama predeterminada para el repositorio remoto?

  • La rama predeterminada es una cosa de github, no una cosa de git.

    – Ismail Badaui

    23 de febrero de 2015 a las 3:10

  • Puede usar la API de GitHub, como en esta pregunta: stackoverflow.com/questions/16500461/…

    – Ismail Badaui

    23 de febrero de 2015 a las 3:15

  • @IsmailBadawi ¿En serio? Al crear un repositorio simple local y realizar una clonación, aún debe haber alguna lógica que determine qué rama se verifica de forma predeterminada, ¿verdad?

    – bluenote10

    16 de julio de 2019 a las 7:33

  • Ninguna de las siguientes soluciones funciona de manera confiable para mí: si estoy en una sucursal featurebifurcado de developme devolverá develop y no master (o maina partir del cual develop es un tenedor)… ¿Alguna ayuda?

    – usuario3341592

    12 de enero de 2021 a las 16:02


  • Pregunta realizada en stackoverflow.com/questions/65703168/…

    – usuario3341592

    13 de enero de 2021 a las 13:42

Avatar de usuario de Radon8472
Radón8472

Encontré una manera de detectar la rama predeterminada si no es maestra.

git remote show [your_remote] | sed -n '/HEAD branch/s/.*: //p'

Lo probé con varios repositorios de gitlab y funcionó bien. (para la mayoría de las situaciones [your_remote] estarán origincorrer git remote para verificar el nombre de su control remoto)

  • Esto funcionó bien para mí, excepto que el comando de corte deja un espacio antes del nombre real de la rama, lo que puede causar problemas al usar esto desde scripts. terminé usando git remote show upstream | grep "HEAD branch" | sed 's/.*: //'

    – JHH

    9 oct 2018 a las 12:01


  • El mejor método hasta ahora. Ni siquiera tengo refs/remotes/origin/HEAD por algunas razones.

    – Loïc Faure-Lacroix

    11 oct 2018 a las 16:08

  • Lo actualicé para que sea así para eliminar el espacio. git remote show origin | grep 'HEAD branch' | cut -d' ' -f5

    – Andrés

    20 sep 2019 a las 16:56

  • Tenga en cuenta que esto podría no funcionar para algunas versiones (más antiguas) de git, siempre que tenga HEAD ambiguo. Ver, por ejemplo, esta publicación

    – David Střelák

    27 de septiembre de 2019 a las 9:53

  • Esto no funcionará si git se ejecuta en una configuración regional distinta del inglés. Por ejemplo, con una configuración regional alemana HEAD branch se escribe Hauptbranch. Para solucionar este uso: LC_ALL=C git remote show origin | sed -n '/HEAD branch/s/.*: //p'

    – Slaven Rezic

    23 de marzo a las 16:15

avatar de usuario de danielkza
danielkza

Probado con git 2.9.4 (pero posiblemente funcione en otras versiones) en un repositorio clonado de Github:

git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'

Salida de muestra:

master

  • si cambio la rama predeterminada en el lado del servidor (github), esto aún obtiene el valor predeterminado anterior en un clon antiguo pero actual (pero los clones nuevos están bien). ¿Cómo se fuerza una actualización aquí?

    – nhed

    5 abr 2018 a las 15:20

  • Tal vez estoy haciendo algo mal, pero cuando ejecuto esto me sale: fatal: ref refs/remotes/origin/HEAD is not a symbolic ref con Git 2.19.1.

    – cristianbundy

    2 de noviembre de 2018 a las 17:03


  • Este método puede fallar o devolver resultados incorrectos. La referencia puede ser un hash que no se puede resolver en una rama en lugar de una referencia simbólica. Esto se puede resolver mirando HEAD también. Aún así, en 6528 repositorios verifiqué los dos git symbolic-ref métodos devuelven resultados incorrectos (por ejemplo, master más bien que develop por Alfresco/chef-alfresco) en 172 casos. los git remote show El método propuesto por @ Radon8472 es más confiable y parece devolver el resultado correcto en algunos de los 172 casos divergentes que verifiqué a mano.

    – Diomidis Spinellis

    25 de enero de 2019 a las 15:20


  • También puedes usar nombre base en lugar de sed basename $(git symbolic-ref refs/remotes/origin/HEAD)

    – OzzyCheco

    26 de marzo de 2019 a las 11:20


  • Para sincronizar esta referencia simbólica desde arriba, git remote set-head origin --auto. Esto actualiza tanto lo que se ve en git remote show y la referencia simbólica a la que se hace referencia aquí.

    –Eduardo Anderson

    14 de enero de 2020 a las 14:46

git rev-parse --abbrev-ref origin/HEAD imprimirá origin/<default-branch-name>. los git symbolic-ref las respuestas están haciendo lo mismo pero necesitan un argumento más largo.

Si el origin repositorio cambia su nombre de rama predeterminado, luego git remote set-head origin -a recuperará el nuevo nombre de rama predeterminado.

  • Esto corre mucho más rápido que git remote show, porque utiliza información local sin sondear el control remoto. Puede recortar los primeros 7 caracteres (es decir, “origen/”) y obtener solo el nombre de la rama con git rev-parse --abbrev-ref origin/HEAD | cut -c8-.

    – scottclowe

    15 de junio de 2021 a las 0:20


  • ¿No es esta realmente la respuesta canónica, ya que usa un comando de plomería y no requiere ninguna utilidad fuera de git?

    – Andrés Spencer

    18 de junio de 2021 a las 11:47

  • Respondiéndome a mí mismo: esta NO es la respuesta canónica, ya que solo funciona en un repositorio creado mediante la clonación desde el control remoto, no desde un repositorio que creó y luego agregó el control remoto por git remote add y empujó a él.

    – Andrés Spencer

    18 de junio de 2021 a las 11:52

  • (Sigo votando porque es la mejor respuesta en el caso de uso probable de un script en el que sabe que ha clonado el repositorio desde un control remoto)

    – Andrés Spencer

    18 de junio de 2021 a las 11:54

  • No funciona para mí: cuando se ejecuta como en la respuesta, el único stdout que obtengo es origin/HEADy también hay errores warning: ignoring dangling symref refs/remotes/origin/HEAD, fatal: ambiguous argument 'origin/HEAD': unknown revision or path not in the working tree.. Si agrego al comando un -- .dice warning: ignoring dangling symref refs/remotes/origin/HEAD, fatal: bad revision 'origin/HEAD'. sin embargo, el git symbolic-ref respuesta esta respuesta se refiere a obras para mí.

    – Hola angel

    8 de agosto de 2021 a las 14:42

No parece haber una respuesta que no requiera clonación hasta ahora

Esto requiere git 2.8.0 o más reciente

$ git ls-remote --symref git@github.com:pre-commit/pre-commit.github.io HEAD
ref: refs/heads/real_master HEAD
e100a6a3c72b4e54f0d176f791dfd2dbd7eb5fa7    HEAD

Esta pregunta es un poco antigua, pero en caso de que alguien se encuentre con esto más recientemente …

git remote show <remote_name> | awk '/HEAD branch/ {print $NF}'

Eso también solo mostrará el nombre de la rama, sin incluir ninguno de los espacios en blanco u otras tonterías.

Me gusta guardar esto usando un par de alias de git (tengo un montón de alias útiles como este):

upstream-name = !git remote | egrep -o '(upstream|origin)' | tail -1
head-branch = !git remote show $(git upstream-name) | awk '/HEAD branch/ {print $NF}'

Uso “aguas arriba” y “origen” como mis controles remotos casi el 100% del tiempo (“aguas arriba” cuando voy con un Tenedor y tirar flujo de trabajo… que es a menudo). Es posible que su caso de uso no necesite el upstream-name alias, simplemente lo encuentro útil.

  • Una posible solución de PowerShell: (git remote show origin | Select-String "HEAD branch: " -Raw).Split(' ', [System.StringSplitOptions]::RemoveEmptyEntries)[2]

    – kapsiR

    5 de mayo de 2021 a las 7:04

  • git remote show es lento porque consulta el servidor. Usar la opción -n es más rápido pero solo devuelve la lista de ramas ya conocidas. Esa podría no ser la mejor solución, pero uno podría escribir lo siguiente: git remote show origin -n | grep -c main &> /dev/null && echo main || echo master

    – Fredericrous

    7 julio 2021 a las 21:57

  • No me funciona, dice “Se agotó el tiempo de conexión”. Supongo que eso se debe a que el comando accede a la red en lugar de usar la información disponible localmente, creo que vale la pena mencionarlo en la publicación.

    – Hola angel

    8 de agosto de 2021 a las 14:35

  • Esto fallará si git está localizado. Ver también stackoverflow.com/questions/28666357/…

    – Slaven Rezic

    1 de julio a las 10:32

  • ¡Esto funciona muy bien con git 2.37.1!

    – djthomas

    9 ago a las 20:50

avatar de usuario de lsl
LSL

Hay un –corto opción a Git simbólico-ref. Así que mi comando preferido:

$ basename $(git symbolic-ref --short refs/remotes/origin/HEAD) 
master

  • Una posible solución de PowerShell: (git remote show origin | Select-String "HEAD branch: " -Raw).Split(' ', [System.StringSplitOptions]::RemoveEmptyEntries)[2]

    – kapsiR

    5 de mayo de 2021 a las 7:04

  • git remote show es lento porque consulta el servidor. Usar la opción -n es más rápido pero solo devuelve la lista de ramas ya conocidas. Esa podría no ser la mejor solución, pero uno podría escribir lo siguiente: git remote show origin -n | grep -c main &> /dev/null && echo main || echo master

    – Fredericrous

    7 julio 2021 a las 21:57

  • No me funciona, dice “Se agotó el tiempo de conexión”. Supongo que eso se debe a que el comando accede a la red en lugar de usar la información disponible localmente, creo que vale la pena mencionarlo en la publicación.

    – Hola angel

    8 de agosto de 2021 a las 14:35

  • Esto fallará si git está localizado. Ver también stackoverflow.com/questions/28666357/…

    – Slaven Rezic

    1 de julio a las 10:32

  • ¡Esto funciona muy bien con git 2.37.1!

    – djthomas

    9 ago a las 20:50

El siguiente comando enumerará la rama HEAD, sin importar cómo hayas nombrado tus controles remotos:

git branch --remotes --list '*/HEAD'

De ahí puedes extraer la rama predeterminada de esta manera:

git branch -rl '*/HEAD' | rev | cut -d/ -f1 | rev

(usando variantes cortas del git branch argumentos).

Si su caparazón no tiene el rev comando, puede usar awk en cambio:

git branch -rl '*/HEAD' | awk -F/ '{print $NF}'

  • estoy trabajando en un lugar que stage se utiliza como tronco para el desarrollo, y master se utiliza para el despliegue. esto me da stageque es lo que quería – ¡gracias!

    – rattray

    27 mayo 2021 a las 18:39

  • da por mi bash: rev: command not found y fatal: -a and -r options to 'git branch' do not make sense with a branch name

    – Radón8472

    21 de septiembre a las 7:51

  • @ Radon8472 Si su caparazón no tiene el rev comando, puede usar awk en cambio: git branch -rl '*/HEAD' | awk -F/ '{print $NF}'

    – Enrique

    22 de septiembre a las 12:15

  • @Henry esto da fatal: -a and -r options to 'git branch' do not make sense with a branch name

    – Radón8472

    24 de septiembre a las 6:31

  • @ Radon8472 ¿Dónde está el -a viene la opcion? ¿Qué obtienes cuando ejecutas solo el primer comando? git branch -rl '*/HEAD' ?

    – Enrique

    25 de septiembre a las 23:02

¿Ha sido útil esta solución?