• ¡Obtenga la seguridad de la aplicación de la manera correcta! Detectar, proteger, monitorear, acelerar y más ...
  • En este artículo, aprenderá diferentes formas de jugar con las confirmaciones en Git.

    Como desarrollador, se habría enfrentado a situaciones de este tipo varias veces en las que hubiera querido volver a una de sus confirmaciones anteriores, pero no estaba seguro de cómo hacerlo. E incluso si conoces el ir comandos como reset, revert, rebase, no es consciente de las diferencias entre ellos. Así que comencemos y entendamos qué son git reset, revert y rebase.

    Restablecimiento de Git

    Git reset es un comando complejo y se usa para deshacer los cambios.

    Puedes pensar en git reset como una función de reversión. Con git reset, puedes saltar entre varias confirmaciones. Hay tres modos de ejecutar un comando git reset: –soft, –mixed y –hard. De forma predeterminada, el comando git reset usa el modo mixto. En un flujo de trabajo de reinicio de git, tres mecanismos de administración internos de git entran en escena: CABEZA, área de ensayo (índice) y el directorio de trabajo.

    reinicio de git - geekflare

    El directorio de trabajo es el lugar donde está trabajando actualmente, es el lugar donde están presentes sus archivos. Usando un comando de estado de git, puede ver qué archivos / carpetas están presentes en el directorio de trabajo.

    El área de ensayo (índice) es donde git rastrea y guarda todos los cambios en los archivos. Los cambios guardados se reflejan en el directorio .git. Utiliza git add "nombre de archivo" para agregar el archivo al área de ensayo. Y como antes, cuando ejecute git status, verá qué archivos están presentes en el área de prueba.

    La rama actual en Git se conoce como HEAD. Apunta a la última confirmación, que ocurrió en la rama de pago actual. Se trata como un puntero para cualquier referencia. Una vez que realiza el pago a otra sucursal, el HEAD también se mueve a la nueva sucursal.

    Permítanme explicar cómo funciona git reset en los modos duro, suave y mixto. El modo difícil se usa para ir a la confirmación puntual, el directorio de trabajo se llena con los archivos de esa confirmación y el área de preparación se restablece. En el restablecimiento parcial, solo el puntero se cambia a la confirmación especificada. Los archivos de todas las confirmaciones permanecen en el directorio de trabajo y el área de preparación antes del reinicio. En el modo mixto (predeterminado), el puntero y el área de preparación se restablecen.

    Restablecer duro de Git

    El propósito de git hard reset es mover HEAD a la confirmación especificada. Eliminará todas las confirmaciones que ocurrieron después de la confirmación especificada. Este comando cambiará el historial de confirmaciones y apuntará a la confirmación especificada.

    En este ejemplo, agregaré tres archivos nuevos, los confirmaré y luego realizaré un restablecimiento completo.

    Como puede ver en el siguiente comando, en este momento, no hay nada que confirmar.

    $ git status
    On branch master
    Your branch is ahead of 'origin/master' by 2 commits.
    
    (use "git push" to publish your local commits)
    
    nothing to commit, working tree clean

    Ahora, crearé 3 archivos y agregaré algo de contenido.

    $ vi file1.txt
    $ vi file2.txt
    $ vi file3.txt

    Agregue estos archivos al repositorio existente.

    $ git add file*

    Cuando vuelva a ejecutar el comando de estado, reflejará los nuevos archivos que acabo de crear.

    $ git status
    On branch master
    Your branch is ahead of 'origin/master' by 2 commits.
    
    (use "git push" to publish your local commits)
    
    Changes to be committed:
    
    (use "git restore --staged <file>..." to unstage)
    
    new file:
    file1.txt
    
    new file:
    file2.txt
    
    new file:
    file3.txt

    Antes de comprometerme, déjame mostrarte, actualmente tengo un registro de 3 confirmaciones en Git.

    $ git log --oneline
    0db602e (HEAD -> master) one more commit
    59c86c9 new commit
    e2f44fc (origin/master, origin/HEAD) test

    Ahora, me comprometeré con el repositorio.

    $ git commit -m 'added 3 files'
    [master d69950b] added 3 files
    3 files changed, 3 insertions(+)
    create mode 100644 file1.txt
    create mode 100644 file2.txt
    create mode 100644 file3.txt

    Si utilizo ls-files, verá que se han agregado los nuevos archivos.

    $ git ls-files
    demo
    dummyfile
    newfile
    file1.txt
    file2.txt
    file3.txt

    Cuando ejecuto el comando log en git, tengo 4 confirmaciones y HEAD apunta a la última confirmación.

    $ git log --oneline
    d69950b (HEAD -> master) added 3 files
    0db602e one more commit
    59c86c9 new commit
    e2f44fc (origin/master, origin/HEAD) test

    Si voy y elimino el file1.txt manualmente y hago un estado de git, mostrará el mensaje de que los cambios no están preparados para su confirmación.

    $ git status
    On branch master
    Your branch is ahead of 'origin/master' by 3 commits.
    
    (use "git push" to publish your local commits)
    
    Changes not staged for commit:
    
    (use "git add/rm <file>..." to update what will be committed)
    
    (use "git restore <file>..." to discard changes in working directory)
    
    deleted:
    file1.txt
    
    no changes added to commit (use "git add" and/or "git commit -a")

    Ahora, ejecutaré el comando de restablecimiento completo.

    $ git reset --hard
    HEAD is now at d69950b added 3 files

    Si vuelvo a comprobar el estado, descubriré que no hay nada que confirmar y el archivo que eliminé ha vuelto al repositorio. La reversión ocurrió porque después de eliminar el archivo, no me comprometí, por lo que después de un restablecimiento completo, volvió al estado anterior.

    $ git status
    On branch master
    Your branch is ahead of 'origin/master' by 3 commits.
    
    (use "git push" to publish your local commits)
    
    nothing to commit, working tree clean

    Si reviso el registro de git, así es como se verá.

    $ git log
    commit d69950b7ea406a97499e07f9b28082db9db0b387 (HEAD -> master)
    Author: mrgeek <[email protected]>
    Date:
    Mon May 17 19:53:31 2020 +0530
    
    added 3 files
    
    commit 0db602e085a4d59cfa9393abac41ff5fd7afcb14
    Author: mrgeek <[email protected]>
    Date:
    Mon May 17 01:04:13 2020 +0530
    
    one more commit
    
    commit 59c86c96a82589bad5ecba7668ad38aa684ab323
    Author: mrgeek <[email protected]>
    Date:
    Mon May 17 00:54:53 2020 +0530
    
    new commit
    
    commit e2f44fca2f8afad8e4d73df6b72111f2f2fd71ad (origin/master, origin/HEAD)
    Author: mrgeek <[email protected]>
    Date:
    Mon May 17 00:16:33 2020 +0530
    
    test

    El propósito del restablecimiento completo es apuntar a la confirmación especificada y actualizar el directorio de trabajo y el área de prueba. Déjame mostrarte un ejemplo más. Actualmente, la visualización de mis confirmaciones se ve a continuación:

    git hard

    Aquí, ejecutaré el comando con HEAD ^, lo que significa que quiero restablecer la confirmación anterior (una confirmación posterior).

    $ git reset --hard HEAD^
    HEAD is now at 0db602e one more commit

    Puede ver que el puntero principal ahora ha cambiado a 0db602e desde d69950b.

    $ git log --oneline
    0db602e (HEAD -> master) one more commit
    59c86c9 new commit
    e2f44fc (origin/master, origin/HEAD) test

    git hard 1

    Si comprueba el registro, la confirmación de d69950b desaparecerá y el encabezado ahora apunta a 0db602e SHA.

    $ git log
    commit 0db602e085a4d59cfa9393abac41ff5fd7afcb14 (HEAD -> master)
    Author: mrgeek <[email protected]>
    Date:
    Mon May 17 01:04:13 2020 +0530
    
    one more commit
    
    commit 59c86c96a82589bad5ecba7668ad38aa684ab323
    Author: mrgeek <[email protected]>
    Date:
    Mon May 17 00:54:53 2020 +0530
    
    new commit
    
    commit e2f44fca2f8afad8e4d73df6b72111f2f2fd71ad (origin/master, origin/HEAD)
    Author: mrgeek <[email protected]>
    Date:
    Mon May 17 00:16:33 2020 +0530
    
    Test

    Si ejecuta ls-files, puede ver que file1.txt, file2.txt y files3.txt ya no están en el repositorio porque esa confirmación y su archivo se eliminaron después del restablecimiento completo.

    $ git ls-files
    demo
    dummyfile
    newfile

    Reinicio suave de Git

    Del mismo modo, ahora les mostraré un ejemplo de un reinicio por software. Considere, he agregado los 3 archivos nuevamente como se mencionó anteriormente y los comprometí. El registro de git aparecerá como se muestra a continuación. Puede ver que 'reinicio suave' es mi última confirmación, y HEAD también apunta a eso.

    $ git log --oneline
    aa40085 (HEAD -> master) soft reset
    0db602e one more commit
    59c86c9 new commit
    e2f44fc (origin/master, origin/HEAD) test

    Los detalles de la confirmación en el registro se pueden ver usando el siguiente comando.

    $ git log
    commit aa400858aab3927e79116941c715749780a59fc9 (HEAD -> master)
    Author: mrgeek <[email protected]>
    Date:
    Mon May 17 21:01:36 2020 +0530
    
    soft reset
    
    commit 0db602e085a4d59cfa9393abac41ff5fd7afcb14
    Author: mrgeek <[email protected]>
    Date:
    Mon May 17 01:04:13 2020 +0530
    
    one more commit
    
    commit 59c86c96a82589bad5ecba7668ad38aa684ab323
    Author: mrgeek <[email protected]>
    Date:
    Mon May 17 00:54:53 2020 +0530
    
    new commit
    
    commit e2f44fca2f8afad8e4d73df6b72111f2f2fd71ad (origin/master, origin/HEAD)
    Author: mrgeek <[email protected]>
    Date:
    Mon May 17 00:16:33 2020 +0530
    
    test

    Ahora, usando el reinicio por software, quiero cambiar a una de las confirmaciones más antiguas con SHA 0db602e085a4d59cfa9393abac41ff5fd7afcb14

    Para hacer eso, ejecutaré el siguiente comando. Debe pasar más de 6 caracteres iniciales de SHA, no se requiere el SHA completo.

    $ git reset --soft 0db602e085a4

    Ahora, cuando ejecuto el registro de git, puedo ver que HEAD se ha restablecido a la confirmación que especifiqué.

    $ git log
    commit 0db602e085a4d59cfa9393abac41ff5fd7afcb14 (HEAD -> master)
    Author: mrgeek <[email protected]>
    Date:
    Mon May 17 01:04:13 2020 +0530
    
    one more commit
    
    commit 59c86c96a82589bad5ecba7668ad38aa684ab323
    Author: mrgeek <[email protected]>
    Date:
    Mon May 17 00:54:53 2020 +0530
    
    new commit
    
    commit e2f44fca2f8afad8e4d73df6b72111f2f2fd71ad (origin/master, origin/HEAD)
    Author: mrgeek <[email protected]>
    Date:
    Mon May 17 00:16:33 2020 +0530
    
    test

    Pero la diferencia aquí es que los archivos de la confirmación (aa400858aab3927e79116941c715749780a59fc9) donde había agregado 3 archivos todavía están en mi directorio de trabajo. No se han eliminado. Es por eso que debe usar un restablecimiento parcial en lugar de un restablecimiento completo. No hay riesgo de perder los archivos en el modo suave.

    $ git ls-files
    demo
    dummyfile
    file1.txt
    file2.txt
    file3.txt
    newfile

    Git Revert

    En Git, el comando revert se usa para realizar una operación de reversión, es decir, para revertir algunos cambios. Es similar al comando de reinicio, pero la única diferencia aquí es que realiza una nueva confirmación para volver a una confirmación en particular. En resumen, es justo decir que el comando git revert es una confirmación.

    El comando de reversión de Git no elimina ningún dato mientras se realiza la operación de reversión.

    Digamos que estoy agregando 3 archivos y realizando una operación de confirmación de git para el ejemplo de reversión.

    $ git commit -m 'add 3 files again'
    [master 812335d] add 3 files again
    3 files changed, 3 insertions(+)
    create mode 100644 file1.txt
    create mode 100644 file2.txt
    create mode 100644 file3.txt

    El registro mostrará la nueva confirmación.

    $ git log --oneline
    812335d (HEAD -> master) add 3 files again
    0db602e one more commit
    59c86c9 new commit
    e2f44fc (origin/master, origin/HEAD) test

    Ahora me gustaría volver a una de mis confirmaciones anteriores, digamos: "59c86c9 nueva confirmación". Ejecutaría el comando a continuación.

    $ git revert 59c86c9

    Esto abrirá un archivo, encontrará los detalles de la confirmación a la que está tratando de revertir, y puede darle un nombre a su nueva confirmación aquí, y luego guardar y cerrar el archivo.

    Revert "new commit"
    
    This reverts commit 59c86c96a82589bad5ecba7668ad38aa684ab323.
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    #
    # On branch master
    # Your branch is ahead of 'origin/master' by 4 commits.
    # (use "git push" to publish your local commits)
    #
    # Changes to be committed:
    # modified: dummyfile

    Después de guardar y cerrar el archivo, esta es la salida que obtendrá.

    $ git revert 59c86c9
    [master af72b7a] Revert "new commit"
    1 file changed, 1 insertion(+), 1 deletion(-)

    Ahora, para realizar los cambios necesarios, a diferencia del reinicio, revert ha realizado una nueva confirmación más. Si vuelve a comprobar el registro, encontrará una nueva confirmación debido a la operación de reversión.

    $ git log --oneline
    af72b7a (HEAD -> master) Revert "new commit"
    812335d add 3 files again
    0db602e one more commit
    59c86c9 new commit
    e2f44fc (origin/master, origin/HEAD) test

    git revert

    Git log tendrá todo el historial de confirmaciones. Si desea eliminar las confirmaciones del historial, revertir no es una buena opción, pero si desea mantener los cambios de confirmación en el historial, revertir es el comando adecuado en lugar de restablecer.

    Git Rebase

    En Git, rebase es la forma de mover o combinar confirmaciones de una rama sobre otra rama. Como desarrollador, no crearía mis funciones en la rama maestra en un escenario del mundo real. Trabajaría en mi propia rama (una 'rama de características'), y cuando tenga algunas confirmaciones en mi rama de características con la característica agregada, me gustaría moverla a la rama maestra.

    Rebase a veces puede ser un poco confuso de entender porque es muy similar a una fusión. El objetivo de fusionar y reajustar ambos es tomar las confirmaciones de mi rama de características y colocarlas en una rama maestra o en cualquier otra rama. Considere, tengo un gráfico que se ve así:

    git rebase

    Suponga que está trabajando en equipo con otros desarrolladores. En ese caso, puede imaginar que esto podría volverse realmente complejo cuando hay un montón de otros desarrolladores trabajando en diferentes ramas de funciones y han estado fusionando múltiples cambios. Se vuelve confuso rastrear.

    Entonces, aquí es donde rebase ayudará. Esta vez, en lugar de hacer una fusión de git, haré una rebase, donde quiero tomar mis dos confirmaciones de ramas de características y moverlas a la rama maestra. Una rebase tomará todas mis confirmaciones de la rama de características y las moverá a la parte superior de las confirmaciones de la rama maestra. Entonces, detrás de escena, git está duplicando las confirmaciones de la rama de características en la rama maestra.

    git rebase 1

    Este enfoque le dará un gráfico de línea recta limpio con todas las confirmaciones en una fila.

    git revert 2

    Hace que sea fácil rastrear qué confirmaciones fueron a dónde. Puedes imaginar que si estás en un equipo con muchos desarrolladores, todas las confirmaciones siguen seguidas. Por lo tanto, es muy fácil de seguir incluso si tiene muchas personas trabajando en el mismo proyecto al mismo tiempo.

    Déjame mostrarte esto de manera práctica.

    Así es como se ve mi rama maestra actualmente. Tiene 4 confirmaciones.

    $ git log --oneline
    812335d (HEAD -> master) add 3 files again
    0db602e one more commit
    59c86c9 new commit
    e2f44fc (origin/master, origin/HEAD) test

    Ejecutaré el siguiente comando para crear y cambiar a una nueva rama llamada característica, y esta rama se creará a partir de la segunda confirmación, es decir, 2c59c86

    (master)
    $ git checkout -b feature 59c86c9
    Switched to a new branch 'feature'

    Si verifica el registro en la rama de funciones, solo tiene 2 confirmaciones provenientes del maestro (línea principal).

    (feature)
    $ git log --oneline
    59c86c9 (HEAD -> feature) new commit
    e2f44fc (origin/master, origin/HEAD) test

    Crearé la característica 1 y la enviaré a la rama de características.

    (feature)
    $ vi feature1.txt
    
    (feature)
    $ git add .
    The file will have its original line endings in your working directory
    
    (feature)
    $ git commit -m 'feature 1'
    [feature c639e1b] feature 1
    1 file changed, 1 insertion(+)
    create mode 100644 feature1.txt

    Crearé una característica más, es decir, la característica 2, en la rama de características y la confirmaré.

    (feature)
    $ vi feature2.txt
    
    (feature)
    $ git add .
    The file will have its original line endings in your working directory
    
    (feature)
    $ git commit -m 'feature 2'
    [feature 0f4db49] feature 2
    1 file changed, 1 insertion(+)
    create mode 100644 feature2.txt

    Ahora, si revisa el registro de la rama de funciones, tiene dos nuevas confirmaciones, que ejecuté anteriormente.

    (feature)
    $ git log --oneline
    0f4db49 (HEAD -> feature) feature 2
    c639e1b feature 1
    59c86c9 new commit
    e2f44fc (origin/master, origin/HEAD) test

    Ahora quiero agregar estas dos nuevas características a la rama maestra. Para eso, usaré el comando rebase. Desde la rama de funciones, me basaré en la rama maestra. Lo que esto hará es volver a anclar mi rama de características contra los últimos cambios.

    (feature)
    $ git rebase master
    Successfully rebased and updated refs/heads/feature.

    Ahora voy a seguir adelante y verificar la rama maestra.

    (feature)
    $ git checkout master
    Switched to branch 'master'
    Your branch is ahead of 'origin/master' by 3 commits.
    
    (use "git push" to publish your local commits)

    Y finalmente, vuelva a basar la rama maestra con mi rama de características. Esto tomará esas dos nuevas confirmaciones en mi rama de características y las reproducirá en la parte superior de mi rama maestra.

    (master)
    $ git rebase feature
    Successfully rebased and updated refs/heads/master.

    Ahora, si reviso el registro en la rama maestra, puedo ver que las dos confirmaciones de mi rama de características se han agregado a mi rama maestra con éxito.

    (master)
    $ git log --oneline
    766c996 (HEAD -> master, feature) feature 2
    c036a11 feature 1
    812335d add 3 files again
    0db602e one more commit
    59c86c9 new commit
    e2f44fc (origin/master, origin/HEAD) test

    Se trataba de reiniciar, revertir y reajustar los comandos en Git.

    Conclusión

    Se trataba de reiniciar, revertir y reajustar los comandos en ir. Espero que esta guía paso a paso haya sido útil. Ahora, sabe cómo jugar con sus confirmaciones según la necesidad utilizando los comandos mencionados en el artículo.