Ruta

Instalación de Git en los distintos sistemas operativos

Os mentí en subtitulo !!
No voy indicaros como instalar en más sistemas operativo que en Linux y en terminal, ya que es el utilizo.  :-)

apt-get install git

Cuando vaya necesitando instalar en otros sistemas operativos, os lo pondré.

Es tan facil desde terminal que da mucha pereza.

Con la instrucción anterior es suficiente para tener todo listo para iniciar tu primer repositorio local con Git.

Inicializar repositorio local

$ git init # Añade repositorio.. crea un directorio oculto .git en esa misma ruta
$ git add . # Marca todos los ficheros para el próximo commit.
$ git commit -m "Estado inicial" # Crea un nuevo commit con los ficheros marcados.

Estos 3 comandos son las que necesitamos para iniciar nuestro primer repositorio, en que añadimos todos los ficheros que tenemos en directorio actual, creando un commit de inicio.

Una vez iniciado el repositorio ya podemos ponernos a currar en él. Añadir, modificar, eliminar ficheros y lineas de código con la garantía y la ventaja que tiene utilizar un control de versiones.

Tanto si ya eres un programador experto, como un amater mi recomendación es comitear y comitear, no pienses en organizar cuando comiteas y cuando vas comitear, comitea todo aquello que hagas, ya tendras tiempo de analizar y ver como mejorarlo.

¡ Te advierto que git se hace muy adictivo !

Configuración de Git

Como ya comente no hace falta nada mas para empezar git para gestionar tu proyecto, aunque cada vez que avances, o colabores en proyectos remotros podrás necesitar configurar un poco tu repositorio:

  • Git config: Con este comando podrás configurar el usuairo y  el mail, ideal si trabajas con mas programadores o repositorios remotos.
    Tambien con ese comando puedes configurar que git tenga en cuenta los cambios de los permisos en los ficheros, algo util cuando trabajamos en distintos servidores con permisos distintos.
  • Gitignore : Este comando es ideal para descartar el seguimiento de ficheros que nos interesa que controle git.

Para ello creo un entrada aparte  Git config, ya que esto es una introducción rápida... :-)

Primer commit en Git

Con las tres instrucciones anteriore ya hicimos el primer comit, podríamos haber clonado un repositorio existente, pero eso lo dejamos para otro post.

Saber en estado estamos.

Empezamos trabajar y realizamos cambios en nuestro código, ahora queremos saber que ficheros hemos añadido, modificado o eliminado, con la instruccion:

git status

Nos indica los ficheros  modificados, eliminados y ficheros sin seguimiento, te los pone ROJO.

Cuando te aparecen en verde , es que ya los añadistes con la instruccion ADD, pero aun hiciste commit.

La instruccion ADD es la que utilizamos para preparar los cambios queremos commitear:

git add .

Ten en cuenta que (.) indicar todos los fichero que siguen en la ruta que estes. Tambien puedes añadir fichero a fichero.

Otra forma más intuitiva para añadir los cambios y indicar los que eliminamos es con el siguiente comando:

git add -i

Donde nos muestra un menu como este:

*** Commands *** 
1: status   2: update   3: revert   4: add untracked
5: patch   6: diff   7: quit   8: help

Seleccionando cualquiera de las opciones , nos permite con simple numero , y secuencias como 1-12, 13 ,15 añadir varios ficheros a la vez... marcándolos con * cuando estén añadidos.

Como veís este menu iteractivo de  algunas de la opciones que tien este comando que es muy potente. Ver entrada Git Add

Si quieres eliminar un fichero puede hacerlo directamente con:

git rm <fichero>

Donde elimina y lo prepara para comitear.

Es lo mismo que si lo eliminamos nosotros a mano y luego realizamos git add <fichero eliminado>, recuerda que estos ficheros si ya fueron comiteado, podras recuperarlos si lo deseas.

Esta opción para un fichero no es mala, pero si tuvieramos mucho ficheros para hacerlo podríamos utilizar

git rm $(git ls-files -d)

