Fundamentos de Git


Git es un sistema de control de versiones distribuído (scvd) escrito en C. El control de versiones es un sistema que registra los cambios realizados sobre un archivo o conjunto de archivos a lo largo del tiempo, de modo que puedas recuperar versiones específicas más adelante.

Podés, por ejemplo, cambiar la colección de archivos a un estado de 2 días atras, o podés cambiar entre los estados para caracteristicas experimentales y problemas de producción.

Git mantiene todas las versiones. Por lo tanto podés revertir a cualquier punto en la historia de tu código fuente usando Git.

Git realiza los commits a tu repositorio local y es posible sincronizar ese repositorio con otros (tal vez remotos) repositorios. Git te permite clonar los repositoriso, por ejemplo, crear una copia exacta de un repositorio incluyendo la historia completa del código fuente. Los dueños de los repositorios pueden sincronizar los cambios via push (transfiere los cambios al repositorio remoto) o pull (obtiene los cambios desde un repositorio remoto).

Git soporta el concepto de branching, es decir, podés tener varias versiones diferentes de tu código fuente. Si querés desarrollar una nueva característica, podés abrir un branch en tu código fuente y hacer los cambios en este branch sin afectar el principal desarrollo de tu código.


Conceptos Iniciales


  • Repositorio. Un repositorio contiene la historia, las diferentes versiones en el tiempo y todas los distintos branch y etiquetas. En Git, cada copia del repositorio es un repositorio completo. El repositoro te permite obtener revisiones en tu copia actual.

  • Branch. Un branch es una linea separada de código con su propia historia. Tambien es posible crear un nuevo branch de a partir de uno existente y cambiar el código independientemente de otros branches. Uno de los branches es el original (master). El usuario selecciona un branch y trabaja en ese branch seleccionado, el cual es llamado copia actual (working copy). Seleccionar un branch es llamado "obtener un branch" (checkout a branch).

  • Etiquetas. Un tag (una etiqueta) apunta a un cierto punto en el tiempo en un branch específico. Con un tag, es posible tener un punto con un tiempo al cual siempre sea posible revertir el código, por ejemplo, ponerle el tag "versión 1.0" al archivo.

  • Commit. Es confirmar los cambios de un archivo en un repositorio. Esto crea una revisión nueva la cual puede ser obtenida después, por ejemplo si querés ver el código fuente de una versión anterior. Cada commit contiene el autor y fecha en la que se realizó el commit, siendo así posible identificar el origen del cambio. 

Configuración

 

Para crear un nuevo repositorio con Git, vamos a crear un directorio llamado ejemplo. Entramos en él y con el comando git init inicializamos nuestro repositorio.


Git permite almacenar configuraciones globales en el archivo .gitconfig, en el cual no solo se guardan metadatos del usuario y preferencias, sino también los commits realizados.  El comando empleado es git config --global, como vemos a continuación.



Con el comando push.default define la acción que debe tomar git push si no se proporciona ninguna rama.  Al ponerlo como "current" push actualiza la rama actual.  Con el comando core.editor definimos el editor por defecto que usara Git para solicitarnos información, yo elegí nano, pero puede ser cualquiera, Sublime, Atom, Vim... Con el comando color.status se activará el resaltado de colores en la consola.


Iniciemos


Lo primero que vamos a hacer es crear algunos archivos dentro de nuestro repositorio y ver en que estado están con el comando git status.




Podemos ver que lo primero que nos dice es que estamos en la rama master luego nos dice que los archivos aun no han sido incluidos en el repositorio, y por esta razón la lista de archivos está en color rojo.  Para añadirlos usamos el comando git add.  Con este comando podemos añadir archivo por archivo usando su nombre, por ejemplo, para añadir archivo1.txt usamos git add arrchivo1.txt,  pero si lo que deseamos es añadir todos los archivos al mismo tiempo usamos git add . con lo cual tenemos:




