git branch, fork, fetch, merge, rebase y clone, ¿cuáles son las diferencias?

¿Alguien puede ayudarme a entender la diferencia entre una twig, un tenedor y un clon en Git?

Del mismo modo, ¿qué significa cuando hago una git fetch en lugar de un git pull ?

Además, ¿qué significa rebase en comparación con merge ?

¿Cómo puedo aplastar compromisos individuales juntos?

¿Cómo se usan, por qué se usan y qué representan?

¿Cómo figura GitHub?

Un clon es simplemente una copy de un repository. En la superficie, su resultado es equivalente a svn checkout , donde se descarga el código fuente de algún otro repository. La diferencia entre VCS centralizado como Subversion y DVCS como Git es que en Git, cuando clonas, en realidad estás copyndo todo el repository fuente, incluyendo todo el historial y las twigs. Ahora tiene un nuevo repository en su máquina y cualquier compromiso que realice ingrese en ese repository. Nadie verá ningún cambio hasta que envíe esos commits a otro repository (o al original) o hasta que alguien extraiga commits de su repository, si es accesible públicamente.

Una twig es algo que está dentro de un repository. Conceptualmente, representa un hilo de desarrollo. Por lo general, tiene una twig principal, pero también puede tener una twig en la que esté trabajando en alguna function xyz, y otra para reparar el error abc. Cuando haya comprobado una twig, cualquier confirmación que realice se mantendrá en esa twig y no se compartirá con otras twigs hasta que las combine o vuelva a establecer una base en la sucursal en cuestión. Por supuesto, Git parece un poco raro cuando se trata de sucursales hasta que se mira el model subyacente de cómo se implementan las sucursales. En lugar de explicarlo yo mismo (ya he dicho demasiado, creo), me vincularé a la explicación de "informática" sobre cómo Git modela las ramificaciones y los compromisos, tomado del website de Git:

http://eagain.net/articles/git-for-computer-scientists/

Un tenedor no es un concepto de Git realmente, 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 copy "maestra" del código fuente, por lo que es tan simple como cortar loops con los desarrolladores originales del proyecto y no requiere exportar el historial desde un repository compartido como podría tener que ver con SVN .

EDITAR: dado que no estaba al tanto de la definición moderna de "fork" utilizada por sitios como GitHub, eche un vistazo a los comentarios y también la respuesta de Michael Durrant debajo de la mía para get más información.

Git

Mi respuesta incluye github, como mucha gente también ha preguntado sobre eso.

Repositorios locales

git (localmente) tiene un directory (.git) en el que usted confía sus files y este es su 'repository local'. Esto es diferente de sistemas como svn donde agrega y se compromete con el repository remoto inmediatamente.

git almacena cada versión de un file que cambia guardando el file completo. También es diferente de svn a este respecto, ya que podría ir a cualquier versión individual sin "recrearla" a través de cambios delta.

git no 'bloquea' files en absoluto y por lo tanto evita la funcionalidad de 'locking exclusivo' para una edición (los sistemas más antiguos como los pvcs vienen a la mente), por lo que todos los files pueden editarse siempre, incluso fuera de línea. En realidad, hace un trabajo increíble al fusionar los cambios de files (dentro del mismo file!) Durante los pull o fetches / push a un repository remoto como github. La única vez que necesita hacer cambios manuales (en realidad editando un file) es si dos cambios involucran la misma (s) línea (s) de código.


Sucursales

Las twigs le permiten conservar el código principal (la twig 'principal'), hacer una copy (una nueva twig) y luego trabajar dentro de esa nueva twig. Si el trabajo lleva un time o el maestro recibe muchas actualizaciones desde que se realizó la sucursal, se debe realizar la fusión o el rebase (a menudo preferido para un mejor historial y para resolver conflictos más fácilmente) contra la twig maestra. Cuando haya terminado, fusionará los cambios realizados en la twig nuevamente en el repository principal. Muchas organizaciones usan twigs para cada pieza de trabajo, ya sea una característica, un error o un elemento de tarea. Otras organizaciones solo usan sucursales para realizar cambios importantes, como actualizaciones de versiones. Tenedor: con una sucursal, usted controla y administra la sucursal, mientras que con un tenedor, alguien más controla aceptar el código nuevamente.
En términos generales, hay dos enfoques principales para hacer sucursales. El primero es mantener la mayoría de los cambios en la twig maestra, usando únicamente twigs para cosas más grandes y de ejecución más larga, como cambios de versión en los que desea tener dos twigs disponibles para diferentes necesidades. El segundo es por el cual básicamente hace una twig para cada request de function, corrección de error o tarea y luego decide manualmente cuándo fusionar esas twigs en la twig principal principal. Aunque esto suena tedioso, este es un enfoque común y es el que actualmente uso y recomiendo porque esto mantiene la twig principal más limpia y es el máster 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 twigs.