Está instruccion hace lo  mismo eliminado del seguimiento para este commit de todos los ficheros eliminados.

Una vez añadidos los ficheros que realizamos cambios o eliminamos, si volvemos a realizar:

git status

Nos listará los ficheros que preparamos para realizar el commit, estos cambiarán de color, en vez rojo aparecera en verde.

Si hay alguno en rojo es que ese fichero que no está preparado para el commit queremos realizar.

Al volver a ver el "status", esos ficheros aparecerán los ficheros preparados y no preparados indicando que se modificaron, se eliminaro o se renombraron.

UNA VEZ TENGAMOS AÑADIDO LOS FICHEROS QUEREMOS COMITAR, SOLO QUEDA A HACERLO

git commit - m " Texto breve de los queremos comitar

La instruccion anterior es el metodo abrevidado, ya que si no poner opcion -m , te abre el editor por defecto y ahi puede escribir el texto.

Incluso te muestra comentadas en lineas los ficheros que comiteas.

Recuerda que el texto que pongas luego con instrucciones como git log, puede buscar esos commit donde hay esos texto.

Deshacer el ultimo commit

Muchas veces hacemos un commit y nos damos cuenta que los cambios realizados están mal o no estan completos.

Queremos eliminar el commit para poder añadir esos cambios y volver a commitear.

Es importante entender que ese ultimo commit este solo en esa rama o master local, ya vamos cambiar la cabecera de esa rama.

git reset HEAD~

Te deja todos los ficheros como están, si realizar un git status, veras que podrás volver añadirlos para commitear.

 

¿Imaginar que antes comitear quieres ver las diferencias que tiene un fichero determinado?

Tiene varios comando para realizar esto, pero el principal

git diff [ruta/del/fichero]

Nos mostrará todos los cambios de ese fichero, si no ponemos fichero , nos muestra todos los cambios de todos los ficheros que no está commiteados.

Este comando tiene muchas opciones y posibilidades ver más información el entrada Git Diff -Ejemplos

 Nosotros ahora utilizamos un programa mas visual que DIFFUSE.

¿ Ahora queremos dejar todo como estaba ?

Muchas veces necesitamos recuperar el estado de unos ficheros , que fuimos cambiando o se cambiaron , por algún motivo...

Pues si queremos volver a recuperar el estado del ultimo commit de todos los ficheros, podemos realizar:

git reset --hard HEAD

Donde está instrucción deja el repositorio en el ultimo comit de esa rama.

Con esta ultima instrucción los ficheros que hubieras eliminado, los recuperas, los ficheros que modificaste te los pone de nuevo, lo que no hace, es eliminar los ficheros que tiene a mayores, que con git status puedes verlos.

 ¿ Quiero ver lo que cambie en commit anteriores ?

Para listar los commit realizados ( nuetras arbol) . Con la instruccion :

git log

Nos muestra un listado de los commit que tenemos en el proyecto, en orden descendente, es decir muestra el ultimo al primero.

Ahora si queremos que nos muestre en una sola linea una forma comoda es:

git log --pretty=format:"%h - %an, %ar : %s"

Si ademas nos gustaría que nos informe de los ficheros que cambiamos (M) Modificamos (D) Eliminamos , pero solo el nombre...

git log --pretty=format:"%h - %an, %ar : %s" --name-status

Una vez localicemos el commit , anotando el numero que nos indica, podemos ver los ficheros que cambiamos en ese commit, con la instrucción

git whatchanged -1 [8 digitos por lo menos del numero commit]

Entonces nos listará los ficheros que cambiamos en ese commit.

Con este mismo commando podemos listar todos los commit que afectaron a un fichero.

git whatchanged [/ruta/del/fichero]

Y si antes de la ruta , ponemos la opción -p , ya nos muestra los cambios en cada commit.

¿ Queremos comparar un fichero en distintos commit?

Ahora imaginar que necesitas saber los cambios que realizamos en un ficheros con respecto al estado actual de ese fichero. Conociendo el numero commit, con git diff ya puedes verlo:

git diff [numero commit] /ruta/del/fichero

