Git: ¿forma correcta de cambiar Active Branch en un repositorio desnudo?

195

Tengo un repositorio desnudo que se utiliza como tienda central para mi proyecto. Todos los desarrolladores lo hacen git clone <repo>para compartirlo. Cuando hacen el clon, obtienen un pago de la rama maestra (a menos que lo hagan git clone -n) porque repo.git/HEADcontiene ref: refs/heads/master, lo que la convierte en la Rama activa .

La pregunta es, ¿cómo cambio la rama activa correctamente? Simplemente podría hackear el repo.git/HEADarchivo directamente, pero eso parece desagradable y, bueno, hacky.

Intenté hacerlo git checkout <otherbranch>en el .gitdirectorio de repositorios , pero eso falló porque no estaba en un árbol de trabajo.

Intenté, git update-ref HEAD refs/heads/otherbranchpero eso solo actualizó refs / heads / master para que sea lo mismo que refs / heads / otherbranch (está bien, lo hice en un repositorio ficticio, ¡no en mi producción!)

Lo intenté git update-ref --no-deref HEAD refs/heads/otherbranch y eso casi funcionó. Actualizó el HEADarchivo, pero lo configuró en el SHA1 del commit señalado por refs/heads/otherbranch.

Estoy probando con la versión git 1.7.0.2.msysgit.0.

Supongo que no hay forma de hacerlo git push, ya que permitir que todos cambien su rama predeterminada parece un poco inseguro (!), Pero seguramente hay una mejor manera de hacerlo en el .gitdirectorio de repositorios que piratear directamente el HEADarchivo.

kbro
fuente
OMI, solo estás tratando de hacer lo incorrecto aquí. Si desea que la rama predeterminada no sea maestra, entonces esa rama debe ser la maestra. Alternativamente, use dos repositorios diferentes.
Nicholas Knight
12
¿Cómo está tratando fundamentalmente de hacer algo incorrecto aquí? Un repositorio desnudo soporta múltiples ramas. Utilizo un repositorio desnudo como respaldo de mi repositorio local, y como tal refleja las ramas. Tengo un maestro en ambos y una rama de desarrollo en ambos. Si quiero ver el registro de la rama de desarrollo en el repositorio simple, tengo que hackear archivos; parece que git es fundamentalmente incorrecto aquí con respecto al soporte del repositorio simple.
Cthutu
15
@NicholasKnight En mi humilde opinión, estás fundamentalmente equivocado aquí. No hay nada especial sobre "maestro" como nombre de sucursal, es solo un valor predeterminado. En los depósitos que mantienen no tenemos una sucursal maestra, ya que "maestro" no tiene sentido para la empresa. Cada vez que hacemos una versión, creamos una nueva rama de mantenimiento con el nuevo número de versión y la asignamos como la rama activa.
Spacemoose
@NicholasKnight Aunque aprecio de dónde vienes, este es el primer SO Q / A que me dijo cómo cambiar a maestro. Tuve mi repositorio inicial en una rama característica cuando hice mi clon desnudo, y los clones posteriores de ese repositorio desnudo estaban predeterminados a esa rama en lugar de master.
Warbo
1
Wow, esta pregunta solo corre y corre, ¡es mi anotador de puntos de reputación número 1! Lo que pasa con "maestro" es que es solo un nombre, y si no tiene sentido para su organización, equipo, proyecto, fase, lo que sea, entonces elija algo que sea apropiado para que cuando sus colaboradores clonen su repositorio cambien inmediatamente a la rama en la que usted, como Administrador de configuración, desea que estén. Solía ​​trabajar con ClearCase (¡bletch!), Por lo que sus opciones fueron "main", "main" o "main". Yuk
kbro

Respuestas:

279

Si tiene acceso al repositorio remoto remoto, esto artículo sugiere :

git symbolic-ref HEAD refs/heads/mybranch

Que actualizará el archivo HEAD en su repositorio para que contenga:

ref: refs/heads/mybranch

como se documenta en el git-symbolic-ref


Si no tiene acceso al repositorio remoto, vea mi respuesta anterior .


Recuerda que un comando como git remote set-head :

  • no cambia la rama predeterminada del repositorio remoto .
    Solo cambia una rama de seguimiento remota almacenada en su repositorio local comorefs/remotes/<name>/HEAD

  • no cambia a HEADsí mismo (de nuevo, solo refs/remotes/<name>/HEAD), de ahí la necesidad de git symbolic-ref.

Entonces git remote set-head no es la respuesta aquí.
git symbolic-ref HEADes decir, si tiene acceso directo al repositorio remoto.

