Regresar a un commit anterior en Git

Muchas veces, nos damos cuenta de que necesitamos regresar en el tiempo  a un punto de nuestro proyecto, para ello el comando checkout nos permite  regresar a un commit anterior en Git,  de esta manera:

git checkout 766abcd

766abcd, es el identificador del commit al que deseamos regresar. Esta operación, si lo hacemos desde  una rama, no afectará a otras, de modo que puedes hacer diferentes commit a partir de ese punto, sin que se modifiquen otras ramas  del proyecto. 

Existen diferentes formas de retroceder en el tiempo a commits previos, checkout es una de ellas, pero tambien se utiliza reset con sus atributos soft o hard

Con una sintaxis como:

git reset—soft referencia del commit

Esto nos permitirá retroceder a un commit previo, manteniendo los cambios:

git reset—soft 568abcj

Si queremos deshacer solo el ultimo:

git reset—soft HEAD~

Si lo que se desea es eliminar permanentemente los cambios realizado después de un commit  específico, el comando a usar es:

git reset—hard 789abcd

Si queremos eliminar los cambios después del ultimo commit lo que hacemos es usar el atributo hard del comando reset, pero dirigiéndolo al apuntador especial HEAD. 

git reset—hard HEAD~

para descartar los cambios antes de retornar a un commit, se utiliza el comando stash

git commit stash

Debemos recordar siempre que poseemos una valiosa herramienta, para obtener información sobre el estado y la estructura del árbol del proyecto, que es el comando log.  

Ver mas sobre Git

Podemos ver la estructura de los últimos commit con este comando

git log --oneline 

Su salida, será algo como esto

8674e5f commit  test3
jº44568 commit segunda parte 
55df4c2 commit de inicio. 

El conocimieno y el uso de log con sus diferente posibilidades, nos permitirá manejar acertadamente, la creación de ramas, los movimientos entre ellas y los avances y retrocesos entre commits.

Y listo, esto es todo.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias.

Subir montañas hermana hombres……

Git, el concepto de branch

Sabemos que Git nos ofrece un sistema de ramas o  branchs,  que  al igual que otras herramientas de control de versiones, soporta la administración de ramificaciones en los proyectos.

Sin ánimo de ahondar demasiado, digamos que la diferencia básica que Git aporta, es que en vez de crear un directorio adicional para guardar una nueva rama, lo hace de forma inmediata sin crear nuevos directorios,  almacenando solo copias instantáneas, de como está el archivo en ese momento, junto a  los nodos padres, lo cual también es una gran ventaja, al momento de gestionar la fusión entre las ramas con que contamos.

¿Que son las ramas?

Podríamos decir, si queremos ser muy escuetos que:  una rama  en Git es solo  un apuntador en movimiento que redirige a su respectivo commit.

Lo explico así: al  iniciar un proyecto y hacer tu primer commit, estas creando una rama principal de trabajo, también llamada master.

A medida que creas tu código,  y vas avanzando buscando una solución, tal vez necesites caminos alternativos, que te lleven a determinado punto y hasta tanto  no lo alcances, no   querrás  incorporarlo a lo que has hecho en tu rama principal, incluso pudiera ser que nunca alcances ese punto, y simplemente necesites regresar adonde estabas antes.

Esto es posible hacerlo creando ramas de trabajo, o sea cada vez que creas una alternativa, podemos decir que estás trabajando en una rama, si a eso unimos, que sobre el propio proyecto, pueden estar trabajando diferentes integrantes de un equipo, tendremos varias ramificaciones, y al mismo tiempo  si cada uno de ellos quiere probar nuevas rutas para buscar un resultado  esperado, entonces crearán nuevas ramas, en un mismo árbol de proyecto.

Lo que hace a Git superior a otros,  es el modo rápido y eficaz en que maneja las ramificaciones, haciendo el avance o el retroceso entre distintas ramas, algo ágil , cómodo y sencillo, lo cual facilita   que durante el  desarrollo, las ramas puedan crearse y unirse entre si, tantas veces como necesitemos.