Nos muestra los cambios que tenemos en el fichero ( estado actual)  comparando con el mismo fichero en momento realizar el commit.

Si quisieramos comparar ese fichero pero cuando comitamos , es decir comparar el estado del archivo en los momento de dos comit.

git diff [nºcommit1] [nºcommit2] /ruta/del/fichero

Más retorcido todavía....

Y si queremos comparar un fichero con otro fichero e incluso fuera del repositorio de git.

diff -u /ruta/del/fichero1 /ruta/del/fichero2

¡¡ IMPRESIONANTE !!...

 

Ramas en  Git : Locales o remotas

Una rama es difurcación del proyecto en punto determinado (commit), donde podemos llegar puntos distintos del proyecto o podríamos volver a juntarnos con el proyecto principal (master).

Nosotros especialmente la utilizamos para tener una rama "master" que es la de producción y la "desarrollo" que es donde vamos realizar los cambios, mejoras o tratamiento de errores. Una vez testeados esos cambios los validamos y la fusionamos con master (merge).

Hasta ahora hablamos de ramas locales, ya que tenemos que tener en cuenta que podemos trabajar con repositorio remotos, por lo cual tendremos ramas remotas.

Ahora solo lo vamos tratar instrucciones básicas para ramas creadas en local, si quieres más información os recomiendo estos dos links:

Aunque el tratamiento de las ramas locales y remostas es identico ( muy similar).

Ramas locales : Explicación básica

Metodos de crear un ramas locales

Cuando creamos una rama , tenemos que tener en cuenta que lo creamos desde el comit actual.

$ git branch <nombre>                
# Crear la rama en el punto actual.
$ git checkout

Con la siguiente instrucción , nos ahorramos la primera instrucción ( git branch )

$ git checkout -b <nombre>

Las dos instrucciones anteriores realizan lo mismo.

Como cambiar el nombre de una rama.

$ git branch -m <actual> <nuevo>      
# Renombrar la rama $ git branch -d <nombre> # Borrar la rama

Como crear una rama desde un commit determinado

$ git branch <nombre> <COMMIT>
$ git checkout      
 # Crea la rama a partir del commit dado. Es necesario hacer checkout.

$ git checkout -b <nombre> <COMMIT>          
 # Crear rama a partir del commit dado.

De las dos formas que podermos crear una Rama , indicando el commit desde el queremos crear la nueva rama.

Listar ramas

$ git branch
# Lista las ramas existentes.

Nos muestras las ramas existentes en repositorio de Git.

Si tuvieramos repositorio remoto, podríamos listar tambien las ramas remotas con la instrucción

$ git branch -v

 En la instrucción anterior nos muestra el commit en el que esta.

Si tenemos varias ramas y queremos saber si se fusionaron, podemos

$ git branch --merged
# Mostrar ramas que se han fusionado con la actual, y por tanto pueden borrarse

Por el contrario si queremos saber aquella que no estan fusionadas con la actual

git branch --no-merged # Mostrar ramas con trabajos sin funsionar. Intentar borrarlas dará un error.

 

Moverse a una rama o a un commit específico

$ git checkout <rama>

De esta forma cambiamos de rama.

Como eliminar una rama.

Para eliminar un rama :

git branch -D <nombreRama>

Fusionar ramas (merge)

$ git merge <nombre>       # Fusiona la rama indicada en la rama actual

Las diferencias se resuelven automáticamente si es posible. En caso de conflictos (código o ficheros binarios modificados en ambas ramas) el proceso se detiene (merging) a la espera de una resolución manual.

1-Resolver conflictos de fusionado:

Al hacer "merge" y si hay conflitos , git nos marca los ficheros con <<<< HEAD  y separando el codigo que tiene conflicto con ============  , cerrando  con >>>>>>>>>>>>>

Esto solo es posible en ficheros de texto plano, claro está... :-)

La sección “Unmerged paths” de git status muestra los ficheros que requieren atención. Debe resolverse cada conflicto manualmente dentro del fichero (eliminando las marcas agregadas por git) y marcarlo como resuelto con git add.