La forma estándar de llevar una twig "en" al maestro es hacer una merge . Las twigs también pueden ser rebase d para 'limpiar' el historial. No afecta el estado actual y se hace para brindar un historial 'más limpio'. Básicamente, la idea es que se ramificó desde un cierto punto (generalmente desde el maestro). Desde que ramificó 'maestro' en sí mismo ha avanzado. Por lo tanto, sería más claro si todos los cambios que ha realizado en una twig se juegan contra el más reciente maestro con todos sus cambios. Entonces el process es: save los cambios; get el "nuevo" maestro, y luego volver a aplicar los cambios nuevamente contra eso. Tenga en count que rebase, al igual que fusionar, puede generar conflictos que debe resolver manualmente (editar).

Una 'guía' a tener en count: ¡ solo rebase si la twig es local y aún no la ha alejado! Esto se debe principalmente a que el rebase puede alterar la historia que otras personas ven y que puede include sus propios commits.

Seguimiento de sucursales

Estas son las twigs que se denominan origen / nombre_twig (a diferencia de simplemente nombre_twig). Cuando está presionando y tirando del código hacia / desde repositorys remotos, este es en realidad el mecanismo a través del cual eso sucede. Por ejemplo, cuando git push una twig llamada 'building_groups', su twig va primero a origin / building_groups y luego va al repository remoto (en realidad eso es una simplificación excesiva pero lo suficientemente buena por ahora). De forma similar, si haces una git fetch building_groups el file que se recupera se coloca en tu twig de origen / building_groups. A continuación, puede elegir fusionar esta twig en su copy local. Nuestra práctica es hacer siempre una búsqueda de git y una combinación manual en lugar de solo un git pull (que hace las dos cosas anteriores en un solo paso).

Fetch nuevas twigs.

Obteniendo nuevas sucursales: en el punto inicial de un clon tendrás todas las twigs. Sin embargo, si otros desarrolladores agregan twigs y las empujan al control remoto, debe haber una forma de 'saber' sobre esas twigs y sus nombres para poder desplegarlas localmente. Esto se hace a través de una git fetch que obtendrá todas las twigs nuevas y cambiadas en el repository local utilizando las twigs de seguimiento (por ejemplo, origen /). Una vez que se git branch --remote , se puede fetch una git branch --remote para enumerar las twigs de seguimiento y git checkout [branch] para cambiar realmente a una dada.

Fusión

Fusionar es el process de combinar cambios de código de diferentes twigs, o de diferentes versiones de la misma twig (por ejemplo, cuando una twig local y un control remoto no están sincronizados). Si uno ha desarrollado el trabajo en una sucursal y el trabajo está completo, listo y probado, puede fusionarse en la sucursal master . Esto se hace por git checkout master para cambiar a la twig master , luego git merge your_branch . La combinación traerá todos los diferentes files e incluso diferentes cambios a los mismos files juntos. Esto significa que realmente cambiará el código dentro de los files para fusionar todos los cambios. Al hacer el checkout de master también se recomienda hacer un git pull origin master para get la última versión del master remoto fusionado en su master local. Si el maestro remoto cambió, es decir, se moved forward , verá información que refleja eso durante ese git pull . Si ese es el caso (maestro cambiado), se recomienda que git checkout your_branch y que luego lo rebase para que los cambios se rebase a reproducir en la parte superior del "nuevo" maestro. Luego, continuaría con la actualización de maestros, como se muestra en el párrafo siguiente.

Si no hay conflictos, el maestro tendrá los nuevos cambios agregados. Si hay conflictos, esto significa que los mismos files tienen cambios en torno a líneas de código similares que no se pueden fusionar automáticamente. En este caso, git merge new_branch informará que hay conflictos para resolver. Los "resuelve" editando los files (que tendrán ambos cambios en ellos), seleccionando los cambios que desea, literalmente borrando las líneas de los cambios que no desea y luego guardando el file. Los cambios están marcados con separadores como ======== y <<<<<<<<

Una vez que hayas resuelto cualquier conflicto, una vez más se git add y se git commit esos cambios para continuar la fusión (recibirás comentarios de git durante este process para guiarte). Cuando el process no funciona bien, encontrarás que git merge --abort es muy útil para reiniciar cosas.

Reasignación interactiva y aplastamiento / reorderamiento / eliminación de confirmaciones

