Git

Git
Información sobre la plantilla
Git-logo.svg.png
Git es un software de control de versiones, pensando en la eficiencia y la confiabilidad del mantenimiento de versiones de aplicaciones cuando éstas tienen un gran número de archivos de código fuente.
CreadorMatthew Ahrens y Jeff Bonwick.
DesarrolladorOracle (originalmente Sun Microsystems). Equipo de desarrollo de OpenZFS como fork.
Diseñado porLinus Torvalds
Versiones2.7.0
Última versión establePlantilla:Fecha de lanzamiento
Plataformas soportadasMicrosoft Windows, Linux
Sistemas Operativos compatiblesMicrosoft Windows, and Linux.
IdiomaIngles
LicenciaGNU GPL v2
Sitio web
http://git-scm.com/


Git es un sistema libre y de código abierto distribuido de control de versiones diseñado para manejar todo, desde pequeñas a proyectos muy grandes con rapidez y eficacia.

Git es fácil de aprender y tiene una pequeña huella con un rendimiento increíblemente rápido. Se supera a herramientas de SCM como Subversion, CVS, Perforce y ClearCase con características como barato ramificación locales, áreas de almacenamiento convenientes, y múltiples flujos de trabajo.

Historia de Git

Como muchas de las grandes cosas en esta vida, Git comenzó con un poco de destrucción creativa y encendida polémica. El núcleo de Linux es un proyecto de software de código abierto con un alcance bastante grande. Durante la mayor parte del mantenimiento del núcleo de Linux (1991-2002), los cambios en el software se pasaron en forma de parches y archivos. En 2002, el proyecto del núcleo de Linux empezó a usar un DVCS propietario llamado BitKeeper. En 2005, la relación entre la comunidad que desarrollaba el núcleo de Linux y la compañía que desarrollaba BitKeeper se vino abajo, y la herramienta dejó de ser ofrecida gratuitamente. Esto impulsó a la comunidad de desarrollo de Linux (y en particular a Linus Torvalds, el creador de Linux) a desarrollar su propia herramienta basada en algunas de las lecciones que aprendieron durante el uso de BitKeeper. Algunos de los objetivos del nuevo sistema fueron los siguientes: • Velocidad • Diseño sencillo • Fuerte apoyo al desarrollo no lineal (miles de ramas paralelas) • Completamente distribuido • Capaz de manejar grandes proyectos (como el núcleo de Linux) de manera eficiente (velocidad y tamaño de los datos) Desde su nacimiento en 2005, Git ha evolucionado y madurado para ser fácil de usar y aún conservar estas cualidades iniciales. Es tremendamente rápido, muy eficiente con grandes proyectos, y tiene un increíble sistema de ramificación (branching) para desarrollo no lineal.

Características

El diseño de Git se basó en BitKeeper y en Monotone.

El diseño de Git resulta de la experiencia del diseñador de Linux, Linus Torvalds, manteniendo una enorme cantidad de código distribuida y gestionada por mucha gente, que incide en numerosos detalles de rendimiento, y de la necesidad de rapidez en una primera implementación.

Entre las características más relevantes se encuentran:

  • Fuerte apoyo al desarrollo no lineal, por ende rapidez en la gestión de ramas y mezclado de diferentes versiones. Git incluye herramientas específicas para navegar y visualizar un historial de desarrollo no lineal. Una presunción fundamental en Git es que un cambio será fusionado mucho más frecuentemente de lo que se escribe originalmente, conforme se pasa entre varios programadores que lo revisan.
  • Gestión distribuida. Al igual que Darcs, BitKeeper, Mercurial, SVK, Bazaar y Monotone, Git le da a cada programador una copia local del historial del desarrollo entero, y los cambios se propagan entre los repositorios locales. Los cambios se importan como ramas adicionales y pueden ser fusionados en la misma manera que se hace con la rama local.
  • Los almacenes de información pueden publicarse por HTTP, FTP, rsync o mediante un protocolo nativo, ya sea a través de una conexión TCP/IP simple o a través de cifrado SSH. Git también puede emular servidores CVS, lo que habilita el uso de clientes CVS pre-existentes y módulos IDE para CVS pre-existentes en el acceso de repositorios Git.
  • Los repositorios Subversion y svk se pueden usar directamente con git-svn.
  • Gestión eficiente de proyectos grandes, dada la rapidez de gestión de diferencias entre archivos, entre otras mejoras de optimización de velocidad de ejecución.
  • Todas las versiones previas a un cambio determinado, implican la notificación de un cambio posterior en cualquiera de ellas a ese cambio (denominado autenticación criptográfica de historial). Esto existía en Monotone.
  • Resulta algo más caro trabajar con ficheros concretos frente a proyectos, eso diferencia el trabajo frente a CVS, que trabaja con base en cambios de fichero, pero mejora el trabajo con afectaciones de código que concurren en operaciones similares en varios archivos.
  • Los renombrados se trabajan basándose en similitudes entre ficheros, aparte de nombres de ficheros, pero no se hacen marcas explícitas de cambios de nombre con base en supuestos nombres únicos de nodos de sistema de ficheros, lo que evita posibles, y posiblemente desastrosas, coincidencias de ficheros diferentes en un único nombre.
  • Realmacenamiento periódico en paquetes (ficheros). Esto es relativamente eficiente para escritura de cambios y relativamente ineficiente para lectura si el reempaquetado (con base en diferencias) no ocurre cada cierto tiempo.