En vez de editar los ficheros es posible escoger una de las dos versiones disponibles (rama actual o rama que se está fusionando):

$ git checkout --ours -- <file> # Obtener la versión del fichero en la rama actual $ git checkout --theirs -- <file> # Obtener la versión del fichero en la rama que se está fusionando con la actual

Para abortar la acción o anularla una vez realizada:

2- Resolución gráfica de conflictos:

$ git mergetool # Inicia la herramienta gráfica de resolución de conflictos

La herramienta crea ficheros adicionales por cada fichero en conflicto (backup, base, local, remote) para que la herramienta de resolución pueda mostrarlos al usuario al mismo tiempo y éste establecer la versión final. Estos ficheros deberían borrarse automáticamente tras la edición (en caso de que persistan es necesario borrarlos manualmente).

La resolución básica sólo sirve para ficheros de texto. En ficheros binarios usar git checkout –ours o git checkout –theirs para escoger una de las dos versiones disponibles.

Deshacer cambios

$ git revert <COMMIT> # La recuperación hace un nuevo commit en la rama actual sin ir "hacia atrás" en la historia $ git reset --hard # Deshace los cambios locales $ git reset --hard HEAD~1 # Elimina el último commit

Recuperar una versión determinada de un fichero o path:

$ git reset <COMMIT> -- <path> # git reset NO sobreescribe cambios locales $ git reset -p <COMMIT> -- <path> # Seleccionar interactivamente las partes a restaurar $ git checkout <COMMIT> -- <path> # Sobreescribe cambios locales sin preguntar

En Windows se puede abrir git-bash directamente en cualquier subcarpeta carpeta del proyecto (boton derecho – git bash here). Entonces para recuperar un fichero o path local:

$ git checkout <COMMIT> -- ./<path>

Historial de proyecto

Si queremos saber los commit que realizaron en es proyecto debemos ejecutar dentro del proyecto

$ git log <path>
# Mostrar todos los commits para un fichero especifico con info detallada
$ git log -n 2 -- <path>
# Mostrar sólo los dos últimos commits para ese fichero
$ git log -oneline -- <path>
# Formato abreviado con id de commit y comentario
$ git log <SINCE>..<UNTIL> -- <path>
# Mostrar los commits para ese fichero entre dos commits indicados

Abrir GITK mostrando gráficamente el historial para un fichero o ruta dado:

$ gitk <path>

Localizar y restaurar ficheros borrados

$ git log --diff-filter=D --summary # Mostrar los ficheros borrados en los últimos commits $ git checkout <COMMIT>^ -- <path> # Restaurar un fichero borrado en un commit dado

El ^ al final del commit es para restaurar el fichero desde el commit anterior al que fue borrado. Equivale a ~1.

Guardar cambios actuales para recuperarlos después

Guarda los cambios desde el último commit. Al recuperarlos, si hay colisiones se hace un merge.

$ git stash # Guarda cambios hechos desde el ultimo commit $ git stash pop # Recupera los cambios guardados $ git stash list # Lista los estados guardados $ git stash apply # Aplica cambios guardados sin borrarlos de la lista

Marcar el commit actual (Tag)

$ git tag -s <nombre> -m <mensaje>

El tag queda firmado usando la firma GPG asociada al autor (ver Creating SSH keys).

El nombre identifica al tag y se usa en los demás comandos (ej. git checkout). Por ejemplo, v2.32.45r1

$ git tag # Mostrar lista de tags $ git tag -n # Mostrar lista y descripción

$ git tag -d <nombre> # Eliminar Tag $ git tag -a <nombre> # Crear Tag no firmado $ git push --tags # Subir Tags al repositorio remoto $ git push origin :refs/tags/<nombre> # Eliminar Tag borrado localmente

Localizar ficheros con una cadena de texto

$ git grep <texto> # Mira en todos los ficheros del repositorio $ git grep <texto> -- <ruta> # Mira sólo en la ruta o rutas especificadas # Admite patrones (ej. *.cpp)