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 solo branch_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, cuando git push
llama una rama building_groups
, su rama va primero origin/building_groups
y luego va al repositorio remoto. Del mismo modo, si hace una git fetch building_groups
, el archivo que se recupera se coloca en su origin/building_groups
rama. Luego puede optar por fusionar esta rama en su copia local. Nuestra práctica es hacer siempre una git fetch
fusión manual y una en lugar de solo una git 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 vez fetch
editado, se puede git branch --remote
enumerar las ramas de seguimiento y git 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 hace git checkout master
para cambiar a la master
rama, entonces git 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
de master
También es recomendable hacer una git 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 eso git pull
. Si ese es el caso (maestro cambiado), se le recomienda que lo haga git checkout your_branch
y luego rebase
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
y git 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):
# git
alias g='git status'
alias gcob='git checkout -b '
alias gcom='git checkout master'
alias gd='git diff'
alias gf='git fetch'
alias gfrm='git fetch; git reset --hard origin/master'
alias gg='git grep '
alias gits='alias | grep "^alias g.*git.*$"'
alias gl='git log'
alias gl1='git log --oneline'
alias glf='git log --name-status'
alias glp='git log -p'
alias gpull='git pull '
alias gpush='git push '
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:
[alias]
co = checkout
cob = checkout -b
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!
git reset [filename(s)]
git checkout -b [name_for_a_new_branch]
git add [file(s)]
git commit -m "A useful message"
Voila! You've moved that 'master' commit to its own branch !
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
:
git reset --hard origin/master # You will need to be comfortable doing this!
Empiezas a hacer cambios localmente, editas media docena de archivos y luego, oh mierda, todavía estás en la rama maestra (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
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:
git checkout your/directories/filename
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
o rebase
: 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 cambios
Estás rebatiendo pero las cosas se complican:
git rebase --abort # To abandon interactive rebase and merge issues
Agregue su rama Git a su PS1
solicitud (consulte https://unix.stackexchange.com/a/127800/10043 ), por ejemplo
La rama es selenium_rspec_conversion
.