Estructura

Tu repositorio local esta compuesto por tres "árboles" administrados por git. El primero es tu Workspace que contiene los archivos, el segundo es el Index que actúa como una zona intermedia, y el último es el HEAD o Repository que apunta al último commit realizado. Git nos permite subir y bajar los cambios realizados, desde nuestro HEAD hacia un servidor remoto y viceversa.

Instalando Git

Vamos a empezar a usar un poco de Git. Lo primero es lo primero: tienes que instalarlo. Puedes obtenerlo de varias maneras; las dos principales son instalarlo desde código fuente, o instalar un paquete existente para tu plataforma.

Instalando desde código fuente

Si puedes, en general es útil instalar Git desde código fuente, porque obtendrás la versión más reciente. Cada versión de Git tiende a incluir útiles mejoras en la interfaz de usuario, por lo que utilizar la última versión es a menudo el camino más adecuado si te sientes cómodo compilando software desde código fuente. También ocurre que muchas distribuciones de Linux contienen paquetes muy antiguos; así que a menos que estés en una distribución muy actualizada o estés usando backports, instalar desde código fuente puede ser la mejor opción. Para instalar Git, necesitas tener las siguientes librerías de las que Git depende: curl, zlib, openssl, expat y libiconv. Por ejemplo, si estás en un sistema que tiene yum (como Fedora) o apt-get (como un sistema basado en Debian), puedes usar estos comandos para instalar todas las dependencias: $ yum install curl-devel expat-devel gettext-devel \

 openssl-devel zlib-devel

$ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext \

 libz-dev libssl-dev

Luego compila e instala: $ tar -zxf git-1.6.0.5.tar.gz $ cd git-1.6.0.5 $ make prefix=/usr/local all $ sudo make prefix=/usr/local install Una vez hecho esto, también puedes obtener Git, a través del propio Git, para futuras actualizaciones: $ git clone git://git.kernel.org/pub/scm/git/git.git

Instalando en Linux

Si quieres instalar Git en Linux a través de un instalador binario, en general puedes hacerlo a través de la herramienta básica de gestión de paquetes que trae tu distribución. Si estás en Fedora, puedes usar yum: $ yum install git-core O si estás en una distribución basada en Debian como Ubuntu, prueba con apt-get: $ apt-get install git

Instalando en Mac

Hay tres maneras fáciles de instalar Git en un Mac. La más sencilla es usar el instalador gráfico de Git, que puedes descargar desde la página de SourceForge. Una alternativa es instalar Git a través de MacPorts. Si tienes MacPorts instalado, instala Git con: $ sudo port install git-core +svn +doc +bash_completion +gitweb No necesitas añadir todos los extras, pero probablemente quieras incluir +svn en caso de que alguna vez necesites usar Git con repositorios Subversion (véase el Capítulo 8). La segunda alternativa es Homebrew. Si ya tienes instalado Homebrew, instala Git con: $ brew install git

Instalando en Windows

