Soy un usuario de SVN y ahora estoy aprendiendo Git.
En SVN, generalmente pago en mi máquina local un repositorio, que incluye todas las ramas en mi proyecto y solía seleccionar la carpeta para mi rama que me interesa y trabajar allí.
Veo una diferencia usando Git.
Actualmente estoy clonando un repositorio y clono una rama específica usando gitk.
La carpeta del proyecto contiene solo el contenido de esa rama y no puedo ver todas las ramas como en SVN, lo cual es un poco confuso para mí.
No puedo encontrar una manera fácil de ver todas las ramas en mi repositorio local usando Git.
Me gustaría saber si el proceso de Git que describí es "estándar" y de alguna manera es correcto o me falta algo.
También me gustaría saber cómo manejar un proceso en el que necesito trabajar en dos ramas al mismo tiempo en caso de que, por ejemplo, necesite hacer una revisión en master pero mantener el contenido de otra rama también.
¿Cuáles son las convenciones de nombre recomendadas para hacer las carpetas que incluyen la rama clonada del repositorio en Git, por ejemplo
myproject-branchname
?
git clone
se parece mássvnadmin hotcopy
osvnrdump
+svnadmin load
de lo que es comosvn checkout
. Congit
, usted no solicita los retazos de la repositorio; Usted copia todo el repositorio y trabaja con él localmente, empujando los cambios de regreso al repositorio "fuente" cuando y si lo desea. Git y Subversion usan dos modelos completamente diferentes para el control de fuente.git-flow
Respuestas:
¡Bienvenido a la pandilla!
SVN Reeducación
Espera un momento. Si bien CVS y SVN y otros sistemas de control de versiones tradicionales (es decir, centralizados) cumplen (en su mayoría) el mismo propósito que los sistemas de control de versiones modernos (es decir, distribuidos) como mercurial y Git, será mucho mejor aprender Git desde cero en lugar de tratando de transferir su flujo de trabajo SVN a Git.
http://hginit.com ( ver en archive.org ) por Joel Spolsky (uno de los fundadores de Stack Exchange) es un tutorial para mercurial, no para Git, pero es el capítulo cero, "Subversion Re-education" es útil para usuarios que se han alejado de SVN para cualquier sistema de control de versiones distribuido, ya que le dice qué conceptos SVN tiene que (temporalmente) de la ONU -Aprender (o a
stash
distancia , ya que los usuarios podrían decir Git) para ser capaz de envoltura de la cabeza alrededor del distribuida conceptos del sistema de control de versiones y los flujos de trabajo idiomáticos establecidos para trabajar con ellos.Entonces puede leer ese capítulo cero y, en su mayoría, simplemente reemplazar la palabra "mercurial" por "Git" y así prepararse adecuadamente a sí mismo y a su mente para Git.
La letra pequeña
(Es posible omitir este por ahora.) Si bien voluble y Git son mucho más similares entre sí que a SVN, no son algunas diferencias conceptuales entre ellos, por lo que algunos de los estados y los consejos de "subversión reeducación" será técnicamente equivocada al reemplazar "mercurial" con "Git":
En SVN, todo es un directorio (pero no necesariamente debe tratarse como tal)
Pero te he estado interrumpiendo. ¿Estabas diciendo?
Si, con eso, quiere decir que ha extraído la carpeta raíz del repositorio SVN (o cualquier otra carpeta que corresponda a más que
trunk
a una sola rama, por ejemplo, en el diseño de repositorio SVN convencional, labranches
carpeta que contiene todas las ramas no troncales) entonces Me atrevo a decir que probablemente haya usado SVN incorrectamente (ish), o al menos haya abusado un poco del hecho de que el tronco, las ramas y las etiquetas están todas dobladas en un solo espacio de nombres (aunque jerárquico) junto con directorios dentro de las revisiones / base de código.Si bien puede ser tentador cambiar varias ramas de SVN en paralelo, AFAIK no es así como se pretende usar SVN. (Aunque no estoy seguro de qué inconvenientes específicos podría tener un trabajo como ese).
En Git, solo los directorios son directorios
Cada clon de un repositorio de Git es en sí mismo un repositorio de Git: de forma predeterminada, obtiene una copia completa del historial del repositorio de origen, incluidas todas las revisiones, ramas y etiquetas. Pero mantendrá todo lo que tenga a su manera: Git lo almacena en una especie de base de datos basada en archivos, ubicada en la
.git/
subcarpeta oculta de la carpeta raíz del repositorio .Pero, ¿cuáles son los archivos no ocultos que ve en la carpeta del repositorio?
Cuando eres
git clone
un repositorio, Git hace varias cosas. Aproximadamente:.git/
subcarpeta con la "base de datos"master
).Ese último paso significa que Git busca la revisión a la que apunta esta rama y desempaqueta el árbol de archivos almacenado allí (la base de datos utiliza algunos medios de compresión y deduplicación) en la carpeta raíz del repositorio. Esa carpeta raíz y todas sus subcarpetas (excluyendo la
.git
subcarpeta especial ) se conocen como la "copia de trabajo" de su repositorio. Ahí es donde interactúa con el contenido de la revisión / rama actualmente desprotegida. Son solo carpetas y archivos normales. Sin embargo, para interactuar con el repositorio per-se (la "base de datos" de revisiones y referencias) utilizagit
comandos.Ver ramas de Git e interactuar con ramas de Git
La versión de
gitk
I got no puede clonar repositorios. Solo puede ver el historial de repositorios y crear sucursales y consultar sucursales. Además, no hay "clonación" de una rama. Solo puede clonar repositorios.¿Querías decir que clonaste un repositorio usando
git clone ...
y luego, usandogitk
, revisas una rama?Sí, eso es bastante estándar:
git clone ...
git checkout ...
o utiliza una herramienta gráfica comogikt
Tal vez:
git branch
git branch -r
o todas las ramas congit branch -a
puede usar
gitk
para ver el historial completo (todas las etiquetas de sucursales, etc., que su repositorio local conoce) invocandoCómo trabajar con múltiples ramas en paralelo
Hay diferentes escenarios aquí:
Un nuevo cambio (aún por crear) debe aplicarse a varias ramas
Use este flujo de trabajo:
c
partir de una revisión que ya esté en la ascendencia de todas estas ramas (por ejemplo, la revisión que introdujo el error cuando el cambio será una corrección de error) o de una revisión que (incluyendo todos sus antepasados) es aceptable para ser introducida en Todas estas ramas.c
.Para cada rama
b
que necesita el cambio:Echa un vistazo a
b
:Fusionarse
c
enb
:Eliminar rama
c
:Se necesita un cambio existente en una sucursal diferente
(... pero sin los otros cambios realizados en el lugar donde reside ese cambio)
En una rama
a
, desea cambiar uno o algunos archivos al estado exacto que tienen en una rama diferenteb
a
Obtenga el contenido del archivo de la rama
b
:(Además de
git checkout
sin pasar rutas, esto no cambiará a ramab
, solo obtendrá el contenido del archivo solicitado desde allí. Estos archivos pueden o no existir yaa
. Si lo hacen, se sobrescribirán con su contenido activadob
).Mientras trabaja en una rama, desea ver cómo están las cosas en otra rama
Echa un vistazo a la rama en la que quieres trabajar.
Luego, por mirar la otra rama,
gitk
intentar cambiar los botones de radio de "parche" a "árbol")git worktree
para crear un directorio de trabajo separado del mismo repositorio (es decir, también usando la base de datos en el.git/
directorio de su repositorio local actual) donde puede verificar esa otra ramafuente
stash
es ideal.git stash
Es bueno quitar el trabajo inacabado, por ejemplo, para cambiar de rama y luego volver.A menos que revise el directorio sobre el enlace troncal, en Subversion generalmente no tiene todas las ramas disponibles localmente. En Git, todo el contenido (confirmaciones, mensajes, ramas, etc.) siempre se clona en cada copia.
No es posible, ver arriba. Puedes
git checkout branch-name
, pero no puedesgit clone something branch-name
. En Subversion, las ramas son carpetas. En Git, las ramas son punteros a un commit.Ejecutar
git branch
. Por defecto, solo muestra sucursales locales. Usegit branch --remote
para ver ramas remotas.fuente
--single-branch
(incluso solo la punta con--depth 1
). La diferencia entre las ramas locales y remotas conocidas por git es simplemente un tipo de etiqueta. Las ramas remotas tienen el prefijo del nombre de la fuente remota (a menudoorigin
). Las sucursales locales no tienen ese prefijo. Pero al final, los datos están disponibles localmente (a menos que lo haya hecho--single-branch
o algo similar). Cuando se ejecutagit checkout $branchname
con una rama para la que no existe una rama local sino remota, git configura automáticamente una rama local que "rastrea" el control remoto.Como esto está etiquetado con git , espero que mi falta de conocimiento de SVN sea descuidada.
Está clonando todo el repositorio remoto, no solo una rama específica.
El repositorio se imagina mejor como una base de datos, por lo que está haciendo un clon del estado actual de la base de datos remota. Pero después de eso, está trabajando en su propia copia de esa base de datos; si se compromete, modifica su base de datos local.
El
fetch
comando se utiliza para mantener la base de datos local sincronizada con la remota.Por lo general, desde esa base de datos local, revisa una sucursal para trabajar. Esto no es más que un marcador interno para git, donde comenzó su trabajo actual.
Digamos que estás trabajando en un repositorio simple, donde no hay una rama además
master
, puedes echar un vistazo a la.git
carpeta para desvelar la "magia":Suponga que su último commit (on
master
) fue182e8220b404437b9e43eb78149d31af79040c66
, encontrará exactamente eso debajocat .git/refs/heads/master
.A partir de eso, ramifica una nueva rama
git checkout -b mybranch
, encontrará exactamente el mismo puntero en el archivocat .git/refs/heads/mybranch
.Las ramas no son más que "punteros". El marcador de "trabajo" se llama a
HEAD
.Si desea saber dónde está su
HEAD
está en:cat .git/HEAD
que diceref: refs/heads/mybranch
, por ejemplo , que a su vez apunta (cat .git/refs/heads/mybranch
) a un hash de confirmación78a8a6eb6f82eae21b156b68d553dd143c6d3e6f
Las confirmaciones reales se almacenan en la
objects
carpeta (el cómo es un tema propio).No confunda el
working directory
con la "base de datos git" en su conjunto. Como dije anteriormente, su directorio de trabajo es solo una instantánea de (quizás) un subconjunto.Digamos que tiene diferentes sucursales, su directorio de trabajo está dedicado a trabajar solo en esa rama (aunque podría colocar el trabajo desde allí en otro lugar).
Por lo general, si desea ver qué ramas están definidas para el proyecto, tiene la posibilidad de
git branch
para sucursales localesgit branch --remote
para sucursales remotasgit branch -a
para ambos(o
git branch -v
)Dado que git es un sistema de control de versiones distribuido, no solo es posible, sino que se recomienda, hacer diferentes ramas localmente / remotas.
Mi flujo de trabajo típico es:
Cuando se completa la función:
WIP
rama (con rebase interactivo) = hacer un solo commit desde eseWIP
rama en la rama de características y ofrecer que (si trabaja con github esa oferta se llamaría una "solicitud de extracción") para integrarse en la rama estable (maestra).Depende de cómo esté estructurado su proyecto:
Digamos que tienes un maestro estable. Y las características solo se desarrollan a partir de esa rama estable, por lo que generalmente está detrás de una rama de características. Entonces tendría un último commit en master que sería la raíz de la rama de características.
Luego, realizaría una confirmación en la rama maestra y podría decidir si fusionar ambas ramas o volver a crear una base (lo cual es una especie de fusión para usuarios con necesidades avanzadas, por así decirlo).
O siempre puede realizar cambios en las ramas (p
master
. Ej. ) Y seleccionarlos en otras ramas.Es tu decision.
Por lo general, terminas con el nombre de los repositorios.
Pero hay ocasiones, cuando esto no se quiere:
por ejemplo, clonas oh-my-zsh con
git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
Aquí.oh-my-zsh
se nombra explícitamente como el objetivo.fuente
Git clone
en realidad clona todo el repositorio, pero establece su directorio de trabajo en el valor predeterminado (generalmente maestro).Puede ver otras ramas usando
git branch
para ver ramas locales ogit branch -r
remotas y luegogit checkout
cambiar a una rama existente o crear una nueva basada en la rama actual.Debería leer la documentación de git para obtener más detalles, y Atlassian también tiene algunos buenos artículos al respecto.
fuente
Las ramas en git y svn son cosas fundamentalmente diferentes.
En svn, una rama (o una etiqueta) es un directorio en el repositorio.
En git, una rama (o una etiqueta) es un puntero a una confirmación.
Con svn puedes hacerlo si deseas pagar la raíz del repositorio. Esto significa que tiene todas las ramas y etiquetas desprotegidas a la vez. De hecho, esta no es la forma normal de usar svn.
Una rama git no es un directorio, por lo que no existe el privilegio de "verificar la raíz del repositorio". Existe cierto soporte para múltiples árboles de trabajo, por lo que supongo que podría improvisar un script para verificar cada rama al mismo tiempo si realmente quisiera, pero sería un pensamiento bastante inusual.
Además, con SVN hay exactamente un repositorio. Con git cada desarrollador tiene su propio repositorio. Esto significa que los desarrolladores pueden trabajar sin conexión, pero también significa que diferentes desarrolladores pueden tener una idea diferente de lo que hay en cada rama.
En virtud de ser directorios y en virtud del modelo de historia lineal simple de svn, las ramas de svn tienen historias sólidas. Si desea saber qué había en la rama x en la fecha y, puede hacer esa pregunta fácilmente.
Las ramas de Git, por otro lado, realmente no tienen historias. Existe el "reflog", pero está pensado más como un mecanismo de recuperación ante desastres que como un historial a largo plazo. En particular, el reflog no se puede leer de forma remota y está deshabilitado de forma predeterminada para repositorios desnudos.
Los commits, por supuesto, tienen historias, pero esas historias no son suficientes para responder a la pregunta de "qué estaba en la rama x del repositorio en la fecha z".
Puede enumerar todas las sucursales locales escribiendo "git branch".
Puede enumerar todas las ramas locales y remotas utilizando "git branch -a"
Un par de opciones
Puede confirmar sus cambios en la "otra rama", cambiar a maestro, hacer su trabajo allí y luego volver a cambiar.
También puede crear un árbol de trabajo adicional. Google "git-worktree" para los detalles sobre la sintaxis.
No creo que haya una convención establecida. Tener varios árboles de trabajo desprotegidos a la vez es la excepción, no la regla.
fuente