En git, ¿existe una forma sencilla de introducir una rama no relacionada en un repositorio?

Resuelto hillu asked hace 15 años • 10 respuestas

Mientras ayudaba a un amigo con un problema de git hoy, tuve que introducir una rama que debía estar totalmente separada de la masterrama. Los contenidos de esta rama realmente tenían un origen diferente a lo que se había desarrollado en la masterrama, pero iban a fusionarse en la rama.master rama más adelante.

Me acordé de haber leído Git de John Wiegley de abajo hacia arriba. cómo las ramas son esencialmente una etiqueta para una confirmación que sigue una determinada convención y cómo una confirmación está vinculada a un árbol de archivos y, opcionalmente, a las confirmaciones principales. Fuimos a crear una confirmación sin padres para el repositorio existente usando la plomería de git:

Así que nos deshicimos de todos los archivos del índice...

$ git rm -rf .

... extrajo directorios y archivos de un tarball, los agregó al índice ...

$ git add .

... y creó un objeto de árbol ...

$ git write-tree

(git-write-tree nos dijo el sha1sum del objeto de árbol creado).

Luego, confirmamos el árbol, sin especificar confirmaciones principales...

$ echo "Imported project foo" | git commit-tree $TREE

(git-commit-tree nos dijo el sha1sum del objeto de confirmación creado).

... y creó una nueva rama que apunta a nuestro compromiso recién creado.

$ git update-ref refs/heads/other-branch $COMMIT

Finalmente regresamos a la mastersucursal para continuar trabajando allí.

$ git checkout -f master

Esto parece haber funcionado según lo planeado. Pero claramente este no es el tipo de procedimiento que recomendaría a alguien que recién está comenzando a usar git, por decirlo suavemente. ¿Existe una forma más sencilla de crear una nueva rama que no tenga ninguna relación con todo lo que ha sucedido en el repositorio hasta ahora?

hillu avatar Sep 06 '09 04:09 hillu
Aceptado

Hay una característica nueva (desde V1.7.2) que hace que esta tarea sea un poco más avanzada que la de cualquiera de las otras respuestas.

git checkoutahora admite la --orphanopción. Desde la página de manual :

git checkout [-q] [-f] [-m] --orphan <new_branch> [<start_point>]

Cree una nueva rama huérfana , denominada <new_branch>, iniciada desde <start_point> y cambie a ella. La primera confirmación realizada en esta nueva rama no tendrá padres y será la raíz de un nuevo historial totalmente desconectado de todas las demás ramas y confirmaciones.

Esto no hace exactamente lo que quería el autor de la pregunta, porque llena el índice y el árbol de trabajo <start_point>(ya que, después de todo, es un comando de pago). La única otra acción necesaria es eliminar cualquier elemento no deseado del árbol de trabajo y del índice. Desafortunadamente, git reset --hardno funciona, pero git rm -rf .se puede usar en su lugar (creo que esto es equivalente a lo que rm .git/index; git clean -fdxse da en otras respuestas).


En resumen:

git checkout --orphan newbranch
git rm -rf .
<do work>
git add your files
git commit -m 'Initial commit'

Lo dejé <start_point>sin especificar porque el valor predeterminado es HEAD y, de todos modos, no nos importa. Esta secuencia hace esencialmente lo mismo que la secuencia de comandos en la respuesta de Artem , solo que sin recurrir a comandos de plomería aterradores.

tcovo avatar Nov 26 '2010 21:11 tcovo

Del libro de la comunidad Git :

git symbolic-ref HEAD refs/heads/newbranch 
rm .git/index 
git clean -fdx 
<do work> 
git add your files 
git commit -m 'Initial commit'
Artem Tikhomirov avatar Sep 05 '2009 21:09 Artem Tikhomirov