Instalar Git en Windows es muy fácil. El proyecto msysGit tiene uno de los procesos de instalación más sencillos. Simplemente descarga el archivo exe del instalador desde la página de GitHub, y ejecútalo: Una vez instalado, tendrás tanto la versión de línea de comandos (incluido un cliente SSH que nos será útil más adelante) como la interfaz gráfica de usuario estándar. Nota para el uso en Windows: Se debería usar Git con la shell provista por msysGit (estilo Unix), lo cual permite usar las complejas líneas de comandos de este libro. Si por cualquier razón se necesitara usar la shell nativa de Windows, la consola de línea de comandos, se han de usar las comillas dobles en vez de las simples (para parámetros que contengan espacios) y se deben entrecomillar los parámetros terminándolos con el acento circunflejo (^) si están al final de la línea, ya que en Windows es uno de los símbolos de continuación.

Configurando Git

Git trae una herramienta llamada git config que te permite obtener y establecer variables de configuración, que controlan el aspecto y funcionamiento de Git. Estas variables pueden almacenarse en tres sitios distintos:

  • Archivo /etc/gitconfig: Contiene valores para todos los usuarios del sistema y todos sus repositorios. Si pasas la opción --system a git config, lee y escribe específicamente en este archivo.
  • Archivo ~/.gitconfig file: Específico a tu usuario. Puedes hacer que Git lea y escriba específicamente en este archivo pasando la opción --global.
  • Archivo config en el directorio de Git (es decir, .git/config) del repositorio que estés utilizando actualmente: Específico a ese repositorio. Cada nivel sobrescribe los valores del nivel anterior, por lo que los valores de .git/config tienen preferencia sobre los de /etc/gitconfig.

En sistemas Windows, Git busca el archivo .gitconfig en el directorio $HOME (%USERPROFILE% in Windows’ environment), que es C:\Documents and Settings\$USER para la mayoría de usuarios, dependiendo de la versión ($USER es %USERNAME% en el entorno Windows). También busca en el directorio /etc/gitconfig, aunque esta ruta es relativa a la raíz MSys, que es donde quiera que decidieses instalar Git en tu sistema Windows cuando ejecutaste el instalador.

Tu identidad

Lo primero que deberías hacer cuando instalas Git es establecer tu nombre de usuario y dirección de correo electrónico. Esto es importante porque las confirmaciones de cambios (commits) en Git usan esta información, y es introducida de manera inmutable en los commits que envías: $ git config --global user.name "John Doe" $ git config --global De nuevo, sólo necesitas hacer esto una vez si especificas la opción --global, ya que Git siempre usará esta información para todo lo que hagas en ese sistema. Si quieres sobrescribir esta información con otro nombre o dirección de correo para proyectos específicos, puedes ejecutar el comando sin la opción --global cuando estés en ese proyecto.

Tu editor

Ahora que tu identidad está configurada, puedes elegir el editor de texto por defecto que se utilizará cuando Git necesite que introduzcas un mensaje. Si no indicas nada, Git usa el editor por defecto de tu sistema, que generalmente es Vi o Vim. Si quieres usar otro editor de texto, como Emacs, puedes hacer lo siguiente: $ git config --global core.editor emacs

Tu herramienta de diferencias

Otra opción útil que puede que quieras configurar es la herramienta de diferencias por defecto, usada para resolver conflictos de unión (merge). Digamos que quieres usar vimdiff: $ git config --global merge.tool vimdiff Git acepta kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge, y opendiff como herramientas válidas. También puedes configurar la herramienta que tú quieras.

Comprobando tu configuración

Si quieres comprobar tu configuración, puedes usar el comando git config --list para listar todas las propiedades que Git ha configurado: $ git config --list user.name=Scott Chacon user.email= color.status=auto color.branch=auto color.interactive=auto color.diff=auto

Puede que veas claves repetidas, porque Git lee la misma clave de distintos archivos (/etc/gitconfig y ~/.gitconfig, por ejemplo). En ese caso, Git usa el último valor para cada clave única que ve. También puedes comprobar qué valor cree Git que tiene una clave específica ejecutando git config {clave}: $ git config user.name Scott Chacon

Obteniendo ayuda

Si alguna vez necesitas ayuda usando Git, hay tres formas de ver la página del manual (manpage) para cualquier comando de Git: $ git help <comando> $ git <comando> --help $ man git-<comando> Por ejemplo, puedes ver la página del manual para el comando config ejecutando: $ git help config Estos comandos están bien porque puedes acceder a ellos desde cualquier sitio, incluso sin conexión. Si las páginas del manual y este libro no son suficientes y necesitas que te ayude una persona, puedes probar en los canales #git o #github del servidor de IRC Freenode (irc.freenode.net). Estos canales están llenos de cientos de personas muy entendidas en Git, y suelen estar dispuestos a ayudar.