Ahora vemos que la lista de archivos esta de color verde, lo que significa que estos archivos están incluidos en Git y listos para confirmarlos con un commit, entonces ahora vamos a realizar el commit.  Cuando confirmamos un archivo en nuestro repositorio es necesario poner un comentario, el cual da cuenta de los cambios que se han realizado en los archivos.  Para nuestro commit inicial usaremos como comentario "creando archivos."




Vemos que los tres archivos han sido agregados, y al ver el estado de nuestro repositorio nos dice que no hay archivos pendientes por agregar o por confirmar. Ahora modifiquemos el archivo1.txt, agregándole una linea, y veamos el estado que nos muestra git status.




Vemos que Git detecta el cambio en el archivo así que vamos a agregarlo y hacemos el commit.





Cuando hacemos el commit Git detecta que a cambiado, por eso nos dice que solo a cambiado un archivo y que en este se ha hecho una inserción, pero vemos que cometimos un error en el comentario con el que se hizo el commit. Para corregirlo usamos la opción amend del comando git commit.




Si queremos eliminar definitivamente un archivo de nuestro repositorio podemos usar el comando git rm archivo. Veamos un ejemplo borrando archivo3.txt




El archivo a sido borrado de nuestro directorio y Git esta listo para que le confirmemos esta acción con un commit. Si nosotros deseamos ver el historial de todos los commits que hemos realizado usamos el comando git log, el  cual nos muestra lo siguiente.





Podemos ver los tres commits que hemos realizado hasta ahora y algunos metadatos, como lo son el nombre y correo del autor, la fecha del commit, y algo muy util, el "sha" del commit, que esta en color amarillo. Una manera mas compacta de ver este historial es con el comando git log --oneline, el cual nos muestra la información de la siguiente manera:




Lo cual es mucho mas fácil de estudiar, en especial cuando nuestro historial sea muy grande.El sha (código amarillo) podemos usarlo para resetear un commit o para estudiar las diferencias entre distintas versiones de nuestros archivos, por ejemplo, vamos a añadir una segunda linea a nuestro archivo1.txt, y luego vamos a decirle a Git que compare esta versión con una anterior.  Esto lo hacemos con el comando git diff sha2 sha1 dode sha2 los sha corresponden a los commits que deseamos comparar.




Hemos comparado el sha del commit "Primer linea"  con el commit "segunda linea" y vemos que nos muestra en verde los cambios que Git encuentra entre los dos archivos.

Cuando hemos realizado un commit, pero deseamos quitarlo, podemos usar el comando git reset, el cual tiene tres variantes principales, soft, mixed y hard.  Veamos que hace cada uno de ellos. Supongamos que creamos un nuevo archivo y hacemos el commit. Si ahora deseamos cambiarlo, pero no queremos usar amend, sino borrarlo y volver a hacerlo entonces usamos git --soft sha1 donde sha1 es el sha desde el commit que deseamos hacer los cambios. Entonces primero veamos la lista de commits que tenemos.



Queremos cambiar el ultimo commit, así que el sha que elegimos es el correspondiente al commit "Segunda linea", con lo cual tenemos:





Vemos que nuestro archivo aun esta agregado en el repositorio y listo para ser confirmado con un nuevo commit, así que una ver realizado este commit podemos ver la lista de commits y notamos que ...



El commit que esta sobre "Segunda linea" ha cambiado y ahora tenemos nuestro nuevo commit.  Con la opción mixed no solo se borra el commit, sino que el archivo también sale del repositorio.  Veamos:



En esta ocasión el archivo esta de color rojo, lo que significa que no esta en nuestro repositorio Git, aunque aun esta presente en el directorio esperando a se agregado, y en la lista de commits vemos que también ha sido borrado.  Ahora si lo que deseamos es no solo borrar el commit sino el archivo también podemos usar git resert --hard sha.   Vemos lo que ocurre.



