$ git reset -- <file_path>
Se puede restablecer por ruta.
Sin embargo, $ git reset (--hard|--soft) <file_path>
informará un error como el siguiente:
Cannot do hard|soft reset with paths.
Porque no tiene sentido (otros comandos ya proporcionan esa funcionalidad), y reduce la posibilidad de hacer algo incorrecto por accidente.
Acaba de hacer un "restablecimiento git checkout HEAD -- <path>
completo " para una ruta (verificando la versión existente del archivo).
Un restablecimiento parcial de una ruta no tiene sentido.
Un restablecimiento mixto para una ruta es lo que git reset -- <path>
hace.
git checkout -- <path>
debería ser reemplazado porgit reset --hard <path>
. Tiene mucho más sentido ...git checkout -- <path>
no hace un restablecimiento completo; reemplaza el contenido del árbol de trabajo con el contenido en etapas.git checkout HEAD -- <path>
realiza un restablecimiento completo para una ruta, reemplazando tanto el índice como el árbol de trabajo con la versión de la confirmación HEAD.reset --hard
con un camino proporcionaría esta pieza que falta. Git ya es tan poderoso que la excusa "No dejamos que hagas esto por tu propia protección" no tiene agua: hay muchas maneras de hacer lo incorrecto "por accidente". Nada de eso importa de todos modos cuando lo tienesgit reflog
.git reset --hard -- <path>
. Hay casos de uso legítimo para ello.Puedes lograr lo que estás tratando de hacer usando
git checkout HEAD <path>
.Dicho esto, el mensaje de error proporcionado no tiene sentido para mí (ya que
git reset
funciona bien en subdirectorios), y no veo ninguna razón por lagit reset --hard
que no deba hacer exactamente lo que le está pidiendo.fuente
La pregunta de cómo ya está respondida , explicaré la parte del por qué .
Entonces, ¿qué hace git reset ? Dependiendo de los parámetros especificados, puede hacer dos cosas diferentes:
Si especifica una ruta, reemplaza los archivos coincidentes en el índice con los archivos de una confirmación (HEAD de forma predeterminada). Esta acción no afecta en absoluto el árbol de trabajo y generalmente se usa como lo contrario de git add.
Si no especifica una ruta, mueve la cabeza de la rama actual a una confirmación especificada y, junto con eso , opcionalmente restablece el índice y el árbol de trabajo al estado de esa confirmación. Este comportamiento adicional está controlado por el parámetro de modo:
--soft : no toque el índice ni el árbol de trabajo.
--mixed (predeterminado): restablece el índice pero no el árbol de trabajo.
--hard : restablece el índice y el árbol de trabajo.
También hay otras opciones, consulte la documentación para ver la lista completa y algunos casos de uso.
Cuando no especifica una confirmación, el valor predeterminado es HEAD, por
git reset --soft
lo que no hará nada, ya que es un comando para mover la cabeza a HEAD (a su estado actual).git reset --hard
, por otro lado, tiene sentido debido a sus efectos secundarios , dice mover la cabeza a HEAD y restablecer el índice y el árbol de trabajo a HEAD.Creo que ya debería estar claro por qué esta operación no es para archivos específicos por su naturaleza: en primer lugar, está destinada a mover un encabezado de rama, restablecer el árbol de trabajo y el índice es una funcionalidad secundaria.
fuente
git checkout
comando? Y hacer un reinicio para hacer lo mismo confundiría aún más a los usuarios. Mi respuesta fue que esa--hard
opción no es aplicable a archivos específicos porque es un modo de restablecimiento de rama, no restablecimiento de índice. Y el reinicio del árbol de trabajo se denomina pago, como puede leer en otras respuestas. Todo eso es solo un mal diseño de la interfaz de usuario de Git, en mi humilde opinión.git checkout
:git reset --
establece solo el índice, mientrasgit checkout --
establece solo el árbol de trabajo?Asegúrese de poner una barra diagonal entre el origen o el flujo ascendente (fuente) y la rama real:
o
fuente
Hay una razón muy importante detrás de eso: los principios de
checkout
yreset
.En términos de Git, pagar significa "traer al árbol de trabajo actual". Y con
git checkout
nosotros podemos llenar el árbol de trabajo con datos de cualquier área, ya sea desde un commit en el repositorio o archivos individuales desde un commit o el área de ensayo (que es el valor predeterminado).A su vez, git reset no tiene esta función. Como su nombre indica, restablecerá la referencia actual pero siempre tendrá el repositorio como fuente, independientemente del "alcance" (--soft, --mixed o --hard).
Resumen:
Por lo tanto, lo que puede ser un poco confuso es la existencia de,
git reset COMMIT -- files
ya que "sobrescribir HEAD" con solo algunos archivos no tiene sentido.En ausencia de una explicación oficial, solo puedo especular que los desarrolladores de git descubrieron que
reset
todavía era el mejor nombre de un comando para descartar los cambios realizados en el área de preparación y, dado que la única fuente de datos era el repositorio, entonces " ampliemos el funcionalidad "en lugar de crear un nuevo comando.Entonces, de alguna manera
git reset -- <files>
ya es un poco excepcional: no sobrescribirá el HEAD. En mi humilde opinión, todas esas variaciones serían excepciones. Incluso si podemos concebir una--hard
versión, otras (por ejemplo--soft
) no tendrían sentido.fuente
git reset -- <files>
cayó como si se hubiera agregado porque esta es una característica útil, pero nadie estaba seguro de en qué comando se debería poner. Afortunadamente, ahora tenemos mucho más sanogit restore
que tiene una funcionalidadgit checkout -- <path>
git checkout <commit> -- <path>
ygit reset [<commit>] -- <path>
con valores predeterminados mucho más sanos e incluso más funciones que no podía hacer antes (Contrariamente a lo que dice la respuesta aceptada. Ahora finalmente puede restaurar fácilmente el árbol de trabajo, sin tocar el índice).Explicación
El
git reset
manual enumera 3 formas de invocación:2 son de archivo: estos no afectan el árbol de trabajo , pero operan solo en los archivos en el índice especificado por
<paths>
:git reset [-q] [<tree-ish>] [--] <paths>..
git reset (--patch | -p) [<tree-ish>] [--] [<paths>...]
1 es commit-wise: funciona en todos los archivos de la referencia
<commit>
y puede afectar el árbol de trabajo:git reset [<mode>] [<commit>]
No hay ningún modo de invocación que funcione solo en archivos específicos y afecte al árbol de trabajo.
Solución alterna
Si quieres ambos:
Puede usar este alias en su archivo de configuración de git:
Luego puede hacer uno de:
(Mnenonic para
reco
:re
set &&c
hecko
ut)fuente
git reset --soft HEAD ~ 1 filename deshace la confirmación pero los cambios permanecen en local. nombre de archivo podría ser - para todos los archivos comprometidos
fuente
Cannot do soft reset with paths.