Comandos

  • Add

Puedes registrar cambios (añadirlos al Index) usando:

git add <filename>
git add .
  • Commit

Este es el primer paso en el flujo de trabajo básico. Para hacer commit a estos cambios usando:

git commit -m "Commit message"

Ahora el archivo esta incluido en el HEAD, pero aún no en tu repositorio remoto. Es importante que el mensaje tenga contenido, esto será de mucha ayuda para el resto de los desarrolladores.

  • Envío de Cambios

Tus cambios están ahora en el HEAD de tu copia local. Para enviar estos cambios a tu repositorio remoto ejecuta:

git push origin master

Reemplaza master por la rama a la que quieres enviar tus cambios.

  • Remote

Crear/Clonar un nuevo repositorio de git.

git ini/clone

Si no has clonado un repositorio ya existente y quieres conectar tu repositorio local a un repositorio remoto, usa:

git remote add origin <server>

Ahora podrás subir tus cambios al repositorio remoto seleccionado.

  • Branch

Las ramas son utilizadas para desarrollar funcionalidades aisladas unas de otras. La rama master es la rama "por defecto" cuando creas un repositorio. Crea nuevas ramas durante el desarrollo y fusiónalas a la rama principal cuando termines. Lista todas las ramas locales con:

git branch

Muestra el estado actual de la rama, como los cambios que hay sin commitear usando:

git status

Crea una nueva rama llamada "dev" y cámbiate a ella usando:

git checkout -b dev

vuelve a la rama principal ejecutando:

git checkout master

y borra la rama con:

git branch -d dev

Una rama nueva no estará disponible para los demás a menos que subas (push) la rama a tu repositorio remoto usando:

git push origin <branch>
  • Actualiza & Fusiona

Para actualizar tu repositorio local al commit más nuevo, ejecuta:

git pull

en tu directorio de trabajo para bajar y fusionar los cambios remotos. Para fusionar otra rama a tu rama activa (por ejemplo master), utiliza:

git merge <branch>

en ambos casos git intentará fusionar automáticamente los cambios. Desafortunadamente, no siempre será posible y se podrán producir conflictos. Tú eres responsable de fusionar esos conflictos manualmente al editar los archivos mostrados por git. Después de modificarlos, necesitas marcarlos como fusionados con:

git add <filename>

Antes de fusionar los cambios, puedes revisarlos usando:

git diff <source_branch> <target_branch>
  • Etiquetas

Se recomienda crear etiquetas para cada nueva versión publicada de un software. Este concepto no es nuevo, ya que estaba disponible en SVN. Puedes crear una nueva etiqueta llamada 1.0.0 ejecutando:

git tag 1.0.0 1b2e1d63ff

1b2e1d63ff se refiere a los 10 caracteres del commit id al cual quieres referirte con tu etiqueta. Puedes obtener el commit id con:

git log

también puedes usar menos caracteres que el commit id, pero debe ser un valor único.

  • Reemplaza Cambios Locales

En caso de que hagas algo mal, puedes reemplazar cambios locales usando el comando:

git checkout -- <filename>

Este comando reemplaza los cambios en tu directorio de trabajo con el último contenido de HEAD. Los cambios que ya han sido agregados al Index, así como también los nuevos archivos, se mantendrán sin cambio. Por otro lado, si quieres deshacer todos los cambios locales y commits, puedes traer la última versión del servidor y apuntar a tu copia local principal de esta forma:

git fetch origin
git reset --hard origin/master

For conflicting paths, the index file records up to three versions

  • Cherry-pick

Permite aplicar los cambios introducidos por algunos commits existentes. Dado uno o más commits existentes, se aplican los cambios que cada uno introduce, registrando un nuevo commit por cada uno. Pero cuando no es obvio cómo aplicar un cambio, ocurre lo siguiente:

1. El branch actual y HEAD pointer permanecen en el ultimo commit que se realizo con éxito.
2. El CHERRY_PICK_HEAD se establece en el punto en el cual el commit tuvo dificultades para realizar los cambios.
3. El trayecto en cual los cambios fueron aplicados limpiamente se actualiza tanto en el archivo del index como en el árbol de trabajo.
4. Para trayectos en conflicto, el archivo del index guarda hasta 3 versiones. 