Vemos que con la opción --hard ell archivo queda totalmente eliminado,  pero aun así, Git nos permite recuperarlo si hemos escogido incorrectamente el sha que deseábamos borrar, pero para ello debemos conservar el sha del commit borrado. En nuestro ejemplo vemos que el sha correspondiente al commit "mi nuevo commit" es 1555a3c.  Lo que debemos hacer es ejecutar la misma linea anterior con este sha, y tendremos de nuevo nuestro archivo.  Veamos.



Vemos que tanto el archivo dentro de nuestro directorio como el commit han regresado.

Otra función interesante son las etiquetas, con estas podemos agrupar conjuntos de commits para versionar nuestros archivos. Para hacerlo usamos el comando git tag -a, por ejemplo, si deseamos poner la etiqueta "V1.1" lo hacemos con:




 Y para ver la lista de etiquetas que tenemos:



Finalmente si queremos borrar alguna etiqueta usamos git tag -d name donde name sera el nombre de la equiqueta a borrar.


Ramas

Las ramas en Git copias independientes del código principal que pueden ser modificadas sin afectar el código de otras ramas. Podemos pensar en las ramas como carpetas independientes que contienen copias del código. Cuando iniciamos un repositorio estamos por defecto en la rama principal, (master) y es por eso que en todos los ejemplos anteriores siempre hemos visto "master" entre paréntesis antes del prom. Para ver cuales ramas hay en nuestro repositorio usamos el comando git branch.


Como vemos, el comando nos muestra que solo tenemos una rama, y que estamos en ella, indicándolo con un asterisco al lado izquierdo del nombre de la rama. Para crear una nueva rama podemos hacerlo de dos maneras.  Si escribimos el nombre de la rama que deseamos crear a continuación del la palabra branch, esta se crea, pero permanecemos en la rama actual. 


Ahora vemos que tenemos una nueva rama, pero que aun estamos en master. Para cambiarnos de rama usamos el comando "checkout", veamos:


Vemos que al ejecutar el comando, cambiamos de rama, y al listar las ramas que tenemos en nuestro repositorio el asterisco esta al lado de nuestra nueva rama.  El comando "checkout" también nos sirve para crear ramas. con la opción "-b" este comando nos crea la rama y nos cambia de rama al mismo tiempo. Creemos  una rama llamada archivos y veamos.



Si deseamos borrar una rama debemos estar fuera de la rama que vamos a borrar.  Tenemos dos maneras de borrar "git branch --delete rama" o "git branch -d rama". Borremos entonces las dos ramas que tenemos.


La utilidad de las ramas se ve principalmente cuando estamos trabajando en equipo, así cada miembro del equipo puede tener su propia rama y así uno no dañar el código de alguno otro miembro del equipo. Como ejemplo creamos dos ramas, vamos a modificar cosas en una de las ramas y veremos que en las demás no se generaron esas modificaciones.


Primero vemos que en la rama1 tenemos tres archivos, los mismos que teníamos en master. Ahora creamos un nuevo archivo llamado "ramita.txt", lo añadimos al repositorio con "git add ." y realizamos el commit, una vez hecho esto nos vamos a la rama2, y podemos ver que en ella no existe el archivo "ramita.txt" ya que este solo pertenece a la rama1.


Ahora supongamos que el commit en la rama 1 debíamos realizarlo en la rama2, entonces podemos arreglar las cosas con el comando "git cherry-pick". Desde la rama1 con git log copiamos el sha del commit que necesitamos pasar a la rama2.


Luego nos pasamos a la rama2 y en ella --> "git cherry-pick sha",  y listo ese commit con su respectivo cambio estará en la rama2, y solo resta borrarlo de la rama1 usando "git reset --hard"



Bibliografía.

  • https://git-scm.com/
  • https://platzi.com/cursos/git-github/

Comentarios

Entradas populares de este blog

Método del Gradiente.

Undeflow y Overfolw