Curso GIT IGZ-BBVA

  • Herramientas visuales de Git :SourceTree (Windows) y SmartGit (Linux)
  • Con Git se trabaja la mayor parte del tiempo offline con su repositorio en local y sólo algunos de los comando son online para cuando quieres comunicarte con un repositorio remoto
  • Creadores: los del kernel de Linux con Linus Torvalds a la cabeza
  • Es un sistema de control de versiones distribuido
  • Trabaja con punteros a los que en su argot se les llama nodos
  • No confundir con los llamados aplicaciones de hosting de repositorios de Git como Github / Bitbucket / Gitlab
  • Cuando haces un commit se hace una foto de todos los ficheros en ese momento (el almacenamiento está optimizado internamente para que no ocupe tanto)
  • Instalación de interprete de Git en Windows: se puede instalar para que se integre con la línea de comandos de Windows o se puede iniciar la Git Bash
  • Ejercicio1
        • mkdir ejercicio1
        • cd ejercicio1
        • git init
        • git status
        • git log
        • Archivo .gitignore para indicar los archivos que no son controlados por el control de versiones
        • git add .

          –> añade todo lo modificado a la zona de index o stage

        • Para hacer unstage (echar para atrás de la zona de stage): git rm –cached <file>
        • NOTA-CONSEJO: los ficheros que se modifiquen que no esten en el stage (buena práctica)
        • Todos los commit tienen su identificador (chorizo de numeros y letras)
        • Pero nos valen los 7 primeros caracteres del chorizo
  • git log --oneline

    –> te saca el log simplificado

  • Se pueden crear alias de los id de commit
  • master se refiere siempre a la rama principal (trunk de SVN)
  • nombre_rama es siempre un puntero al último commit de la rama (Ej: master)
    Siempre que se hace un nuevo commit se avanza el punteroUpstream repository se refiere al conjunto de repositorios remotos

    ZONA STASH

  • stash significa alijo en inglés
    es una zona donde se pueden almacenar los commits de manera temporal.
    El ejemplo típico de uso es cuando hay un fuego en PRO ,tienes cambios en local que no has subido y quieres cambiarte a la rama de PRO.
    Entonces para no ensuciar el repo con tus archivos sucios y porque tampoco quieres prederlos los almacenas en la zona de stash.
    Para utilizar la zona de stash los archivos primero tienen que estar en la zona de staging
    Siempre se almacena en forma de pila

    git stash list
     pop
     apply
     save

    Resolver conflictos , una vez resueltos con el editor que sea , el marcar como resuelto se hace con con

    git add .

    NOTA: nunca modificar los cambios que ya se han pusheados , porque estamos cambiando la historia del repo , git no te deja a no ser que hagas push -f.Y los otros miembros del grupo tienen que clonarse de nuevo el repo

    Ciclo de vida de un fichero git

  • puede estar tracked o untracked
  • Tracked –> cuando ya se ha hecho git add de ese archivo entonces los siguientes commits se pueden hacer con git commit -am
  • untracked –> cuando aún no se han añadido , antes de hacer commit siempre hay que hacer git add .
git show id_commit

–> se ve el changeset del commit

HEAD es una referencia simbólica que apunta al último commit de la rama actual

git checkout id_commit/id_rama

–> cambia el HEAD a donde te quieras posicionar

git checkout master^^

–> te mueves dos abajo –>esto es como volver al pasado con el delorian

crear una rama en GIT es crear un puntero

git reset

te cargas nodos

Si se vuelve al pasado con git checkout lo ideal es crear una rama a partir de ese punto para no perderlo. Mas tarde se fusionará con la rama principal.

git reflog

–> log de lo que se va haciendo con git –> NOTA: puedes coger los commits que se han quedado en el limbo

Crear rama

con

git checkout -b nuevaRama

–> la creas y te posiciones en ella

git branch nuevaRama

–> la creas

git reset --hard master~2

–> te cargas los commit de arriba
si no pones –hard , funciona por defecto con –mixed y de ese modo los nodos de arriba se quedan en la zona de stage