Es fácil entender entonces, que este enorme potencial es de gran ayuda, para agilizar y fortalecer el modo en que creamos código.  

El valor  del Commit

Al escribir git add . estas indicando a git que pase tus archivos a la zona conocida como stage, pero  lo que sucede realmente es que  se ejecuta una suma de control de ellos, en 40 caracteres (un resumen SHA-1), y se  almacena un blob (copia) de cada uno en el repositorio,  guardando cada suma de control, en el área de preparación (staging area):

Al crear una orden de confirmación  commit, estamos diciéndole a Git  que aceptamos  que los cambios añadidos previamente con el add al  área stage,  sean procesados,  y lo que hará el sistema es crear  y almacenar una impresión  del código de ese momento, con un grupo de metadatos explicativos como los que recoge la opción –m.

Nuestro commit, también creará un apuntador hacia esta impresión instantánea (piensa en una foto de ese momento), que permitirá identificarla, retornarla, o unirla a otra; o los apuntadores podrían ser varios, si lo que hay detrás de nuestro commit, es un merge que une varias ramas.

Suponiendo que estuvieras  trabajando con 5 subdirectorios, lo que sucederá al hacer commit es que Git realizará  sumas de cada uno, que  guardará  como objetos árbol en el repositorio Git y creará un objeto de confirmación con los metadatos y  además un apuntador al objeto árbol de la raíz del proyecto.

Hecho esto,  ahora  habría 7 objetos en el repositorio de tu proyecto, los 5 blobs, un árbol que no es más que la lista estructurada de lo  que contiene el repositorio, y la confirmación  de los cambios que el commit procesó  y que apunta directamente  a la raíz del árbol.

Entonces, si decides hacer más cambios y confirmarlos, el siguiente commit también tendrá un apuntador que se dirige al commit previo, de esa manera queda encadenado a la versión anterior y así sucesivamente.

 Por tanto, la  rama se mantiene en movimiento avanzando en cada commit, ese desplazamiento comienza al crear  la rama principal master, con el primer commit.

 ¿Cómo se crea una rama?

El comando utilizado para crear una rama es :

git branch nombre de la rama

Este comando lo que hará será crear un nuevo apuntador, disponible para que dirija al ultimo commit que has realizado.

Para crear la rama nuevo_test, escribe:  

$ git branch nuevo_test

El nuevo apuntador, dirigirá  al commit en el que estés. 

Aunque pueda parecer complicado, no lo es.

En este punto, habrá dos ramas, cada una con su apuntador que refieren al mismo commit, sin embargo la magia está en que existe un apuntador llamado HEAD, con una labor especial que es la de apuntar a la rama local en la que te encuentres, en este caso master, pues aunque se creó la rama nuevo_test, con el comando branch, aun no se ha entrado a ella.

El comando que maneja los logs, y que debemos tener siempre a mano para saber cómo vamos, y entre otras cosas, la estructura de nuestro árbol de proyecto:   git log , en su opción --decorate nos mostrará la estructura

Por ejemplo nos devolverá algo como esto

$ git log --oneline --decorate
g40ac (HEAD, master, nuevo_test) add feature ………. 

Donde g40ac  será el commit al que apuntan ambas ramas. 

Moviendose entre ramas

Para moverse de una rama a la otra el comando a usar es :

git checkout 

y la sintaxis si queremos ir a la rama nuevo_test es :

$ git checkout nuevo_test

Ahora el apuntador se apuntará a la rama nuevo_test

Si hacemos ahora un commit

$ git commit -a -m 'primer cambio'

Y corremos nuevamente log --decorate veremos que la rama nuevo_test apunta al  nuevo commit junto al apuntado HEAD.

 Si queremos regresar a la rama master, utilizaremos igualmente checkout, al hacerlo, se moverá nuevamente el apuntador HEAD a la rama master, y restituirá los archivos  dejándolos tal y como estaban en el último commit de esa rama principal.