VonC
fuente
3
¡Gracias! Tengo acceso directo al repositorio remoto remoto, por lo que git-symbolic-ref hará el trabajo. Sin embargo, me gusta el truco de antepasados ​​no comunes mencionado en el otro hilo, definitivamente uno para el cajón inferior. Pasé años buscando en Google para esto, pero no pude encontrar su respuesta anterior, sin embargo, "git remote head master" lo encuentra como el segundo golpe mejor clasificado, justo debajo de git-remote (1). Extraño. Solo muestra lo difícil que es encontrar algo cuando no sabes exactamente lo que estás buscando.
kbro
git symbolic-ref HEAD refs/heads/mybranchfuncionó muy bien para mí! ¡GRACIAS! ;)
vinzenzweber
1
Realmente aprecio esta pregunta, porque accidentalmente verifiqué una rama diferente a la maestra y ahora tuve que arreglarla.
Jonny Best
Esto no funciona para mi. Curiosamente, a pesar de que el HEAD remoto en el repositorio desnudo ahora muestra la rama correcta, ¡git TODAVÍA me predetermina a una rama diferente cuando clono de ella!
Magnus
@Magnus, sería una buena pregunta en una nueva página.
VonC
3

Para cambiar la rama, debe cambiar la referencia HEAD a la rama que desea usar.

Primero enumere todas las referencias en el repositorio desnudo haciendo

$find ref

Luego encuentre la referencia para su sucursal, el formato será el siguiente refs/heads/<my_branch>. Entonces, el siguiente paso es verificar la referencia actual, simplemente escriba:

$git symbolic-ref HEAD

para saber cuál es la rama actual y luego actualizarla según sea necesario.

$git sumbolic-ref HEAD ref/heads/<my_branch>

Eso es todo. Disfrutar.

Saul Rosales
fuente
2

¿Cómo cambiar la rama activa correctamente?

  • estado: git checkout en el directorio repo .git devuelve fatal: esta operación debe ejecutarse en un árbol de trabajo

  • consejos: solo agregue el argumento --work-tree

ejemplo detallado: suposiciones: git desnudo en servidor remoto:

~ / bare_git_repository.git árbol de trabajo separado: / var / www / myappremote

en el servidor local: cree la versión de sucursal 1.7 (nuestra otra rama)

git branch versión 1.7

git push origin version.1.7

en el servidor remoto con git bare repo:

$ cd ~ / bare_git_repository.git

$ git branch


  • versión maestra 1.7

Como se dijo, siguiendo el comando

git checkout versión 1.7

regreso

fatal: esta operación debe ejecutarse en un árbol de trabajo

Usando el siguiente comando

git --work-tree = / var / www / myappremote checkout versión.1.7

cambiar correctamente la rama activa propely

$ git branch

Maestro

  • versión.1.7

verifique los resultados con lo siguiente

ll / var / www / myappremote

espero que ayude

herramientas c
fuente
Esta solución muy simple funcionó para mí, ¡gracias! Una nota: tuve que crear un directorio de árbol de trabajo vacío a mano para que el comando se ejecute correctamente.
Joël Esponde
-1

Además, si no tiene acceso al repositorio simple, haciendo una git remote set-heady ya está

Ver esta respuesta anterior

dvdvck
fuente
-3

También tengo un repositorio desnudo en nuestro servidor y pude recuperar archivos usando

git clone //server/repo/directory -b branch_name

en un nuevo repositorio local a pesar de que la página de manual dice que esto es solo para repositorios no descubiertos.

mcjh
fuente
1
Si bien lo que usted dice es cierto, el hecho de que esté utilizando -b para seleccionar una rama en particular rompe su respuesta en el contexto de mi pregunta, que es cómo establecer la rama POR DEFECTO.
kbro
-4

Comparé dos directorios antes y después de aplicar

git symbolic-ref HEAD refs/heads/mybranch

y parece que solo se cambió el archivo repo.git / HEAD, por lo que probablemente sea bastante seguro "piratear" el archivo.

Boryn
fuente
2
Hay problemas de ruptura sutiles que pueden introducirse editando directamente archivos de referencia de Git. Recomiendo altamente contra eso. Los comandos de plomería son más fáciles y seguros que editar referencias directamente.
Alain O'Dea
2
¿Cuál es la ventaja de este @boryn?
Alex Chamberlain
2
Git realiza un seguimiento de muchas cosas en el fondo, como un historial de árbitros. Si cambia manualmente el archivo, no se registrará. Es cierto que probablemente no importará. Pero si pierde el rastro de algunos commits y desea encontrarlos, será más feliz si no solo "piratea" el archivo.
qwerty9967
Usé el comando Pero esta respuesta fue útil para comprender cómo funciona y, en particular, para comprender que los árbitros / jefes es algo interno y no debería cambiarlo, solo la última parte del "camino". Entonces, voté porque creo que era información valiosa después de todo.
Mike Keskinov