HEAD sólo se crea con el first commit

Referencias

Con las refs se puede referenciar commits tanto locales como remotos
Referencias simbólicas:

  • HEAD
  • ORIG_HEAD –> apunta al commit anterior
  • MERGE_HEAD –> apunta al último commit de la rama que fusioné con la ppal
  • FETCH_HEAD –> apunta a la cabeza del último commit de una rama del remoto

Se almacenan en directorio .git

COMMITS

Es posible hacer commit de ficheros sueltos

git commit -amend

—> machaca el último commit
Por ejemplo si hemos hecho un commit erronea y no queremos que se quede en el log ese comit hacemos otro con ammend que lo machaque.
Aunque nunca hacer esto si el último commit ya se ha pusheado

NOTA-CONSEJO: Nada más crear el proyecto se recomienda crear un commit tonto con un README porque será más fácil trabajar cuando se tengan que hacer resets.
De hecho cuando creas un repositorio en Github , él automaticamente te crea un ‘initial commit’

Squashing = aplastamiento de commits

— > se hace con git reset
Con la opción -soft te lo llevas al index
Con la opción -mixed te lo llevas al workspace
Con la opción -hard te cargas los commits que se queden por delante

NOTA-CONSEJO: antes de hacer push revisar los logs con git log para ver que los commit que tengo en local son bonitos para subir al remoto.

git show-branch --more=<número de commits que tengo>

–> muestra lo mismo que log pero con las referencias en nombre

git log -- <file>

–> todos los commits en los que participa ese fichero

git log --grep='reg-exp'

–> buscar en los comentarios de los commit
Con la opción –no-merges filtra los comentarios de los commit de mergeo

git log --decorate

–> información visual sin tener SourceTree

NOTA-CONSEJO: El plugin Egit de Eclipse hace cosas raras , no es recomendable hasta la fecha

git checkout <files>

–> descartar los cambios desde la zona de staging

git checkout <comit-id> <file>

–> volver a un momento del pasado sólo para un fichero

REVERT

–> deshace un commit en un commit nuevo –> git revert commit/commits
Puede dar conflictos y quedarse a medias . Por lo que después de resolver el conflicto se puede lanzar de nuevo el comando con la opción

  • –abort –> deja el workspace como estaba
  • –continue –> hemos resuelto el conflicto t continuamos
  • –quit –> no recomendable porque es posible que se deje el workspace corrupto

La diferencia con git reset es que éste borra commitas y el revert no

NOTA: Todos los comandos que pueden producir conflictos a resolver tienen las opciones de –quit / –abort/ –continue

RAMAS

NOTA-CONSEJO: Mantener dos ramas en paralelo durante mucho tiempo sin mergearlas no es recomendable porque te expones a un merge infernal –> lo ideal es hacerlo frecuente , a diaria está bien.

Se crean ramas por varios motivos:

  •  por añadir una nueva funcionalidad
  •  para resolver un bug
  •  por tener una rama de trabajo cada miembro del equipo

NOTA-CONSEJO: Nomenclatura de rama: se recomienda utilizar el caracter ‘/’ porque te permite agrupar ramas bajo un mismo nombre y el SourceTree las mete en una carpeta
Ej : feature/p123_añadir_usuarios (p123 puede ser el id del ticket de jira)
bug/falla-edicion

NOTA-CONSEJO: No hacer cambios de rama si tenemos el workspace sucio o hay stage por comitear

Borrar ramas remotas:

git push origin: <branch>

Cuando se hace un git clone por defecto te mueve a la rama master y no te traes otras ramas.
Si hay que traerse otras ramas remotas entonces hay que hacer git checkout -b rama_remota

MERGE

Para ver los conflictos se puede hacer con git diff o con git status

Lo primero antes de hacer merge es colocarse en la rama destino con checkout y después hacerlo

git checkout destinyBranch
git merge anotherBranch