Esto, no es otra cosa que rebobinar el proyecto, dando marcha atrás en el tiempo, por tanto  los cambios que hagas en adelante, serán diferentes de la versión anterior  del proyecto.  

Otro aspecto importante de Git,  es que si no es capaz de realizar este rebobinado de un modo limpio, o sea si no puede recuperar la impresión exacta del ultimo commit, no permitirá hacer el checkout.

En definitiva para moverte entre ramas los comando son tres, branch que crea la rama, commit que la confirma y checkout que te permite saltar de una a otra

Por supuesto al saltar entre ramas, cada  rama  tendrá diferencias en tu labor, para ver las diferencias podemos usar el comando log de este modo:

 git log --oneline --decorate --graph –all

Esto mostrará el historial de los commit, indicando dónde están los apuntadores de cada ramas y como ha variado el historial.

Si ahora analizamos lo que dijimos al inicio, sobre el modo en que se compone una rama, desde el punto de vista estructural, comprenderemos porque una rama Git es un simple archivo, con  los 40 caracteres de una suma de control SHA-1,  vinculado a un commit específico.

De ahí su simpleza,  velocidad y  eficiencia.

Y listo, esto es todo.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias.

 ….un sueño es casi todo  y más que  nada;  más que todo al soñarlo, casi nada después……

Añadir un repositorio en git a Github

En dos  articulos anteriores, hable sobre los principales comandos de Git, hoy explicare muy concretamente como subir un repositorio a Github.

Necesitamos para ello,  realizar dos acciones:

  •  vincular nuestro repositorio local a un repositorio remoto, y…
  • empujarlo  (push) o colocarlo  allí, ya sea a una rama (branch) o directamente al master que  el la rama principal.

Para ello usaremos dos comandos

git remote add origin

 Se encargará de asociar  el respositorio original con el repositorio remoto en github

Smart Black Power@DESKTOP-695M5L3 MINGW64/H/desarrollo/sierra_maestra(master)                                                                                                                                                                       $ git remote add origin https://github.com/FrankGalanDev/sierraMaestra.git

y el comando:

$ git push -u origin master

que empuja al respositorio remoto creado previamente en github, el contenido del nuestro respositorio local .

Smart Black Power@DESKTOP-695M5L3 MINGW64/H/desarrollo/sierra_maestra (master)                                                                                                                                                                               $ git push -u origin master

Y listo, esto es todo.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias.

…..lo que realmente importa no es lo que te da la vida, sino lo que haces con ello….

Trabajar en remoto con Git

Trabajar en remoto con Git,  es como todo el que se mueve en el mundo de la programación sabe, una necesidad imperativa.

Este gestor de versiones, posee entre una de sus características más potentes, que permite la participación de diferentes integrantes de un equipo en el desarrollo, a través del uso de branchs(ramas),  lo cual enriquece enormemente las potencialidades de la colaboración.

Este es aún más interesante y útil si trabajamos con  repositorios,   hospedados en la red de internet u otra cualquiera de acceso remoto. 

Los comandos que muestro hoy son para eso, o sea los que utiliza Git para conectar y trabajar con repositorios remotos.

Ya que podemos tener tantos repositorios remotos como deseemos,  podremos tener tantas versiones de nuestro código como consideremos necesario, para lo cual vamos a precisar de un flujo de información flúido, sobre todo si vamos a interactuar con varios compañeros.

Aquí algunos de los  comandos:

git remote 

Muestra los nombres de los remotos que posees vinculados, o qué tienes especificado en git.

$ git remote -v

Devuelve  las URLs que Git ha asociado al repositorio remoto. Son las que usará para interactuar con él.  

git clone

Clona un repositorio en la dirección que le des: la sintáxis es:

git clone https://github.com/tu repositorio destino