Si ha realizado el trabajo en muchos pequeños pasos, por ejemplo, ha confirmado el código como 'trabajo en curso' todos los días, puede querer "aplastar" esas pequeñas confirmaciones en unas cuantas confirmaciones más grandes. Esto puede ser particularmente útil cuando quiere hacer revisiones de código con colegas. No quiere repetir todos los 'pasos' que tomó (a través de compromisos), solo quiere decir que aquí está el efecto final (diff) de todos mis cambios para este trabajo en una confirmación. El factor key que se debe evaluar al considerar si hacer esto es si las múltiples confirmaciones están en contra del mismo file o files más de una vez (es mejor aplastar las confirmaciones en ese caso). Esto se hace con la herramienta de rebase interactiva. Esta herramienta le permite comprimir confirmaciones, eliminar confirmaciones, modificar posts, etc. Por ejemplo, git rebase -i HEAD~10 Tenga en count que es un ~ NO a - muestra lo siguiente:
reajuste interactivo en Git Sin embargo, tenga cuidado y use esta herramienta 'cautelosamente'. Haga una acción squash / delete / reorder a la vez, salga y guarde esa confirmación, luego vuelva a ingresar a la herramienta. Si los commits no son contiguos, puede reorderarlos (y luego aplastarlos según sea necesario). En este caso, también puedes eliminar confirmaciones, ¡pero realmente necesitas estar seguro de lo que estás haciendo cuando lo haces!

tenedores

Hay dos enfoques principales para la queueboración en repositorys git. El primero, detallado anteriormente, se realiza directamente a través de las sucursales que las personas extraen y empujan desde / hacia. Estos queueboradores tienen sus keys ssh registradas en el repository remoto. Esto les permitirá ingresar directamente a ese repository. La desventaja es que debe mantener la list de usuarios. El otro enfoque, el de bifurcación, permite a cualquiera "copyr" el repository, básicamente haciendo una copy local en su propia count de repository git. Luego pueden hacer cambios y cuando terminen, envíen una 'request de extracción' (realmente es más un "empujón" de ellos y una request de "extracción" para el mantenedor real del depósito) para que se acepte el código.
Este segundo método, utilizando horquillas, no requiere que alguien mantenga una list de usuarios para el repository.


Github

github (un repository remoto) es una fuente remota que normalmente empuja y extrae de esos cambios comprometidos si tiene (o se agrega) tal repository, por lo tanto, local y remoto son bastante distintos. Otra forma de pensar en un repository remoto es que es una estructura de directory .git que vive en un server remoto.

Cuando 'fork' – en la guía del browser web github, puede hacer clic en enter image description here – creas una copy ('clon') del código en tu count github. Puede ser un poco sutil la primera vez que lo haces, así que sigue asegurándote de ver en qué repository se encuentra una base de código, ya sea del propietario original o 'ahorrado' y de ti, por ejemplo. enter image description here
Una vez que tenga la copy local, puede hacer los cambios que desee (tirando de ellos y empujándolos a una máquina local). Cuando hayas terminado, envías una "request de extracción" al propietario / administrador del repository original (aunque suena elegante, simplemente haces clic en esto: – enter image description here ) y lo "jalan".
Más común para un equipo que trabaja en código en set es 'clonar' el repository (click el icono 'copyr' en la pantalla principal del repository). Luego, localmente escriba git clone [paste] Esto lo configurará localmente y también puede presionar y jalar a la location github (compartida).

Clones

Como se indica en la sección sobre github, un clon es una copy de un repository. Cuando tiene un repository remoto, emite el command git clone contra su URL y luego termina con una copy local, o clona el repository. Este clon tiene todo , los files, la twig principal, las otras twigs, todos los commits existentes, todo el shebang. Es esta clonación la que realiza sus agregaciones y confirmaciones y luego el repository remoto en sí es a lo que obliga a comprometerse. Es este concepto local / remoto el que hace que git (y sistemas similares a él como Mercurial) sea un DVCS (Sistema de control de versiones distribuidas ) en comparación con los CVS más tradicionales (Sistemas de control de versiones de códigos) como SVN, PVCS, CVS, etc. te comprometes directamente con el repository 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 quieres una visualización de cómo funcionan los cambios, no puedes vencer a la herramienta visual gitg (gitx para mac) con una interfaz gráfica que llamo 'el map del metro' (especialmente el metro de Londres), excelente para mostrar quién hizo qué, cómo cambian las cosas, divergieron y se fusionaron, etc.

¡También puede usarlo para agregar, comprometer y administrar sus cambios!

interfaz gitg / gitx

Aunque gitg / gitx es bastante mínimo, en los últimos 2-3 años (2009-2012) la cantidad de herramientas GUI continúa expandiéndose. Muchos usuarios de Mac usan fork de gitx de brotherbard y para Linux una gran opción es smart-git con una interfaz intuitiva pero potente:

interfaz gráfica de usuario de smart-git