Los archivos del árbol de trabajo incluirán una descripción del conflicto entre corchetes por las marcas de conflicto habituales <<<<<<< y >>>>>>>.

  • Ejemplos útiles

Aplicar el cambio introducido por el commit en la punta de la master branch y crear un nuevo commit con este cambio.

git cherry-pick master

Aplicar los cambios introducidos por todos los commits que son antepasados de master, pero no de HEAD para producir nuevos commits.

git cherry-pick ..master
git cherry-pick ^HEAD master

Cuando un parche no se aplica correctamente, pero ha realizado demasiados cambios, y necesitamos volver atrás para luego volver a intentar teniendo mas cuidado con cada linea, la secuencia ha realizar seria la siguiente:

git cherry-pick topic^ (1)
git diff (2)
git reset --merge ORIG_HEAD (3)
git cherry-pick -Xpatience topic^ (4)

En (1) se aplican los cambios, los cuales se podrían mostrar con el comando: "git show topic^". En este ejemplo, el parche no se aplica limpiamente, por lo que la información en conflicto se escribe en el Index y en el Arbol de Trabajo y no se hacen nuevos commit. Con (2) podemos ver un resumen de los cambios realizados. En (3) se vuelve al estado Pre-cherry-picking, pero preservando las modificaciones locales que tienes en el árbol de trabajo. Finalmente en (4) aplicamos los cambios introducidos por topic^ de nuevo, pero con cuidado extra para evitar errores en la base o en el emparejamiento de las lineas de contexto.

Sub-comandos

continue Permite continuar la operación en curso utilizando la información de .git/sequencer. Se puede utilizar para continuar después de la resolución de conflictos en una falla de cherry-pick o revert.

git cherry-pick --continue
  • quit

Permite olvidar la operación actual en curso. Se puede utilizar para limpiar el estado del .git/sequencer después de una falla de cherry-pick o revert.

git cherry-pick --quit
  • abort

Permite cancelar la operación y volver al estado previo del .git/sequencer.

git cherry-pick --abort
  • Revert

El comando "git revert" es esencialmente un git cherry-pick pero inverso. Se crea un commit pero aplicando exactamente lo contrario del cambio introducido por el commit, es decir deshacer o revertirlo. Por lo tanto, cuando lo usamos se deshace el merge commit.

Dado que "git revert" es como un cherry-pick, también posee los sub-comandos:

git revert --continue
git revert --quit
git revert --abort

Para revertir los cambios especificados por el antepenúltimo commit en HEAD y crear un nuevo commit con los cambios reversos, se ocupa:

git revert HEAD~2'

Para revertir los cambios hechos por el antepenúltimo commit en HEAD al penúltimo commit en HEAD. Pero no crea ningún commit con los cambios reversos. El revert solo modifica el Arbol de trabajo y el Index.

git revert -n master~2..master~1
  • Patch

Un parche no sera otra cosa que la concatenación de los diffs, para cada uno de los commits que el parche incluirá. Por lo tanto, la creación de parches en Git es la mejor manera de compartir cambios que aun no están listos para un push a una rama publica de nuestro proyecto.

Al tener varias ramas, estas pueden tener distintos niveles de avance, para obtener las diferencias de acuerdo a los commit realizados en cada una de las ramas, ocupamos:

git log --oneline --all

Obteniendo por ejemplo:

 * b36f227 (experimental) third commit -- added file3
 * f39ebe8 second commit -- added file2
 * 04a26e5 (HEAD, master) first commit -- committed file1

Por lo tanto, para la creación de un parche ocupamos:

git diff from-commit to-commit > output-file

Es decir, nuestro parche se crearía de la siguiente manera para el ejemplo antes mencionado:

git diff 04a2 b36f > patch.diff

Y lo aplicaríamos de la siguiente manera:

git apply patch.diff

Ademas nos permite ocupar el parche creado para generar nuevos parches con cambios nuevos, repitiendo el proceso antes mencionado.

  • Datos Útiles

Hard Reset: Volver a un commit en particular. Borrar los cambios posteriores a este commit.

git reset –hard 1b2e1d63ff

Interfaz gráfica por defecto:

gitk

Colores especiales para la consola:

git config color.ui true

Mostrar sólo una línea por cada commit en la traza:

git config format.pretty oneline

Agregar archivos de forma interactiva:

git add -i

Fuentes