¿Quiero entender la diferencia entre una rama, una bifurcación y un clon en Git?
Del mismo modo, ¿qué significa cuando hago un git fetch
en lugar de un git pull
?
Además, ¿qué rebase
significa en comparación con merge
?
¿Cómo puedo aplastar los compromisos individuales juntos?
¿Cómo se usan, por qué se usan y qué representan?
¿Cómo figura GitHub?
Respuestas:
Un clon es simplemente una copia de un repositorio. En la superficie, su resultado es equivalente a
svn checkout
, donde descargas el código fuente de algún otro repositorio. La diferencia entre VCS centralizado como Subversion y DVCS como Git es que en Git, cuando clonas, en realidad estás copiando todo el repositorio de origen, incluido todo el historial y las ramas. Ahora tiene un nuevo repositorio en su máquina y cualquier confirmación que realice irá a ese repositorio. Nadie verá ningún cambio hasta que envíe esas confirmaciones a otro repositorio (o al original) o hasta que alguien extraiga las confirmaciones de su repositorio, si es de acceso público.Una rama es algo que está dentro de un repositorio. Conceptualmente, representa un hilo de desarrollo. Por lo general, tiene una rama maestra, pero también puede tener una rama en la que está trabajando en alguna característica xyz, y otra para corregir errores abc. Cuando haya desprotegido una rama, las confirmaciones que realice permanecerán en esa rama y no se compartirán con otras ramas hasta que las combine o las rebase en la rama en cuestión. Por supuesto, Git parece un poco extraño cuando se trata de ramas hasta que observas el modelo subyacente de cómo se implementan las ramas. En lugar de explicarlo yo mismo (ya he dicho demasiado, creo), enlazaré con la explicación "informática" de cómo Git modela ramas y se compromete, tomada del sitio web de Git:
http://eagain.net/articles/git-for-computer-scientists/
Una bifurcación no es realmente un concepto Git, es más una idea política / social. Es decir, si algunas personas no están contentas con la forma en que se desarrolla un proyecto, pueden tomar el código fuente y trabajar en él por separado de los desarrolladores originales. Eso se consideraría un tenedor. Git facilita la bifurcación porque todos ya tienen su propia copia "maestra" del código fuente, por lo que es tan simple como cortar los lazos con los desarrolladores del proyecto original y no requiere exportar el historial desde un repositorio compartido como podría tener que ver con SVN .
EDITAR: dado que no estaba al tanto de la definición moderna de "fork" como la usan sitios como GitHub, por favor, eche un vistazo a los comentarios y también a la respuesta de Michael Durrant debajo de la mía para obtener más información.
fuente
Git
Esta respuesta incluye GitHub ya que muchas personas también han preguntado sobre eso.
Repositorios locales
Git (localmente) tiene un directorio (
.git
) al que compromete sus archivos y este es su 'repositorio local'. Esto es diferente de los sistemas como SVN donde agrega y se compromete al repositorio remoto de inmediato.Git almacena cada versión de un archivo que cambia guardando todo el archivo. También es diferente de SVN a este respecto, ya que podría acceder a cualquier versión individual sin 'recrearla' a través de cambios delta.
Git no 'bloquea' archivos en absoluto y, por lo tanto, evita la funcionalidad 'bloqueo exclusivo' para una edición (los sistemas más antiguos como pvcs vienen a la mente), por lo que todos los archivos siempre se pueden editar, incluso cuando están fuera de línea. En realidad, hace un trabajo increíble al fusionar los cambios de archivos (¡dentro del mismo archivo!) Juntos durante las extracciones o recuperaciones / empujes a un repositorio remoto como GitHub. La única vez que necesita hacer cambios manuales (en realidad editando un archivo) es si dos cambios involucran las mismas líneas de código.
Ramas
Las ramas le permiten conservar el código principal (la rama 'maestra'), hacer una copia (una nueva rama) y luego trabajar dentro de esa nueva rama. Si el trabajo lleva un tiempo o el maestro recibe muchas actualizaciones desde que se realizó la bifurcación, se debe hacer una fusión o rebase (a menudo preferido para un mejor historial y conflictos más fáciles de resolver) contra la bifurcación maestra. Cuando haya terminado, fusionará los cambios realizados en la rama nuevamente en el repositorio maestro. Muchas organizaciones usan ramas para cada trabajo, ya sea un elemento de función, error o tarea. Otras organizaciones solo usan sucursales para cambios importantes, como actualizaciones de versión.
Bifurcación: con una bifurcación usted controla y administra la bifurcación, mientras que con una bifurcación alguien más controla la aceptación del código nuevamente.
En términos generales, hay dos enfoques principales para hacer ramas. El primero es mantener la mayoría de los cambios en la rama maestra, solo usando ramas para cosas más grandes y de mayor duración, como cambios de versión, donde desea tener dos ramas disponibles para diferentes necesidades. El segundo es mediante el cual básicamente se hace una rama para cada solicitud de función, corrección de errores o tarea y luego se decide manualmente cuándo fusionar esas ramas en la rama maestra principal. Aunque esto suena tedioso, este es un enfoque común y es el que uso y recomiendo actualmente porque esto mantiene la rama maestra más limpia y es la maestra que promovemos a la producción, por lo que solo queremos un código completo y probado, a través del rebase y fusión de ramas.
La forma estándar de traer una rama 'en' al maestro es hacer a
merge
. Las ramas también se pueden "rebasear" para "limpiar" el historial. No afecta el estado actual y se hace para dar un historial 'más limpio'.Básicamente, la idea es que te ramifiques desde cierto punto (generalmente desde el maestro). Desde que se bifurcó, 'master' se ha movido desde ese punto de bifurcación. Será 'más limpio' (más fácil de resolver problemas y el historial será más fácil de entender) si todos los cambios que ha realizado en una rama se juegan contra el estado actual del maestro con todos sus últimos cambios. Entonces, el proceso es: guardar los cambios; obtenga el 'nuevo' maestro, y luego vuelva a aplicar (esta es la parte de rebase) los cambios nuevamente contra eso. Tenga en cuenta que el rebase, al igual que la fusión, puede generar conflictos que debe resolver manualmente (es decir, editar y corregir).
Una pauta a tener en cuenta: ¡
Solo vuelva a crear un rebase si la sucursal es local y aún no la ha colocado en remota!
Esto se debe principalmente a que el rebase puede alterar la historia que otras personas ven y que puede incluir sus propios compromisos.
Rastreo de ramas
Estas son las ramas que se nombran
origin/branch_name
(en lugar de solobranch_name
). Cuando empuja y tira el código hacia / desde repositorios remotos, este es realmente el mecanismo a través del cual eso sucede. Por ejemplo, cuandogit push
llama una ramabuilding_groups
, su rama va primeroorigin/building_groups
y luego va al repositorio remoto. Del mismo modo, si hace unagit fetch building_groups
, el archivo que se recupera se coloca en suorigin/building_groups
rama. Luego puede optar por fusionar esta rama en su copia local. Nuestra práctica es hacer siempre unagit fetch
fusión manual y una en lugar de solo unagit pull
(que hace las dos cosas anteriores en un solo paso).Obteniendo nuevas ramas.
Obtención de nuevas ramas: en el punto inicial de un clon tendrá todas las ramas. Sin embargo, si otros desarrolladores agregan ramas y las envían al control remoto, debe haber una manera de 'saber' sobre esas ramas y sus nombres para poder desplegarlas localmente. Esto se realiza a través de una
git fetch
que llevará todas las ramas nuevas y modificadas al repositorio local utilizando las ramas de seguimiento (por ejemplo,origin/
). Una vezfetch
editado, se puedegit branch --remote
enumerar las ramas de seguimiento ygit checkout [branch]
cambiar a una determinada.Fusionando
La fusión es el proceso de combinar cambios de código de diferentes ramas, o de diferentes versiones de la misma rama (por ejemplo, cuando una rama local y remota no están sincronizadas). Si uno ha desarrollado trabajo en una rama y el trabajo está completo, listo y probado, entonces puede fusionarse en la
master
rama. Esto se hacegit checkout master
para cambiar a lamaster
rama, entoncesgit merge your_branch
. La fusión traerá todos los diferentes archivos e incluso diferentes cambios a los mismos archivos juntos. Esto significa que en realidad cambiará el código dentro de los archivos para fusionar todos los cambios.Al hacer la
checkout
demaster
También es recomendable hacer unagit pull origin master
para obtener la última versión de la maestra remota fusionado en su maestro local. Si el maestro remoto cambió, es decir,moved forward
verá información que refleje eso durante esogit pull
. Si ese es el caso (maestro cambiado), se le recomienda que lo hagagit checkout your_branch
y luegorebase
lo haga para que sus cambios se "reproduzcan" en la parte superior del "nuevo" maestro. Luego continuaría con la actualización del master como se muestra en el siguiente párrafo.Si no hay conflictos, el maestro tendrá los nuevos cambios agregados. Si hay conflictos, esto significa que los mismos archivos tienen cambios alrededor de líneas de código similares que no se pueden combinar automáticamente. En este caso
git merge new_branch
informará que hay conflictos que resolver. Los 'resuelve' editando los archivos (que tendrán ambos cambios), seleccionando los cambios que desea, literalmente eliminando las líneas de los cambios que no desea y luego guardando el archivo. Los cambios están marcados con separadores como========
y<<<<<<<<
.Una vez que haya resuelto cualquier conflicto que, una vez más
git add
ygit commit
esos cambios para continuar la fusión (que obtendrá retroalimentación de git durante este proceso para guiarle).Cuando el proceso no funciona bien, encontrará que
git merge --abort
es muy útil para restablecer las cosas.Rebajas interactivas y aplastamiento / reordenamiento / eliminación de confirmaciones
Si ha trabajado en muchos pasos pequeños, por ejemplo, confirma el código como "trabajo en progreso" todos los días, es posible que desee "aplastar" esas pequeñas confirmaciones en unas pocas confirmaciones más grandes. Esto puede ser particularmente útil cuando desea hacer revisiones de código con colegas. No desea volver a reproducir todos los 'pasos' que realizó (a través de commits), solo quiere decir que aquí está el efecto final (diff) de todos mis cambios para este trabajo en un commit.
El factor clave a evaluar cuando se considera si hacer esto es si las confirmaciones múltiples están en contra del mismo archivo o archivos más de una vez (mejor aplastar las confirmaciones en ese caso). Esto se hace con la herramienta interactiva de rebase. Esta herramienta le permite aplastar confirmaciones, eliminar confirmaciones, reformular mensajes, etc. Por ejemplo,
git rebase -i HEAD~10
( nota: eso es~
, no a-
) muestra lo siguiente:Sin embargo, tenga cuidado y use esta herramienta "con cautela". Haga un squash / delete / reordenar a la vez, salga y guarde ese commit, luego vuelva a ingresar la herramienta. Si las confirmaciones no son contiguas, puede reordenarlas (y luego eliminarlas según sea necesario). En realidad, también puede eliminar confirmaciones aquí, ¡pero realmente necesita estar seguro de lo que está haciendo cuando hace eso!
tenedores
Hay dos enfoques principales para la colaboración en repositorios de Git. El primero, detallado anteriormente, es directamente a través de ramas que la gente tira y empuja desde / hacia. Estos colaboradores tienen sus claves SSH registradas con el repositorio remoto. Esto les permitirá empujar directamente a ese repositorio. La desventaja es que debe mantener la lista de usuarios. El otro enfoque, la bifurcación, permite a cualquiera 'bifurcar' el repositorio, básicamente haciendo una copia local en su propia cuenta de repositorio Git. Luego pueden hacer cambios y, cuando terminen, enviar una 'solicitud de extracción' (en realidad es más una 'inserción' de ellos y una solicitud de 'extracción' para el responsable del repositorio real) para que se acepte el código.
Este segundo método, el uso de horquillas, no requiere que alguien mantenga una lista de usuarios para el repositorio.
GitHub
GitHub (un repositorio remoto) es una fuente remota a la que normalmente empuja y extrae esos cambios confirmados si tiene (o se agrega) a dicho repositorio, por lo que local y remoto son realmente bastante distintos. Otra forma de pensar en un repositorio remoto es que es una
.git
estructura de directorio que vive en un servidor remoto.Cuando 'bifurca' - en la GUI del navegador web de GitHub puedes hacer clic en este botón - creas una copia ('clonar') del código en tu cuenta de GitHub. Puede ser un poco sutil la primera vez que lo haces, así que asegúrate de mirar en qué repositorio se enumera una base de código, ya sea el propietario original o 'bifurcado' y tú, por ejemplo, así:
Una vez que tenga la copia local, puede hacer los cambios que desee (tirando y empujándolos a una máquina local). Cuando termine, envíe una 'solicitud de extracción' al propietario / administrador del repositorio original (suena elegante, pero en realidad solo hace clic en esto:) y lo 'extraen'.
Más común para un equipo que trabaja en código juntos es 'clonar' el repositorio (haga clic en el icono 'copiar' en la pantalla principal del repositorio). Luego, escriba
git clone
y pegue localmente . Esto lo configurará localmente y también puede empujar y tirar a la ubicación (compartida) de GitHub.Clones
Como se indica en la sección de GitHub, un clon es una copia de un repositorio. Cuando tiene un repositorio remoto, emite el
git clone
comando contra su URL y luego termina con una copia local, o clon, del repositorio. Este clon tiene todo , los archivos, la rama maestra, las otras ramas, todos los commits existentes, todo el shebang. Es a este clon con el que hace sus adiciones y confirmaciones y luego el repositorio remoto es a lo que empuja esas confirmaciones. Es este concepto local / remoto lo que hace que Git (y sistemas similares a él, como Mercurial), sea un DVCS ( Sistema de control de versiones distribuido ) en lugar de los CVS (sistemas de control de versiones de código) más tradicionales, como SVN, PVCS, CVS, etc., donde usted se compromete directamente con el repositorio remoto.Visualización
La visualización de los conceptos básicos se puede ver en
http://marklodato.github.com/visual-git-guide/index-en.html y
http://ndpsoftware.com/git-cheatsheet.html#loc=index
Si desea una visualización de cómo funcionan los cambios, no puede superar la herramienta visual
gitg
(gitx
para macOS) con una GUI que llamo 'el mapa del metro' (especialmente London Underground), ideal para mostrar quién hizo qué, cómo cambian las cosas, divergen y se fusionan, etc.¡También puede usarlo para agregar, confirmar y administrar sus cambios!
Aunque gitg / gitx es bastante mínimo, la cantidad de herramientas GUI continúa expandiéndose. Muchos usuarios de Mac usan la bifurcación de gitx de brotherbard y para Linux, una gran opción es smart-git con una interfaz intuitiva pero potente:
Tenga en cuenta que incluso con una herramienta GUI, probablemente ejecutará muchos comandos en la línea de comandos.
Para esto, tengo los siguientes alias en mi
~/.bash_aliases
archivo (que se llama desde mi~/.bashrc
archivo para cada sesión de terminal):Y tengo los siguientes "alias git" en mi
~/.gitconfig
archivo: ¿por qué tenerlos?¡Para que la finalización de la rama (con la tecla TAB) funcione!
Entonces estos son:
Ejemplo de uso:
git co [branch]
<- completar la pestaña para las ramas funcionará.Herramienta de aprendizaje GUI
Puede encontrar https://learngitbranching.js.org/ útil para aprender algunos de los conceptos básicos. Captura de pantalla: Video: https://youtu.be/23JqqcLPss0
¡Finalmente, 7 salvavidas clave!
Haces cambios, los agregas y los confirmas (pero no presionas) y luego ¡oh! te das cuenta de que estás en el maestro!
Desordena algunos archivos mientras trabaja en una sucursal local y simplemente quiere volver a lo que tenía la última vez que hizo un
git pull
:Empiezas a hacer cambios localmente, editas media docena de archivos y luego, oh mierda, todavía estás en la rama maestra (u otra):
Arruina un archivo en particular en su rama actual y básicamente quiere 'restablecer' ese archivo (perder cambios) como estaba la última vez que lo sacó del repositorio remoto:
En realidad, esto restablece el archivo (como muchos comandos de Git, no está bien nombrado por lo que está haciendo aquí).
Realiza algunos cambios localmente, desea asegurarse de no perderlos mientras realiza una
git reset
orebase
: a menudo hago una copia manual de todo el proyecto (cp -r ../my_project ~/
) cuando no estoy seguro de si podría estropear Git o perder importantes cambiosEstás rebatiendo pero las cosas se complican:
Agregue su rama Git a su
PS1
solicitud (consulte https://unix.stackexchange.com/a/127800/10043 ), por ejemploLa rama es
selenium_rspec_conversion
.fuente
Aquí está la imagen de Oliver Steele de cómo encaja todo:
fuente
Tenedor vs. Clon: dos palabras que significan copia
Por favor vea este diagrama. (Originalmente de http://www.dataschool.io/content/images/2014/Mar/github1.png ).
Tenedor
Clon
fuente
anidea
directamente a su repositorio y ahorrarle las tareas de mantener su tenedor actualizado. OTOH, si no logra llegar a un acuerdo con Joe, podría seguir desarrollando y utilizando su tenedor (y ver si puede hacer que cambie de opinión más adelante).Solo para agregar a otros, una nota específica para bifurcar.
Es bueno darse cuenta de que técnicamente, clonar el repositorio y bifurcar el repositorio es lo mismo. Hacer:
y puedes tocarte en la espalda --- acabas de bifurcar otro repositorio.
Git, como VCS, de hecho se trata de bifurcación de
clonación. Además de "simplemente navegar" usando la IU remota como cgit, hay muy poco que ver con el repositorio de git que no implicabifurcar laclonación del repositorio en algún momento.Sin embargo,
cuando alguien dice que bifurqué el repositorio X , significan que han creado un clon del repositorio en otro lugar con la intención de exponerlo a otros, por ejemplo, para mostrar algunos experimentos o para aplicar un mecanismo de control de acceso diferente (por ejemplo, para permitir que las personas sin Acceso a Github pero con cuenta interna de la empresa para colaborar).
Hechos que: el repositorio probablemente se crea con otro comando que
git clone
, probablemente esté alojado en algún lugar en un servidor en lugar de la computadora portátil de alguien, y lo más probable es que tenga un formato ligeramente diferente (es un "repositorio desnudo", es decir, sin árbol de trabajo) son todos solo detalles técnicos.El hecho de que probablemente contendrá diferentes conjuntos de ramas, etiquetas o confirmaciones es probablemente la razón por la que lo hicieron en primer lugar.
(Lo que hace Github cuando hace clic en "tenedor", es simplemente clonar con azúcar agregada: clona el repositorio por usted, lo coloca en su cuenta, registra el "bifurcado de alguna parte", agrega el control remoto llamado "ascendente" y, lo más importante, reproduce la bonita animación)
Cuando alguien dice que cloné el repositorio X , significan que han creado un clon del repositorio localmente en su computadora portátil o de escritorio con la intención de estudiarlo, jugar con él, contribuir a él o construir algo a partir del código fuente.
La belleza de Git es que hace que todo encaje perfectamente: todos estos repositorios comparten la parte común de la cadena de confirmación de
bloque, por lo que es posible fusionar de forma segura (ver la nota a continuación) los cambios de un lado a otro entre todos estos repositorios como mejor le parezca.Nota: "con seguridad" siempre y cuando no reescriba la parte común de la cadena, y siempre que los cambios no sean conflictivos.
fuente