Si luego de clonar, llamas al comando  remote, debe mostrar como mínimo el repositorio del que ha clonado, y lo hará nombrará origin

git remote add [nombre] [url]:

Añade un repositorio remoto

  git fetch [remote-name] 

Devuelve los datos de tus proyectos remotos.

Este comando, trae al nuestro, los datos de los proyectos alojados en los repositorios remotos, por lo que a partir de ese momento dispondremos de  referencias a todas las ramas de ese remoto, con la posibilidad de poder inspeccionarlas o combinarlas

git fetch origin

En este caso por ejemplo, nos trae todo el trabajo nuevo que ha sido enviado a ese servidor desde que lo clonamos, o desde la última vez que trajimos datos de el.

Es importante destacar que el comando git fetch solo trae datos a nuestro, repositorio local, pero no lo combina automáticamente con el proyecto que estamos desarrollando, ni tampoco actualiza lo que tengamos ya creado.

La combinación debe hacerse de mod manual.

aj https://github.com/Antonio_J/test (fetch)
aj https://github.com/antonio_J/test (push)

Con este comando asignamos el alias aj a este repositorio, y ya podemos usar ese nombre para  enviar o traer datos en función de los permisos que tengamos.

Entonces para traer la información que tiene Antonio, podríamos hacer esto sencillamente:

$ git fetch aj

 Esto nos dara al final algo como esto

* [new branch]      master     -> aj/master
* [newbranch]      test    -> aj/test

Ahora podemos acceder localmente a la rama maestra de Antonio,   con el nombre aj/master, de igual modo, esta queda disponible para que podamos combinarla con alguna rama nuestra o    inspeccionarla.