El concepto de fast-forward: Cuando se hace un merge y solo hay un comit de diferencia lo que hace automaticamente git es un fast-forward y te lo pone como un comit más.
Lo puedes deshabilitar con –no-ff

SourceTree

Se pueden organizar los repositorios por carpetas
NOTA: Si las ramas vienen con la nomenclatura de / entonces se agrupan tambien en carpetas
Trabajo con repos remotos –> url de repo puede ser http o ssh. En el caso de ssh hay que generar una clave y subirla al servidor
A veces el ST no refresca bien y hay que ‘menearlo’ un poco

NOTA: Rebase != rebase no interactivo

NOTA: si sale mal un merge hacer un reset master-1 –hard y vuelves a donde estabas

REMOTOS

Clone: por defecto sólo me traigo la rama master –> tengo que explicitamente traerme ramas del remoto para trabajar sobre ellas

Push: se puede configurar para que no te pida u/p

Dos opciones para iniciar repos remoto:
– Creo en local y lo subo a Github
– Creo en github y me lo clono

Github hay que pagar para tener repos privados. En bitbucket puedes tener privados pero un máximo de 5 usuarios

Github puedes crear archivo de licencia en el repo

git remote -v -

–> lista los remotos

git remote add origin https://github.com

Con github al crear el repo te crea un initial commit

Collaborators

FORK = coger un remoto y clonarmelo en mi repo remoto

El tema de los FORKS se utiliza cuando queremos tener colaboradores en un proyecto pero queremos tener control total sobre los merge de la rama global.

PULL-REQUEST

Cada grupo colaborador se clona el master , trabaja sobre su propio github y cuando tienen versiones estables solicitan un pull-request al repo master

El administrador del repo master le llegarán los pull-request y podrá aceptarlos , rechazarlos con comentarios , etc.

Si el administrador acepta el pull-request harán merge con la rama master y de esta forma se añadirán todos los commit que se enviaron desde el solicitante

Posible escenarios cuando queremos que no todos puedan hacer push

  • 1.- Que puedan subir solo a una rama de DEV y pidan un pull request sobre el mismo remoto al gatekeeper
  • 2.- Que cada uno tenga su remoto y se vayan pidiendo pull request

NOTA-CONSEJO: Actualizar diariamente el remoto para no dejarte los cambios de otros desde hace mucho tiempo que puedes tener que resolver muchos conflictos

GIT REBASE

—> rebasar mis commits a otra rama: git rebase dev –> absorvo los cambios de dev en mi rama
Git va absorviendo los commits uno a uno y cuando encuentra conflictos se para y te deja que los resuelvas.
Cuando los tienes resueltos haces git rebase –continue

NOTA-CONSEJO: de secuencia diaria:
git checkout dev
git pull origin dev
git checkout feature/…
git rebase dev

TAGS

En SVN se hace una copia física de todo , aqui no , aquí es un puntero
El id de tag se puede usar como un commit

Cuando se hace push las tags se suben de forma independiente

Tipos: lightweight / annotated

Creación de alias de comandos

git config alias.logo “log –oneline”

Alias típicos: ci= commit , co=checkout

git blame <file> –> se vé quien tocó

git checkout -b –track –> para bajarme ramas en modo sólo lectura

Esto se suele hacer cuando se quiere integrar trabajo de otras personas pero no queremos que por error modificar eso ficheros. Son lo que se llaman las ramas trackeadas

Repos bare

Para que tu máquina sirva de repo remoto a los compañeros del equipo

La carpeta en donde esté debe tener lo privilegios de red apropiados

Esa carpeta puede ser una carpeta de dropbox (las carpetas de dropbox se sincronizan automáticamente en toda las máquinas donde esté instalado con el usuario que sea)

ALTERAR COMMITS

squashing / splitting

REBASES = transplantes

Rebase interactivo: rebase -i

git rebase -i <puntero-base>

El puntero-base tiene que ser uno por debajo de donde queremos tocar

Te lanza el editor por defecto de git para que tu decidas que quieres hacer con esos commits

No deja modificar los commits de merge