Tenga en count que incluso con una herramienta de interfaz gráfica de usuario, probablemente hará una gran cantidad de commands en la command-line.
Para esto tengo los siguientes alias en mi file ~ / .bash_aliases (que se llama desde mi file ~ / .bashrc para cada session de terminal:

 # git alias gst='git status' # Warning: gst conflicts with gnu-smalltalk (when used). alias gb='git branch' alias gco='git checkout' alias gcob='git checkout -b ' alias ga='git add ' alias gc='git commit' alias gg='git grep ' # A great very FAST search option, easier then `find` 

Finalmente, 6 salvavidas key:

1) Echas a perder tu sucursal local y simplemente quieres volver a lo que tuviste la última vez que hiciste un truco:

 git reset --hard origin/master # You will need to be comfortable doing this! 

2) Empiezas a hacer cambios localmente, editas media docena de files y luego, oh mierda, sigues en la twig principal (u otra):

 git checkout -b new_branch_name # just create a new branch git add . # add the changes files git commit -m"your message" # and commit them 

3) Usted arruina un file en particular en su twig actual y básicamente quiere 'reiniciar' ese file (perder cambios) a cómo fue la última vez que lo sacó del repository remoto: git checkout your/directories/filename Esto en realidad restablece el file (al igual que muchos commands de git, no está bien nombrado para lo que está haciendo aquí).

4) Realizas algunos cambios localmente, quieres asegurarte de no perderlos mientras realizas un git reset o rebase: a menudo realizo una copy manual de todo el proyecto ( cp -r ../my_project ~/ ) cuando No estoy seguro de si podría estropearme en git o perder cambios importantes.

5) Estás reajustando pero las cosas se arruinan:

 git rebase --abort # To abandon interactive rebase and merge issues 

6) Agregue su twig git a su request de PS1 (consulte https://unix.stackexchange.com/a/127800/10043 ), por ejemplo enter image description here
La twig es selenium_rspec_conversion

Aquí está la image de Oliver Steele de cómo encaja todo:

enter image description here

Solo para agregar a los demás, una nota específica para bifurcar.

Es bueno darse count de que técnicamente, clonar el repository y bifurcar el repository son la misma cosa. Hacer:

 git clone $some_other_repo 

y puedes darte un golpecito en la parte de atrás — acabas de abrir otro repo.

Git, como un VCS, de hecho es todo acerca de la bifurcación de clonación . Además de "solo navegar" usando UI remota como cgit, hay muy poco que ver con git repo que no implique clonar el repos en ningún momento.

Sin embargo,

  • cuando alguien dice que he ahorrado repo X , quieren decir que han creado un clon del repository en otro lugar con la intención de exponerlo a otros, por ejemplo, para mostrar algunos experimentos o para aplicar diferentes mecanismos de control de acceso (por ejemplo, para permitir que personas sin Acceso Github pero con la count interna de la compañía para queueborar).

    Hechos que: el repository es probablemente creado con otro command que git clone , que probablemente esté alojado en algún server y no en el portátil de alguien, y muy probablemente tenga un formatting ligeramente diferente (es un "repository vacío", es decir, sin funcionamiento) tree) son solo detalles técnicos.

    El hecho de que probablemente contenga un set diferente de twigs, tags o confirmaciones es probablemente la razón por la que lo hicieron en primer lugar.

    (Lo que hace Github cuando haces clic en "fork", es clonar con azúcar añadido: clona el repository, lo coloca debajo de tu count, registra el "bifurcado" en alguna parte, agrega el nombre remoto "ascendente", y lo más importante, juega la bonita animation.)

  • Cuando alguien dice que cloné repo X , quieren decir que han creado un clon del repository localmente en su computadora portátil o computadora de escritorio con la intención de estudiarlo, jugar con él, contribuir a él o crear algo a partir del código fuente.

La belleza de Git es que hace que todo encaje perfectamente: todos estos repos comparten la parte común de la cadena de compromiso de bloques , por lo que es posible (de forma segura) ver los cambios entre todos estos repositorys como mejor les parezca.


Nota: "con security", siempre y cuando no reescriba la parte común de la cadena, y siempre que los cambios no sean conflictivos.

Tenedor vs. Clon: dos palabras que significan copyr

Por favor mira este diagtwig. (Originalmente de http://www.dataschool.io/content/images/2014/Mar/github1.png ).

Tenedor

  • Una copy para su repository remoto (nube) que lo vincula a Joe
  • Una copy que luego puede clonar en su repository local y F *% $ – hasta
  • Cuando haya terminado, puede retroceder a su control remoto
  • Luego, puede preguntarle a Joe si desea usarlo en su proyecto haciendo clic en "solicitar request".

Clon

  • una copy a su repository local (disco duro)