Instalación de Git en los distintos sistemas operativos

Os mentí, en subtitulo , no voy indicaros como instalar mas que en el sistemam operativo que utilizao, Linux y en terminal :-)

apt-get install git

Los demás sistema operativos lo iremos a ver si algún dia los pongo , pero como es tan facil desde terminal que da mucha pereza.

Lo instrucción anterior ya tienes todo listo para iniciar tu primer repositorio local.

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 experto, como un programador 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, pero quizas tu necesites:

  • Git config: Tanto configurar el usuario, como el email si en algún momento trabajas con repositorios remotos.
  • Git config: Para configurar para que no tenga en cuenta los permisos de los ficheros, ideal para aquellos proyectos que en un servidor tiene unos permisos y otros servidores tiene otros.
  • Gitignore : Un fichero que se crea para indicarle git que ficheros y cuales no va llevar un seguimiento.

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.

Empezar a trabajar con Git

Empezamos trabajar y realizamos cambios en nuestro código.

Para saber que fichero hemos añadido o modificado con la instruccion:

git status

Indicando los ficheros  modificados, eliminados y ficheros sin seguimiento en rojo, los que estan en verde es que ya los añadiste al seguimiento, con la siguiente instruccion:

git add .

Con esta instrucción, los ficheros eliminados no los añade al comit, nosotros utilizamos la instruccion pero con el parametro -i que mucho mas intuitiva. La explicamos un poco mas abajo.

Una vez añadidos con la instrucción anterior , 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.

Como ya comentamos , los ficheros eliminados no los añade directamente debemos eliminarlo de en el repositorio.

Recordar que aunque lo eliminemos del repositorio , si en algún momento queremos volver a recuperarlo, podemos en los commits anteriores.

Con las siguientes instrucciones podremos eliminar los fichero del repositorio:

git rm RutaNombreFicheroEliminado

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.

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

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 tiene muchas más opciones , muy interesantes.

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

git commit - m " Texto breve de los queremos comitar

El texto de descripción del comit debe ser claro y breve , que podamos reconocer rápidamente lo que hicimos, pero no siempre es posible que sea breve , por lo que si no ponemos  -m , no abre el editor nano, " me imagino que el que tengamos por defecto git".

¿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 loos cambios de todos los ficheros, pero siempre con respeto al ultimos commit.

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

 

¿ 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

 

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)

 

Otras anotaciones :

   # Listar todas las ramas $ git branch -v    # Mostrar último commit en cada rama y su situación respecto a su rama remota (si hay) $ git branch --merged # Mostrar ramas que se han fusionado con la actual, y por tanto pueden borrarse $ git branch --no-merged # Mostrar ramas con trabajos sin funsionar. Intentar borrarlas dará un error.

$ git checkout <COMMIT> # No toca los cambios locales $ git checkout -f <COMMIT> # Sobreescribe los cambios locales

Se puede hacer una rama desde el commit actual para continuar el desarrollo (git branch). Si se hacen cambios en un commit intermedio (no es un HEAD) y se commitean sin hacer una rama, se crea un commit separado que sale del actual (rama sin nombre).

 

Link de referencia:

Podemos encontrarlo en Git, guia rapida.

1. Trabajo con repositorios remotos.

2. Tareas especiales.