He visto posts interesantes explicar las sutilezas acerca de git reset.

Por desgracia, cuanto más leo sobre ello, más me parece que no me entienden. Yo vengo de un SVN de fondo y Git es un paradigma totalmente nuevo. Tengo mercurial fácilmente, pero Git es mucho más técnico.

Creo git reset está cerca de hg revert, pero parece que hay diferencias.

Entonces, ¿qué hace exactamente git reset hacer? Por favor, incluya una explicación detallada sobre:

  • las opciones --hard, --soft y --merge;
  • el extraño notación que utiliza con HEAD como HEAD^ y HEAD~1;
  • casos de uso concretos y flujos de trabajo;
  • consecuencias en la copia de trabajo, el HEAD y su nivel de estrés.
  • Creo que Visual Git Referencia da una buena visión general de lo que sucede cuando el uso común de los comandos de git.
InformationsquelleAutor e-satis | 2010-03-27

7 Comentarios

  1. 940

    En general, git reset‘s función es tomar la rama actual y poner a punto en algún otro lugar, y, posiblemente, traer el índice y el trabajo del árbol a lo largo. Más concretamente, si la rama master (actualmente desprotegidos) es como este:

    - A - B - C (HEAD, master)
    

    y te das cuenta de que quiere dominar al punto B, no C, que va a utilizar git reset B a mover de allí:

    - A - B (HEAD, master)      # - C is still here, but there's no branch pointing to it anymore
    

    Digresión: Esto es diferente de una caja. Si desea ejecutar git checkout B, tendrían esta:

    - A - B (HEAD) - C (master)
    

    Has terminado en un desprendimiento de la CABEZA del estado. HEAD, el trabajo del árbol, el índice de todos coinciden B, pero la rama master se quedó atrás en C. Si usted hace un nuevo commit D en este punto, usted recibirá este, que probablemente no es lo que usted desea:

    - A - B - C (master)
           \
            D (HEAD)
    

    Recuerde, reset no hace compromete, sólo se actualiza una rama (que es un puntero a un commit) para que señale a otro a cometer. El resto es sólo detalles de lo que sucede a su índice y el trabajo del árbol.

    Casos de uso

    Me cubren muchos de los principales casos de uso para git reset dentro de mi descripciones de las diversas opciones en la siguiente sección. Realmente puede ser utilizado para una amplia variedad de cosas, el hilo común es que todas ellas implican el restablecimiento de la rama, el índice de obra y/o árbol a punto de a/partido de una confirmación.

    Cosas a tener cuidado de

    • --hard puede hacer que usted realmente perder el trabajo. Se modifica el trabajo de árbol.

    • git reset [options] commit puede causar que usted (tipo de) perder comete. En el juguete ejemplo anterior, hemos perdido cometer C. Aún está en el repo, y usted puede encontrar buscando en git reflog show HEAD o git reflog show master, pero en realidad, no es accesible desde cualquier sucursal más.

    • Git elimina de forma permanente tales comete después de 30 días, pero hasta entonces se puede recuperar C señalando una sucursal en nuevo (git checkout C; git branch <new branch name>).

    Argumentos

    Parafraseando el hombre de la página, la mayoría de uso común es el de la forma git reset [<commit>] [paths...], que restablecerá el dado rutas de acceso a su estado de la confirmación. Si los caminos no son siempre, todo el árbol es cero, y si la confirmación no se proporciona, se toma para ser el JEFE (el actual commit). Este es un patrón común a través de los comandos de git (por ejemplo, caja, diff, registro, a pesar de que la semántica exacta variar), así que no debería ser demasiado sorprendente.

    Por ejemplo, git reset other-branch path/to/foo restablece todo en la ruta/a/foo a su estado en otras sucursales, git reset -- . restablece el directorio actual a su estado en la CABEZA, y un simple git reset restablece todo a su estado en la CABEZA.

    La obra principal del árbol y de opciones de índice

    Hay cuatro opciones principales para el control de lo que sucede a su trabajo árbol y el índice durante el restablecimiento.

    Recuerde, el índice es git «en el área de ensayo» – es el lugar donde van las cosas cuando se dicen git add en preparación a la confirmación.

    • --hard hace que todo coincida con el commit restablecer. Este es el más fácil de entender, probablemente. Todos los cambios locales paliza. Un uso principal es soplado lejos de su trabajo, pero no de conmutación de envíos: git reset --hard significa git reset --hard HEAD, es decir, no cambiar la rama, pero deshacerse de todos los cambios locales. El otro es simplemente mover una rama de un lugar a otro, y mantener el índice de trabajo/árbol en la sincronización. Esta es la que realmente puede hacer que usted pierda el trabajo, ya que modifica su trabajo árbol. Estar muy muy seguro de que quiera tirar el local de trabajo antes de ejecutar cualquier reset --hard.

    • --mixed es el predeterminado, es decir, git reset significa git reset --mixed. Se restablece el índice, pero no la obra de árbol. Esto significa que todos los archivos están intactos, pero las diferencias entre el original de la confirmación y el restablecimiento de a se muestran como modificaciones locales (o sin marcar archivos) con git status. Utilice esta opción cuando te das cuenta de que hecho algunas malas comete, pero desea mantener todo el trabajo que has hecho así que usted puede arreglar y renovar el compromiso. En orden de cometer, tendrás que añadir los archivos al índice de nuevo (git add ...).

    • --soft no toque el índice de o trabajo de árbol. Todos los archivos están intactos, así como con --mixed, pero todos los cambios se muestran como changes to be committed con git status (es decir, activado en la preparación para cometer). Utilice esta opción cuando te das cuenta de que has hecho algunas malas comete, pero el trabajo del todo bien – todo lo que necesitas hacer es comprometernos de manera diferente. El índice es virgen, así que usted puede comprometerse de inmediato si usted quiere – el resultado cometer tendrán todos el mismo contenido que donde estaba antes de restablecer.

    • --merge fue añadido recientemente y está pensado para ayudarle a abortar un error en la mezcla. Esto es necesario porque git merge realmente vamos a intentar una combinación con un trabajo sucio árbol (uno con modificaciones locales) siempre y cuando dichas modificaciones están en los archivos afectados por la fusión. git reset --merge restablece el índice (como --mixed – todos los cambios se muestran como modificaciones locales), y restablece los archivos afectados por la fusión, pero deja a los demás solo. Esto se espera que restaurar todo a como estaba antes de la mala combinación. Normalmente usarás como git reset --merge (significado git reset --merge HEAD) debido a que usted sólo desea restablecer lejos de la combinación, en realidad no mover la rama. (HEAD que no se han actualizado todavía, ya que la combinación de error)

      Para ser mas concreto, supongamos que se ha modificado los archivos a y B, y se intenta combinar en una rama por la cual se modifica archivos de C y D. La combinación de falla por alguna razón, y decide abortar. Utilice git reset --merge. Trae C y D volver a cómo eran en HEAD, pero deja que las modificaciones a y B solo, ya que no fueron parte del intento de combinar.

    Quieres saber más?

    Creo man git reset es realmente muy bueno para esto – tal vez usted necesita un poco de sentido de la forma git trabaja para ellos, para que realmente se hunden en aunque. En particular, si se toma el tiempo para leerlos cuidadosamente, esas tablas que detallan los estados de archivos en el índice y el trabajo de árbol para todas las diferentes opciones y los casos son muy, muy útiles. (Pero sí, son muy denso – que está tratando de comunicar un montón de la información anterior en una forma muy concisa.)

    Extraño notación

    El «extraño» notación (HEAD^ y HEAD~1) que mencionar es simplemente una abreviatura para especificar compromete, sin tener que utilizar un hash nombre como 3ebe3f6. Es totalmente documentado en la «la especificación de revisiones» de la sección de la página man git-rev-analizar, con un montón de ejemplos y relacionados con la sintaxis. El símbolo de intercalación y la tilde en realidad significa cosas diferentes:

    • HEAD~ es corto para HEAD~1 y significa la confirmación del primer padre. HEAD~2 significa la confirmación del primer padre del primer padre. Creo que de HEAD~n como «n se compromete antes de la CABEZA» o «la enésima generación antepasado de la CABEZA».
    • HEAD^ (o HEAD^1) también significa la confirmación del primer padre. HEAD^2 significa la confirmación de la segundo de los padres. Recuerde, una normal de la combinación de cometer tiene dos padres – la primera de los padres es la fusión-en cometer, y la segunda de los padres es la confirmación que fue fusionada. En general, las uniones de hecho pueden tener arbitrariamente muchos padres (pulpo funde).
    • La ^ y ~ los operadores pueden ser atados juntos, como en HEAD~3^2, el segundo padre de la tercera generación antepasado de HEAD, HEAD^^2, el segundo padre de los primeros padres de HEAD, o incluso HEAD^^^, que es equivalente a HEAD~3.

    En la llanura inglés, ¿qué significa

    • «usted va a usar git reset para mover de allí.» ¿por qué no utilizar git checkout para hacerlo?
    • git checkout va a mover la CABEZA, pero dejar la rama en donde estaba. Esto es para cuando desea mover la rama.
    • Entonces, si entiendo bien, restablecer B haría : – a – B – C – B (maestro), mientras que checkout B iba a hacer – a – B (master) ?
    • No. Actualizada la respuesta a cubrir.
    • Okayyyyyy. Sólo he conseguido algo muy importante. Usted dijo: «no hay ninguna rama de señalar» y se me fastidiaron. Ahora lo entiendo. Una sucursal no es una lista de los cambios, es sólo un puntero a un lugar en la historia, ¿no? Por eso SVN chico no lo entiendo, no lo vemos de la manera adecuada. Muy útil el post, espero que usted tiene un montón de representante de ella.
    • Ah, y no es sólo una CABEZA, que no tiene nada que ver con las ramas. Su CABEZA es sólo el último commit, lo que nunca sucursal en es en. Usted no tiene uno en la CABEZA por sucursal. O estoy equivocada?
    • Sí. Una rama es simplemente un puntero a un determinado commit – buscar en un archivo en .git/refs/heads y verás su contenido es sólo un SHA1.
    • Sí, sólo hay una CABEZA. Puede ser una referencia simbólica a la rama actual (este es el estado normal) o una referencia directa a un commit dado (por SHA1, como ramas hacer – este es el desprendimiento de la CABEZA). Más prolija explicación de esto en tu otra pregunta: stackoverflow.com/questions/2529971/what-is-the-head-in-git
    • Creo que HEAD~3 no es necesariamente siempre el mismo como HEAD^^^, especialmente cuando la CABEZA tiene más de uno de los padres.
    • j: es. Un extracto de la documentación que he enlazado: «Un sufijo ~<n> para una revisión parámetro significa que el objeto de commit que es el <n>th generación del gran padre de la denominada cometer objeto, siguiendo sólo el primer padre. I. e. rev~3 es equivalente a rev^^^ que es equivalente a la rev^1^1^1.»
    • los médicos son buenos aunque se tarda una eternidad para leer ellos y son muy densa y se tarda una eternidad para verificar que decir que funciona como usted ya sabe cómo funciona. No suena como la de google docs son buenas para mí…
    • Me toma más tiempo para leer algo como esto. La documentación completa, correcta y concisa, lo que significa que son densos. Es no trivial de información; nunca se puede transmitir en un corto período de tiempo sin que se resumen y la aproximación.
    • Agradezco lo que está pasando con la edición, y el diagrama es agradable. Cuidado, sin embargo; se reescribió una gran cantidad de texto, hizo algunas cosas más claras y algunas cosas menos (en mi opinión, de todos modos), y eliminado el enlace a la canónica de la documentación. He editado de nuevo, sino que se mantiene mucho de lo que se haya agregado.
    • Una mucho más simple y comprensible explicación es dada por este MODO de respuesta: stackoverflow.com/questions/3528245/whats-the-difference-between-git-reset-mixed-soft-and-hard
    • Por favor, añada también información acerca de estos comandos: git reset y git reset -- ..
    • La mayoría de que ya estaba allí, por ejemplo, que el comportamiento predeterminado es –mezclados, y cuando originalmente respondió a esta es que era bastante claro que el OP no tiene problemas con la noción de cometer/ruta de los argumentos, pero he añadido una sección adicional acerca de los argumentos.
    • gracias.
    • Uno de los mejor artículo que he leído sobre git reset. Yo no se cómo te las arreglas para escribir este tipo de artículo detallado dentro de los 4 minutos de la Pregunta publicado :)debe ser super rápido 😀
    • Bonito gráfico de CABEZA con ~ y ^
    • este es un muy gr8 respuesta tanto es así que me sentí obligado a escribir esto de alguien que muy rara vez los comentarios y que sólo entiende la mitad de los git de puzzle. esto solo me ayudó inmensamente la comprensión de git. Esto también me hace pensar que otros comentaristas que no muestran aprecio por esta respuesta es muy perezosa (admito que yo soy uno, pero la respuesta es tan gud que tenía que escribir esto) o realmente no entiendo git tanto como para apreciar cómo gud esta respuesta. gracias por tomarse el tiempo para escribir esta valiosa respuesta.

  2. 77

    Recordar que en git tiene:

    • la HEAD puntero, que te dice a qué cometer estás trabajando en
    • la árbol de trabajo, que representa el estado de los archivos en su sistema
    • la área de ensayo (también llamado el índice), que «etapas» cambios para que luego pueden ser enviados juntos

    Por favor, incluya una explicación detallada sobre:

    --hard, --soft y --merge;

    En orden creciente de peligroso-ness:

    • --soft mueve HEAD pero no toque el área de ensayo o el árbol de trabajo.
    • --mixed mueve HEAD y actualizaciones en el área de ensayo, pero no el árbol de trabajo.
    • --merge mueve HEAD, se restablece el área de ensayo, y trata de seguir todos los cambios en su árbol de trabajo en el nuevo árbol de trabajo.
    • --hard mueve HEAD y se ajusta a su área de ensayo y árbol de trabajo a la nueva HEAD, tirando por la borda todo.

    casos de uso concretos y flujos de trabajo;

    • Uso --soft cuando desea mover a otro a cometer y arreglar las cosas sin «perder su lugar». Es bastante raro que usted necesita.

    # git reset --soft example
    touch foo                            //Add a file, make some changes.
    git add foo                          //
    git commit -m "bad commit message"   //Commit... D'oh, that was a mistake!
    git reset --soft HEAD^               //Go back one commit and fix things.
    git commit -m "good commit"          //There, now it's right.
    

    • Uso --mixed (que es el predeterminado) cuando usted quiere ver lo que ven las cosas a otro a cometer, pero usted no quiere perder los cambios que ya tienen.

    • Uso --merge cuando desea mudarse a un nuevo lugar, pero incorporar los cambios que ya tiene en que el árbol de trabajo.

    • Uso --hard a borrar todo y empezar de un fresco de pizarra en el nuevo commit.

    • Esa no es la intención de caso de uso para reset --merge. No realizar una mezcla de tres vías. Es realmente sólo para el restablecimiento de conflicto se funde, como se describe en la documentación. Usted querrá usar checkout --merge a hacer lo que estás hablando. Si desea mover la rama así, creo que la única manera es hacer un seguimiento con algunos checkout/reset para arrastrarla.
    • Sí, yo no la frase que muy bien. Por «un nuevo spot» me refería a «un lugar fresco donde no se tiene el conflicto de mezcla».
    • Ah, ya veo. Creo que lo importante aquí es que, a menos que realmente sepa lo que está haciendo, usted probablemente no desea utilizar reset --merge con cualquier objetivo, además de (el valor predeterminado) HEAD, porque en los casos en que además de abortar a un conflicto de mezcla, va a tirar de información que de lo contrario, podría salvar.
    • He encontrado esta respuesta la más sencilla y útil
    • Por favor agregar información acerca de estos comandos: git reset y git reset -- ..
    • Hice un git reset mixto para revertir un commit, pero lo que realmente debería haber hecho git reset–suave. Ahora no puedo ver los archivos en git status. Ayuda?

  3. 35

    El post Restablecer Desmitificado en el blog Pro Git da una muy obviedad explicación en git reset y git checkout.

    Después de que todos los útiles de discusión en la parte superior de ese post, el autor reduce las reglas para el siguiente sencillo de tres pasos:

    Que es básicamente la misma. El reset comando sobrescribe estos tres árboles en un orden específico, y se detienen cuando se le indique.

    1. Mover cualquier rama de la CABEZA de los puntos a (stop si --soft)
    2. A CONTINUACIÓN, realice el Índice de aspecto (a parar aquí, a menos que --hard)
    3. A CONTINUACIÓN, hacer que el Directorio de Trabajo aspecto que

    También hay --merge y --keep opciones, pero prefiero mantener las cosas simples por ahora – eso será para otro artículo.

  4. 25

    Cuando usted comete algo a git primer lugar de la etapa (añadir al índice) los cambios. Esto significa que usted tiene que git agregar todos los archivos que desea incluir en este commit antes de git, los considera parte de la confirmación. Primero vamos a echar un vistazo más de la imagen de un repositorio git:
    En la llanura inglés, ¿qué significa

    así, su simple ahora. Tenemos que trabajar en el directorio de trabajo, creación de archivos, directorios y todos. Estos cambios son sin marcar los cambios. Para hacer seguimiento de ellos, tenemos que añadir a git índice mediante git add comando. Una vez que se añaden a git índice. Ahora podemos cometer estos cambios, si queremos ir a repositorio de git.

    Pero de repente llegamos a conocer mientras se envio que tenemos un archivo extra que hemos añadido en el índice no es necesario para empujar en el repositorio de git. Significa que no queremos que el archivo de índice.
    Ahora la pregunta es cómo eliminar ese archivo de git índice, Ya que hemos utilizado git add a poner en el índice sería lógico utilizar git rm? Mal! git rm simplemente eliminar el archivo y agregar la eliminación en el índice. Entonces, ¿qué hacer ahora:

    Uso:-

    git reset

    Se Borra de su índice, sale de su directorio de trabajo sin tocar. (simplemente unstaging todo).

    Puede ser utilizado con el número de opciones con ella.
    Hay tres opciones principales para el uso con git reset: – duro, –suave y –mezclados. Estos afectan a lo que se consigue el restablecimiento además del JEFE del puntero cuando se restablece.

    Primero, – duro restablece todo. El directorio actual sería exactamente como lo haría si hubiera sido después de que se ramifican a lo largo de todos. El directorio de trabajo y el índice se ha cambiado para que se comprometan. Esta es la versión que yo uso más a menudo. git reset –hard es algo así como svn revert .

    Siguiente, todo lo contrario, —soft, no restablece el árbol de trabajo ni el índice. Solo mueve la CABEZA puntero. Esto deja a su estado actual con los cambios diferentes de la confirmación a la que desea cambiar en su directorio, y la «puesta en escena» por cometer. Si usted hace un commit a nivel local, pero no ha empujado al comprometerse con el servidor git, puede restablecer a la anterior cometer, y a comprometernos con un buen mensaje de confirmación.

    Finalmente, –mezclados restablece el índice, pero no el árbol de trabajo. Así que los cambios son todavía los hay, pero son «unstaged» y sería necesario git add ed o git commit-a. podemos usar esto a veces si hemos cometido más de lo que significó para con git commit-a, se puede realizar el commit git reset –mezclados, añadir las cosas que nos quieren comprometerse y acaba de cometer esos.

    Diferencia entre git revert y git reset :-


    En palabras simples, git reset es un comando para «fix-uncommited errores» y git revert es un comando para «fix-comprometido error».

    Significa que si hemos cometido algún error en algunos cambios y añadidos y empujó el mismo repositorio git, entonces git revert es la solución. Y si en el caso que hemos identificado el mismo error antes de empujar/envio, podemos utilizar git reset para solucionar el problema.

    Espero que esto le ayudará a deshacerse de su confusión.

    • Este es un buen inglés simple respuesta como se pide por el OP.
    • A pesar de que yo podría perderse y que en su respuesta. ¿Qué es git reset HEAD por defecto? --hard,--soft o --mixed ? Respuesta excelente por cierto.
    • Gran respuesta, pero me gustaría dejar claro que git reset --hard va a provocar la pérdida de algunos datos. Y hay un punto que podría estar equivocado (aunque no estoy 100% seguro… sigo aprendiendo!): hablando de --mixed usted dice que «podemos usar esto a veces si hemos cometido más de lo que significó para con git commit-a». Did you mean: «si nosotros protagonizaron más de lo que significó para con git stage .«? Si realmente cometido, creo que es demasiado tarde (como dices al final, git reset es un comando para «fix-uncommited errores»)
  5. 6

    TL;DR

    git reset restablece de Ensayo para el último commit. Uso --hard también para restablecer los archivos en su directorio de Trabajo para el último commit.

    VERSIÓN MÁS LARGA

    Pero que, obviamente, simplista de ahí los muchos, más detallado de las respuestas. Tenía más sentido para mí leer en git reset en el contexto de deshacer los cambios. E. g. ver esto:

    Si git revert es un «seguro» para deshacer los cambios, usted puede pensar de git
    reset del método peligroso. Al deshacer con git reset(y la
    comete ya no hace referencia alguna ref o la reflog), hay
    no hay manera de recuperar la copia original—es una permanente deshacer. La atención debe
    tener precaución al utilizar esta herramienta, ya que es uno de los únicos comandos de Git que tiene el potencial de perder su trabajo.

    De https://www.atlassian.com/git/tutorials/undoing-changes/git-reset

    y este

    En la confirmación de nivel, el restablecimiento es una manera de mover la punta de una rama a otra a cometer. Esto puede ser usado para quitar las confirmaciones de la rama actual.

    De https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting/commit-level-operations

  6. 2

    Tenga en cuenta, esta es una explicación simplificada como un primer paso en la búsqueda de entender este complejo funcionalidad.

    Puede ser útil para los estudiantes visuales que desea visualizar lo que su proyecto de estado se ve como después de cada uno de estos comandos:


    Para aquellos que utilizan la Terminal con el color encendido
    (git config –global de color.interfaz de usuario automático):

    git reset --soft A y verás B y C del material en verde (puesta en escena y listo para comprometerse)

    git reset --mixed A (o git reset A) y verás B y C de cosas en rojo (unstaged y listo para ser simulado (verde) y, a continuación, comprometidos)

    git reset --hard A y no volverás a ver a B y C de cambios en cualquier lugar (será como si nunca hubieran existido)


    O para aquellos que utilizan una interfaz gráfica de usuario del programa como ‘la Torre’ o ‘SourceTree’

    git reset --soft A y verás B y C de la materia en el » montaron de los archivos del área listo para comprometerse

    git reset --mixed A (o git reset A) y verás B y C de las cosas en el » unstaged de los archivos del área listo para ser trasladado a la puesta en escena y, a continuación, comprometido

    git reset --hard A y no volverás a ver a B y C de cambios en cualquier lugar (será como si nunca hubieran existido)

  7. 1

    Checkout puntos de la cabeza en un commit.

    Puntos de Reset de una rama específica de cometer. (Una rama es un puntero a un commit.)

    por cierto, si tu cabeza no apunta a una confirmación de que también es señalado por una rama, a continuación, usted tiene un desprendimiento de la cabeza. (resultó ser incorrecto. Ver comentarios…)

    • De no ser quisquilloso, pero (sí, en el hecho de que está como una molestia, pero vamos a añadir para completar su frase 3 es técnicamente falso. Digamos que su CABEZA está apuntando a la sección B, que es a su vez apunta a cometer abc123. Si ahora checkout cometer abc123, la CABEZA y la rama B son ambos apuntando a cometer abc123 Y su CABEZA se separa. Cometiendo en este punto se no actualización de la rama B de la posición. Podrías haber dicho «si su cabeza no apuntan a una rama, a continuación, usted tiene un desprendimiento de la cabeza»
    • Lo que va a cometer hacer en esa circunstancia?
    • Cometer crearía compromete a que no se hace referencia a cualquier rama, y la rama B se siguen apuntando a la misma cometer abc123 incluso después de cometido varias veces después de eso. Esto implica que estos se compromete podría convertirse en candidatos para la recolección de basura cuando la CABEZA deja de señalar en el último commit en este ‘salvaje’ de la serie de confirmaciones.

Dejar respuesta

Please enter your comment!
Please enter your name here