Tutorial Git
Tutorial Git
Introducción y referencias....................................................................................................................4
Manuales en línea y configuración.......................................................................................................4
git <commando> --help...................................................................................................................4
git config..........................................................................................................................................5
Commit o versión.................................................................................................................................5
Branch o rama.......................................................................................................................................5
Directorio de trabajo.............................................................................................................................5
git init...............................................................................................................................................6
Índice o área de cambios (stagin area, index).......................................................................................6
git add .............................................................................................................................................6
git reset ............................................................................................................................................6
git commit .......................................................................................................................................7
git log –oneline................................................................................................................................7
Análisis del directorio de trabajo..........................................................................................................7
git status...........................................................................................................................................7
git diff .............................................................................................................................................8
git diff --cached ...............................................................................................................................8
git mv <old> <new>........................................................................................................................8
git rm <files>...................................................................................................................................9
git rm --cached <files>.....................................................................................................................9
git checkout <files>.........................................................................................................................9
git checkout .....................................................................................................................................9
Ejemplos.............................................................................................................................................10
Transformar un directorio en el directorio de trabajo git...............................................................10
Crear ficheros en el directorio de trabajo git.................................................................................10
Mostrar estado del directorio de trabajo........................................................................................11
Registrar nuevos ficheros en el índice...........................................................................................11
Mostrar estado del directorio de trabajo........................................................................................11
Crear nuevo commit y ver historia................................................................................................12
Inspeccionar historia y área de trabajo..........................................................................................12
Añadir nuevo fichero.....................................................................................................................13
Crear un nuevo commit a master...................................................................................................13
Ramas.................................................................................................................................................14
Crear una rama: git branch <nombre rama> <id commit base>..................................................14
Mostrar ramas existentes: git branch -v.........................................................................................15
Grafo de commits...............................................................................................................................15
Padres y ancestros de un commit...................................................................................................15
Mostrar historia de un commit o una rama....................................................................................16
git log -<n>................................................................................................................................16
git log --oneline --graph <rama>...............................................................................................16
git log --oneline <commit>.......................................................................................................16
git log --oneline --all …............................................................................................................16
git log --oneline --all --graph....................................................................................................16
Mostrar diferencias entre ficheros de diferentes commits.............................................................17
git diff …...................................................................................................................................17
git show …................................................................................................................................17
Restaurar commits en el directorio de trabajo...............................................................................17
git checkout <commit>.............................................................................................................17
El comando reset............................................................................................................................18
git reset <commit>....................................................................................................................18
git reset --hard <commit>.........................................................................................................18
Ejemplo de uso para integración de varios commits.................................................................18
Ejemplos ramas..................................................................................................................................19
Mostrar ramas................................................................................................................................19
Mostrar historia..............................................................................................................................20
Crear rama......................................................................................................................................20
Mostrar ramas................................................................................................................................21
Mostrar rama en modo verboso.....................................................................................................21
Restaurar rama (en el directorio de trabajo)..................................................................................22
Mostrar historia..............................................................................................................................23
Integración de commits con merge.....................................................................................................23
git merge <commit>.......................................................................................................................23
git merge …...................................................................................................................................24
Conflictos de integración...............................................................................................................24
Ejemplo de integración..................................................................................................................25
Mostrar ramas en modo verboso...............................................................................................25
Crear nueva rama para realizar la integración...........................................................................26
Integrar master en inverse.........................................................................................................27
Resolver conflictos....................................................................................................................27
Crear commit de integración.....................................................................................................28
Conflictos vistos con diff..........................................................................................................28
Integración ff (fast-fordward)........................................................................................................29
Ejemplo de integración ff..........................................................................................................29
Mostrar ramas...........................................................................................................................30
Restaurar rama master...............................................................................................................30
Crear rama nueva......................................................................................................................31
Integrar en rama master.............................................................................................................32
Integración de ramas con rebase.........................................................................................................32
git rebase .......................................................................................................................................33
Ejemplo de rebase..........................................................................................................................34
Mostar ramas.............................................................................................................................34
Crear y restaurar rama...............................................................................................................34
Comenzar cambio de base.........................................................................................................35
Resolver conflictos....................................................................................................................35
Finalizar rebase, mostrar ramas y grafo....................................................................................36
Git y GitHub.......................................................................................................................................37
Tipos de repositorio.......................................................................................................................37
GitHub...........................................................................................................................................37
Crear repositorios remotos en GitHub...........................................................................................39
Crear un nuevo repositorio (New repository)...........................................................................39
.gitignore...................................................................................................................................40
Importar un repositorio a GitHub..............................................................................................41
Clonar un repositorio de GitHub...............................................................................................42
Referenciar un repositorio remoto.................................................................................................43
git remove [-v]..........................................................................................................................43
git remote add ….......................................................................................................................43
git remote remove …................................................................................................................43
Clonar un repositorio remoto en uno local....................................................................................44
Actualizar un repositorio en GitHub con push..............................................................................45
Git y GitHub.......................................................................................................................................47
Rama local, remota y tracking.......................................................................................................47
Crear, enlazar o listar ramas remotas.............................................................................................47
git clone …................................................................................................................................47
git branch …..............................................................................................................................48
git fetch …................................................................................................................................48
Ejemplo de clonar un repositorio remoto..................................................................................49
Ejemplo de crear un remote...........................................................................................................50
Copiar una rama remota en una local............................................................................................52
El repositorio central..........................................................................................................................54
Ejemplo de clonar rep. CORE-UPM/cal e integrar rama cal_merge de jquemada/cal..................55
Traer cal_merge de jquemada/cal e integrar.............................................................................56
Actualizar rama master (tracking) de CORE-UPM/cal............................................................58
Actualizar ramas remotas...................................................................................................................60
Ejemplo de como enviar pull request desde CORE-UPM/cal a jquemada/cal en GiHub.............61
Preparar pull-request.................................................................................................................61
Editar pull_request....................................................................................................................62
Enviar pull_request...................................................................................................................62
Ejemplo de como integrar pull request en jquemada/cal...............................................................63
Resumen de evolución del proyecto..............................................................................................65
Introducción y referencias
Git es un gestor de repositorios de versiones software, desarrollado por Linus Torvalds en 2005 en
código libre. Lo diseño para soportar el desarrollo de Linux con un modelo descentralizado y
abierto.
git es un comando de UNIX/Linux.
• Documentación: https://git-scm.com/documentation
◦ Tutorial: https://www.atlassian.com/git/tutorials/setting-up-a-repository
Commit o versión
Instantánea del estado de los ficheros de un proyecto (puede restaurarse). Algunos commits se
etiquetan con tags especiales de versión, p.e. v1, v1.3, ..
Branch o rama
Secuencia de commits ordenada por fechas que soporta un desarrollo. Los nuevos commits se
añaden al final de la rama de desarrollo.
La rama de desarrollo principal se denomina habitualmente master. La rama master se crea
automáticamente al crear el primer commit.
Directorio de trabajo
Directorio donde se crean las versiones del proyecto: código fuente, datos, … Se denomina
también:
• Área o espacio de trabajo (workspace).
• Árbol de trabajo (work-tree) por la estructura en árbol de los subdirectorios que agrupan
ficheros.
• Base de código (codebase).
git init
El comando git init transforma un directorio en un directorio de trabajo Git, añadiendo el repositorio
de commits al directorio, en un subdirectorio oculto .git (que contiene la base de datos donde
guardar los commits).
Muchos comandos git se invocan en el directorio de trabajo o un subdirectorio
• git commit guarda nuevo commit y abre un editor para crear mensaje del commit
• git commit --amend -m “....” modifica el último commit con lo registrado en el índice !OJO
cambia commit
Y asigna un identificador único para el nuevo commit, que es un número hexadecimal de 40
dígitos generado como clave de hash SHA1 (973751d21c4a71f13a2e729ccf77f3a960885682).
Se suele usar el formato corto (formato largo es incómodo) con los 7-8 dígitos iniciales, que son
únicos en un proyecto (973751d2). Los comandos git permiten identificadores cortos o largos.
git status
Muestra estado de los ficheros del directorio:
• modified: modificados respecto al commit anterior
Con la opción -s (git status -s) muestra estado en formato compacto muy cómodo y conciso.
git diff ...
Muestra diferencias en los ficheros modified respecto al commit anterior
• git diff muestra los cambios en todos los ficheros modified del directorio de trabajo
• git diff README.md muestra solo los cambios en README.md, pero solo si es modified
• git diff --cached README.md muestra solo los cambios en README.md, pero solo si es
staged
git rm <files>
Borra <files> del directorio de trabajo y registra lo borrado en el índice
git rm file1.js file2.js borra file1.js y file2.js del directorio de trabajo y del índice
git checkout .
Elimina los cambios de todos los ficheros modified del directorio de trabajo que pasan a
unmodified (Peligro! Cambios se pierden).
git checkout . elimina cambios en todos los ficheros modified del directorio de trabajo
Ejemplos
Transformar un directorio en el directorio de trabajo git
• La rama master es la rama principal de un repositorio, es una rama predefinida que se crea al
crear el primer commit.
• Las ramas soportan desarrollos separados de master. Una rama puede comenzar en cualquier
commit del repositorio.
• Los nuevos commits de una rama se deben añadir al final (la rama siempre crece). La flecha
indica el commit o los commits a partir de los se ha generado.
• El nombre de la rama es un puntero a su último commit, por ej.
Crear una rama: git branch <nombre rama> <id commit base>
git branch rama_y 46g8g8 crea la rama de nombre rama_y con base en el commit C3 (46g8g8)
Mostrar ramas existentes: git branch -v
Grafo de commits
El grafo de commits de un repositorio es un grafo con la relación de todos los commits de las ramas
del repositorio.
Las flechas de salida de un commit indican su relación con las anteriores.
• Una flecha indica un commit generado por modificación del commit anterior.
• Dos flechas indica un commit generado por la integración de una rama en otra.
La historia de un commit es la secuencia ordenada, por fechas, de commits utilizados para generar
dicho commit.
git log --oneline master^2 muestra la historia del 2º padre de master (formato 1 línea)
git log --oneline master~3 muestra la historia del 3º ancestro de master (formato 1 línea)
git log --oneline --all muestra todos los commits del repositorio ordenados por fechas
git diff master~2 muestra los cambios en ficheros entre master~2 y HEAD
git diff rama_x master -- LICENSE muestra los cambios en el fichero LICENSE entre rama_x y master
git diff rama_x master LICENSE similar al anterior si no hay ambigüedad en los nombres
git show …
Muestra metadatos de commit y diferencias con el commit anterior
git show rama_x muestra los metadatos del último commit de rama_x y las diferencias con el commit
anterior
git show muestra los metadatos del commit actual (HEAD) y las diferencias con el commit anterior
El HEAD es un puntero al commit que está guardado en el directorio de trabajo, que se actualiza
automáticamente al hacer chekout.
El comando reset
El comando git reset permite compactar o eliminar commits del grafo. Normalmente se utiliza para
eliminar, compactar o rehacer la última parte de la historia de una rama.
Ejemplo:
git reset master~2 mueve HEAD y el puntero de rama al 2º ancestro, dejando las diferencias en el directorio
de trabajo
Nota: Los cambios introducidos en los 2 commits que desaparecen de la rama quedan en los ficheros
modified
Ejemplo:
git reset --hard master~2 mueve HEAD y el puntero de rama al 2º ancestro. Los cambios introducidos en los
dos últimos commits de la rama desaparecerían si no estuviesen en otra rama.
Crear rama
Mostrar ramas
Mostrar historia
Integración de commits con merge
git merge <commit>
Intenta automatizar la integración de un commit. Por defecto utiliza la estrategia recursiva que
integra el commit indicado, fichero a fichero, en el commit actual, aproximadamente así:
• Ficheros iguales en ambos commits: incluye el fichero común (sin conflicto)
• Fichero esta solo en uno de los commits: incluye el fichero (sin conflicto)
• Ficheros con diferencias disjuntas: une ambos ficheros con auto-merge (sin conflicto)
• Ficheros con ancestro común en sus historias: incluye el último fichero (sin conflicto)
• Ficheros con diferencias en el mismo contexto: une ambos, marca diferencias y genera
conflicto
git merge …
Intenta integrar un commit con el activo (HEAD):
• git merge master → integra el último commit de master en el commit activo (HEAD)
• git merge g699g8 → integra el commit g699g8 con el commit activo (HEAD)
• git merge -m “msg” master → integra master en HEAD y asigna el mensaje “msg” al commit de
integración
• git merge --abort → aborta la integración sin generar commit de integración cuando ha habido
conflictos
Conflictos de integración
Si hay conflictos no se genera commit de integración.
• Los conflictos quedan marcados en el fichero en el directorio de trabajo, en un estado
especial denominado unmerged.
• Los conflictos se resuelven editando manualmente. Una vez resueltos los conflictos se
genera el commit de integración con git commit …
• Los ficheros sin conflictos quedan también en el directorio de trabajo, en estado staged.
Ejemplo de integración
Para integrar los 2 botones desarrollados en ramas diferentes, se deben integrar las 2 ramas con git
merge ...
Resolver conflictos
Crear commit de integración
Ejemplo de integración ff
Siguiendo con el ejemplo anterior, si integramos ahora la rama cal_merge en la rama master, se
reutiliza, con fast-forward, la integración ya realizada en la rama cal_merge, porque master ya se ha
integrado en cal_merge (tal y como muestra el grafo de commits)
Mostrar ramas
Este paso no es necesario para la integración que queremos hacer, sólo es para dejar en una rama
propia el commit del x^2 button. De este modo, al final tendremos una rama para x^2 button, otra
para 1/x button y, en el master la integración de los dos botones.
Integrar en rama master
Cambiar la base (rebase) de una rama permite también integrar desarrollos, integra los desarrollos
linealmente (muy limpio), pero elimina la historia de ramas utilizadas e integradas para el
desarrollo.
git rebase ...
• Una rama puede cambiar de base con git rebase .…
La rama cal_rebase cambia la base “Read. & Lic.” por “x^2 button”. Este cambio de base integra
los botones de forma similar a merge.
Ejemplo de rebase
Mostar ramas
Resolver conflictos
Finalizar rebase, mostrar ramas y grafo
Git y GitHub
Tipos de repositorio
Repositorio sin directorio de trabajo (bare). Repositorio para compartir desarrollos con otros a
través de Internet. Suele estar alojado en un servidor de Internet y
Se sincroniza con uno local, con
• git push ... sube ramas de desarrollo a un repositorio bare
• git pull ... integra una rama de otro repositorio con una rama local
Se crea con:
• git init –bare Crea solo un fichero con el repositorio de commits y sin directorio de trabajo
GitHub
GitHub es un portal donde programadores comparten repositorios con proyectos Git. Nos da acceso
a ellos a través del navegador Web y a través de Git.
GitHub: https://github.com
Los repositorios públicos son gratis, los privados de pago.
Los repositorio sde GitHub se identifica en un repositorio local con un URL, p. e.
• https://github.com/jquemada/cal → URL del rep. jquemada/cal en GitHub
• .gitignore fichero donde se indica que ficheros debe ignorar Git al generar versiones.
Otros desarrolladores lo copian con Fork a su cuenta en GitHub. Los desarrollos se realizan en la
copia en GitHub clonada con Fork. GitHub permite contribuir los desarrollos al repositorio de
referencia con pull request.
Referenciar un repositorio remoto
Un repositorio remoto se identifica en Internet con un URL, por ejemplo:
• https://github.com/jquemada/cal
• https://github.com/jquemada/cal_I
git remote ... permite asociar un nombre, denominado remote, a un URL. El nuevo nombre puede
utilizarse, en vez del URL, en los comandos para identificar el repositorio.
git clone … crea un nuevo repositorio local, donde copia la rama master del repositorio remoto
clonado. Además asocia el nombre de remote origin al repositorio remoto origen de la clonación.
• git clone https://github.com/jquemada/cal_I → copia el repositorio remoto en el directorio
local cal_I (mismo nombre que el repositorio). origin referencia al repositorio clonado
https://github.com/jquemada/cal_I.
• git clone https://github.com/jquemada/cal_I mi_cal → Copia el repositorio remoto en el
directorio local mi_cal. origin referencia al repositorio clonado
https://github.com/jquemada/cal_I.
Actualizar un repositorio en GitHub con push
git push … Actualiza el repositorio remoto con los nuevos commits de una rama local:
• git push https://github.com/jquemada/cal master → actualiza los nuevos commits de la rama
master en el repositorio GitHub jquemada/cal
• git push https://github.com/jquemada/cal_2com master → actualiza los nuevos commits de
la rama master en el repositorio GitHub jquemada/cal_2com
• Rama tracking: rama local asociada a una remota. La rama tracking simplifica las
operaciones de sincronización con la remota. Una rama de desarrollo local suele ser tracking
de la remota equivalente, por ej. master de origin/master
• git branch -vv → muestra en las ramas tracking la rama remota asociada y su estado
git fetch …
Crea si no existen o actualiza las ramas remotas de un remote creado con git remote .…
• git fetch cal → crea las ramas remotas del remote cal o actualiza su estado si existen
• git fetch --all → crea o actualiza el estado de todas las ramas de todos los remotes definidos
• git fetch -p origin → la opción -p (--prune) actualiza las ramas de origin eliminando las que
ya no existen
Ejemplo de clonar un repositorio remoto
Ejemplo de crear un remote
Copiar una rama remota en una local
Para añadir desarrollos a una rama remota debemos copiarla en una local. Los desarrollos se
realizan sobre la rama local añadiendo nuevos commits.
git checkout …
Copia una rama remota en una local tracking y restaura la rama local (solo cuando no existe)
• git checkout square → crea y restaura la rama tracking square asociada a <remote>/square
Restaura una rama remota en mode detached HEAD, es decir no asociada a ninguna rama
• git checkout origin/square → restaura origin/square en modo detached HEAD
git fetch .…
Copia una rama remota en una local utilizando refspecs: [+]<local_branch>:<remote_branch>
• git fetch origin square:sqrt → Crea o actualiza la rama local sqrt con los commits de la
remota origin/square
• git fetch origin pull/1/head:s1 → Crea o actualiza la rama local s1 con el pull_request 1 del
repositorio remoto origin en GitHub
• git fetch cal_branches +s1:s1 → Crea o actualiza la rama local s1 con la remota
cal_branches/s1 aunque sean incompatibles (+)
• git fetch https://github.com/jquemada/cal square:square → Crea o actualiza la rama local
square con la rem. square de https://github.com/jquemada/cal
git pull .…
Traer la rama remota indicada e integrarla con una rama del repositorio local
• git pull cal_branches square → integra la rama square de cal_branches en la rama activa
git push ... copia una rama local en una remota. Puede utilizar refspecs: [+]<local_branch>:<remote_branch>
• git push → Actualiza las ramas remotas de las ramas locales tracking definidas en el
repositorio local
• git push -f cal_branches master → Actualiza la rama cal_branches/master con la local
master, aunque sean incompatibles.
• git push cal_branches sqrt:square → Actualiza la rama remota cal_branches/square con los
nuevos commits de la local sqrt
• git push https://github.com/jquemada/cal sqrt:square → Actualiza la rama remota cal/square
con los nuevos commits de la local sqrt
git push … borra ramas en un repositorio remoto (OJO! son las ramas reales del repositorio remoto)
• git push origin :sqrt → Borra la rama sqrt en el repositorio remoto origin
• git push origin --delete sqrt → Similar a anterior, opción posible en versiones recientes de
git
Ejemplo de como enviar pull request desde CORE-UPM/cal a
jquemada/cal en GiHub
Preparar pull-request
Editar pull_request
Enviar pull_request
Ejemplo de como integrar pull request en jquemada/cal
Resumen de evolución del proyecto