git push [nombre-remoto] [nombre-rama

Envía  un proyecto a un servidor. Si  por ejemplo lo que quieres  es enviar tu rama master a tu servidor origin, debes ejecutar:

$ git push origin master

Este comando funciona solo en servidores clonados sobre los que tenemos permisos de escritura.

Una cuestión importante, es que funciona solo si nadie con los mismos  permisos  ha enviado datos entretanto.

Si un compañero clona el mismo repositorio y envía información antes que nosotros, no podremos enviar porque será rechazado.

La solucion más fácil  a esto, es hacer un fetch al compañero para bajar su código, combinarlo con el que tenemos y entonces hacer el push al servidor.  

git remote show [nombre-remoto]

Nos devuelve información sobre un servidor remoto especifico.

git remote show:

Nos da información sobre todos los servidores remotos y sus proyectos

Entre la información que nos brinda, nos dirá a cuál rama estamos enviando la información cuando ejecutamos  git push, también nos dice cualés ramas remotas aún no tenemos,  las  que serán combinadas si ejecutamos ejecutes git pull, y las que  han sido eliminadas del servidor.

git remote rename.

Modifica  el nombre de la referencia de un remoto, con la sintaxis :

git remote rename aj antonio

Hemos renombrado el remoto aj como antonio

git remote rm aj

Elimina un remoto

Y listo, esto es todo.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias.

…., si avanzo sígueme, si me detengo empújame, si retrocedo mátame…….

Otros comandos de git

Este articulo da continuación a otro que publique, e intentaré hablar de otros comandos de Git.

Continuaremos pues con otros comandos también muy importantes en Git

git log

Permite ver los operaciones que hemos realizado:

git log --oneline

Como resultado nos traerá los commit realizados:

El primer conjunto de letras y números que veremos, a la izquierda es el id del commit, que nos servirá para identificar el commit y si es necesario volcer a un estado anterior a el. Entre paréntesis nos mostrará la rama a la que pertenece el commit y a continuación el mensaje que le agregamos

git commit –amend

Nos permite rectitficar un commit, ya sea que nos hemos equivocado en un detalle importante, en el mensaje, u otra cosa; con este comando rectificaremos, mediante el uso del parametro --amend

git commit --amend -m "Estoy corrigiendo cosas entre ellas mensaje"

git checkout id_commit

Es el comando  que usa git para volver a un commit anterior, o estado anterior a ese commit:

Este potente comando, es el que necesitamos todos, cuando algo falla sin que podamos saber que es, y necesitamos volver a ese momento en que todo funcionaba.

Al regresar se revertirán todos los cambios; si hemos eliminado archivos del  proyecto en el que trabajamos estos se recuperaran o viceversa si se han añadido, desaparecerán al retornar a una posición anterior en el tiempo. 

Y listo, esto es todo.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias.

….un sueño es casi todo  y más que  nada, más que todo al soñarlo, casi nada después……

Git, comandos mas importantes

Los comandos  más  importantes de Git, son aquellos que nos ayudan a crear nuestro repositorio, actualizarlo y publicarlo, permitiéndonos su total control, seamos freelance o un equipo de trabajo.

Resumiendo como trabaja git, diré que :

Git controla versiones  en un repositorio local, siguiendo una estructura de edición, preparación y confirmación de acciones sobre el.

Cuando estas programando y estas listo para añadir cambios los preparas con git add . que los coloca en estado stage, o sea  como una copia instantánea lista, la cual solo valdrá si la confirmas con git commit, o será rechazada si la deshaces con git reset. Esta confirmación se guardará  en el historial de proyecto y será entonces si tienes un repositorio remoto cuando usaras git push para enviarlo allí.

No voy a ahondar mucho mas en el tema teorico de que  es git, ni porque se necesitas, o no.

Lo cierto es que si trabajas  en proyectos cortos, tu solo, y manejas bien las versiones de lo que haces con las carpetas en tu ordenador,  bien documentadas,  no lo necesitas obligatoriamente, sin embargo si desarrollas junto a un grupo de desarrolladores, con muchos cambios y participación en el código, manejos de variantes,  etc , git es una excelente opción.

Los comandos que muestro aquí son solo unos pocos, pero que te permitirán saber como funciona git  de modo básico y espero que útil.

Asumo que has instalado git que no tiene mayores complicaciones y estás en la consola.

Git init

Ve hastas la carpeta  donde esta tu código y escribe

git  init 

Te creará un repositorio creará un repositorio local vacio,  dentro de la carpeta donde tenemos el proyecto, con un mensaje como este

 Smart Black Power@DESKTOP-695M5L3 MINGW64 /H/desarrollo/sierra_maestra
 $ git init 
 Initialized empty Git repository in H:/desarrollo/sierra_maestra/.git/ 

Al mismo tiempo se habrá creado una  carpeta oculta llamada .git, que  es la encargada de gestionar el repositorio que acabamos de crear. Si quieres dejar de utilizar git, borra esa carpeta y listo, si quieres volver a utilizarlo vuelve a crear el repositorio con : git init

Para ver las carpetas ocultas utiliza el comando:  ls -a.

 Smart Black Power@DESKTOP-695M5L3 MINGW64 /H/desarrollo/sierra_maestra (master)
 $ ls -a
  ./.git/js/'plantilla sierra maestra V1.html' 
 ../css/'Plantilla pag web 1.psd'   plantilla-sierra-maestra-1.jpg 

Para conocer el estado del repositorio, los commit realizados , escribe

git status

El resultado como no has hecho nada aun en el repositorio será:

  Smart Black Power@DESKTOP-695M5L3 MINGW64 /H/desarrollo/sierra_maestra (master)
 $ git status
 On branch master
  
 No commits yet
  
 Untracked files:
   (use "git add <file>..." to include in what will be committed)
         Plantilla pag web 1.psd
         css/
         js/
         plantilla sierra maestra V1.html
         plantilla-sierra-maestra-1.jpg
  
 nothing added to commit but untracked files present (use "git add" to track) 

Lo primero que vemos es “On branch master” esto significa que estamos en la rama principal, es la rama por defecto cuando creamos un repositorio.Git tiene dos procesos para gestionar nuestros archivos. Primero los tenemos que añadir a una zona intermedia conocida como stage y después tenemos que confirmar el paso  definitivo de los archivos al repositorio.

Nota:

Branch : rama de proyecto, puedes crear tantas como desees, y después desecharlas o llevarlas  al proyecto

Master: rama original  y principal del proyecto y la que ese establece por defecto.

git add

git add .

Importante: Hay que dejar un espacio entre add y el punto”

Con este comando le decimos a git que pase todos los archivos que estén sin pasar al estado stage.

 Smart Black Power@DESKTOP-695M5L3 MINGW64 /H/desarrollo/sierra_maestra (master)
 $ git add .
 warning: LF will be replaced by CRLF in css/bootstrap-grid.css. The file will have its original line endings in your working directory
 warning: LF will be replaced by CRLF in css/bootstrap-grid.min.css.
 The file will have its original line endings in your working directory
 warning: LF will be replaced by CRLF in css/bootstrap-reboot.css.
 The file will have its original line endings in your working directory
 warning: LF will be replaced by CRLF in css/bootstrap-reboot.min.css. ...........

Si ahora volvemos ejecutar el comando git status obtendremos algo como esto:

  Smart Black Power@DESKTOP-695M5L3 MINGW64 /H/desarrollo/sierra_maestra (master)
 $ git status
 On branch master
  
 No commits yet
  
 Changes to be committed:
   (use "git rm --cached <file>..." to unstage)
         new file:   Plantilla pag web 1.psd
         new file:   css/bootstrap-grid.css
         new file:   css/bootstrap-grid.css.map
         new file:   css/bootstrap-grid.min.css
         new file:   css/bootstrap-grid.min.css.map
         new file:   css/bootstrap-reboot.css
         new file:   css/bootstrap-reboot.css.map
      .............

git commit  

Para confirmar estos archivos y que pasen  definitivamente al  repositorio,  utilizamos como ya dijimos  commit .

Utilizamos el parámetro -m para indicarle una descripción del commit que vamos a hacer, en este caso le decimos que es el commit inicial del proyecto.

 Smart Black Power@DESKTOP-695M5L3 MINGW64 /H/desarrollo/sierra_maestra (master)
 $ git commit -m "Commit inicial del proyecto"
 [master (root-commit) 9e33f1e] Commit inicial del proyecto
  25 files changed, 36210 insertions(+)
  create mode 100644 Plantilla pag web 1.psd
  create mode 100644 css/bootstrap-grid.css
  create mode 100644 css/bootstrap-grid.css.map
  create mode 100644 css/bootstrap-grid.min.css
  create mode 100644 css/bootstrap-grid.min.css.map
  create mode 100644 css/bootstrap-reboot.css
  create mode 100644 css/bootstrap-reboot.css.map
  create mode 100644 css/bootstrap-reboot.min.css
  create mode 100644 css/bootstrap-reboot.min.css.map
  create mode 100644 css/bootstrap.css
  create mode 100644 css/bootstrap.css.map
.............

Si no indicamos el parámetro -m se abrirá un editor de código de terminal  que hayamos definido como editor por defecto puede ser Vim u otro, deberemos escribir  el mensaje Si volvemos a ejecutar el comando git status obtendremos este mensaje:

 Smart Black Power@DESKTOP-695M5L3 MINGW64 /H/desarrollo/sierra_maestra (master)
 $ git status
 On branch master
 nothing to commit, working tree clean 

Esto significa que no hay nada para confirmar, es decir que todos los archivos se encuentran ya en el repositorio.

En resumen

git  add: Añade modificaciones al codigo

commit:  Confirma las modificaciones en el código.

Usa: git commit -m”comentarios sobre el commit”  como buena practica

Push:  añadir un proyecto, código o modificación al repositorio externo, por ejemplo github

Y listo, esto es todo.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias.

…., si avanzo sígueme, si me detengo empújame, si retrocedo mátame…….