git checkout no está eliminando archivos que debería

5 minutos de lectura

Al usar un repositorio público, quiero que mi rama maestra vuelva a una determinada confirmación del pasado. He revisado las opciones y lo mejor para mí parece ser un simple pago hasta la confirmación deseada y luego confirmar en la rama maestra. Sin embargo, cuando realizo el pago, no elimina algunos archivos que se agregaron al maestro después del hash de confirmación especificado.

Entonces, por ejemplo, si quiero volver a comprometerme aaa1:

$ cd working-copy-top-dir
$ git checkout master
$ git checkout -- .
$ git clean -fd
$ git checkout aaa1 .
$ git clean -fd

Pero en este punto se agregaron algunos archivos después aaa1 todavía están en la copia de trabajo. Cuál es el checkout comando para obtener la copia de trabajo datos volver a como era en aaa1?

$ git --version
git version 2.7.2.windows.1

  • puede deberse al tipo de pago que hice stackoverflow.com/a/14460890/339874

    – Mullhausen

    13 de mayo de 2016 a las 4:22

  • creo que tienes que intentarlo reiniciar.

    – PraNaY

    13 de mayo de 2016 a las 5:16

  • Ver también stackoverflow.com/questions/4114095/…

    – torek

    13 de mayo de 2016 a las 7:33

TL; DR: eliminar todo primero

cuando usaste git checkout aaa1 .le dijiste a Git que tradujera aaa1 a una confirmación, encuentre esa confirmación (más precisamente, su árbol) y copie cada archivo en esa confirmación a su índice/área de ensayo y árbol de trabajo.

Digamos, solo por el bien del argumento, que comienzas con master que contiene dos archivos, README y hello:

$ git checkout master
[output snipped]
$ ls
README   hello
$ cat README
Yay, you read me!
$ cat hello
world
$ 

Digamos además que cometer aaa1 existe y tiene dos archivos en él, README y addendum. Su README dice Thank you for reading. Hagamos esa comprobación:

$ git checkout aaa1 -- .
[output snipped]
$ ls
README    addendum  hello

(Agregué el --: en realidad no se requiere aquí, pero es una buena práctica.) El contenido de README son los actualizados README. El archivo addendum también se ha extraído. El archivo hello es no eliminado y permanece sin cambios desde la versión que se encuentra en master. el actualizado README y hello se ponen en escena:

$ git status --short
M  README
A  addendum

pero hello no se elimina:

$ git ls-files --stage
100644 ac6f2cf1acbe1b6f11c7be2288fbae72b982823c 0   README
100644 7ddf1d71e0209a8512fe4862b4689d6ff542bf99 0   addendum
100644 cc628ccd10742baea8241c5924df992b5c019f71 0   hello

Usando git cleanincluso con -x, no tendrá ningún efecto: nada necesita limpieza; no hay archivos sin preparar (hello es puesta en escena, simplemente no es modificado).


Quería específicamente que el árbol de trabajo coincidiera con el compromiso aaa1, byte por byte. Para hacer eso, debe encontrar archivos que están en el índice ahora, pero que no estaban en aaa1y eliminarlos.

Sin embargo, hay una manera más fácil: simplemente elimine todo. Entonces, usa tu git checkout aaa1 -- . para extraer todo de aaa1. Esto completará el índice y el árbol de trabajo de aaa1: todos los archivos que deben restaurarse a la forma en que estaban antes de eliminarlos, se restauran (a la forma en que estaban en aaa1 cual es lo mismo como la forma en que están en HEAD). Cualquier archivo que deba cambiarse para que coincida con la forma en que estaba en aaa1son restaurados (a la forma en que estaban en aaa1 cual es diferente).

$ git rm -rf .
rm 'README'
rm 'addendum'
rm 'hello'
$ git checkout aaa1 -- .
$ git ls-files --stage
100644 ac6f2cf1acbe1b6f11c7be2288fbae72b982823c 0   README
100644 7ddf1d71e0209a8512fe4862b4689d6ff542bf99 0   addendum
$ git status --short
M  README
A  addendum
D  hello

Ahora puede confirmar y tendrá una nueva confirmación en master que, independientemente de lo que había antes, tiene exactamente el mismo árbol que aaa1.

(Ya sea que esto sea un buena idea es otra cosa completamente diferente, pero te dará el estado deseado).

avatar de usuario
pranay

¿Desea revertir su repositorio a ese estado? ¿O simplemente quiere que su repositorio local se vea así?

Ver https://git-scm.com/docs/git-reiniciar para reiniciar git.

CASO 1:
si lo haces

git reset --hard [commit hash]

Hará que su código local y su historial local sean como estaban en ese compromiso. Pero luego, si quisiera enviar esto a otra persona que tiene la nueva historia, fallaría.

CASO 2: si lo haces

git reset --soft [commit hash]

Hará que sus archivos locales cambien para que sean como eran entonces, pero dejará su historial, etc. igual.

Encontré respuesta aquí. También puede ver la respuesta relacionada aquí.

  • es un repositorio público, así que git reset --soft es lo que necesito 🙂

    – Mullhausen

    13 de mayo de 2016 a las 5:34

  • mmm git reset --soft aaa1 no elimina los archivos añadidos después aaa1 o. si miro en mi copia de trabajo todavía están allí

    – Mullhausen

    13 de mayo de 2016 a las 5:46


  • SÍ, me alegra saber que te ayuda.

    – PraNaY

    13 de mayo de 2016 a las 6:29


  • Lo sentimos, esto es incorrecto. git reset --soft <commit-hash> lo hace no cambie los archivos locales, como se menciona en la página del manual: --soft Does not the the index file or the working tree at all, but reset the head to <commit>

    – Flamm

    31 de agosto de 2017 a las 11:09

avatar de usuario
mullhausen

Git checkout no eliminará los archivos agregados desde una confirmación anterior. Para hacer esto necesitaría git revert.

sin embargo encuentro git checkout thehash . mucho más fácil de usar, y no es tan difícil ver qué archivos se han agregado desde ese hash:

git diff --name-status HEAD thehash

Descubrí que este comando actualiza tanto el índice como la copia de trabajo al compromiso que quiero, dado por variable treeish en este caso:

# use with care: destroys any uncommitted changes
git read-tree "$treeish" --reset -u

Para actualizar la copia de trabajo sin actualizar el índice, tal vez podría hacer algo como esto:

index_bak=$(git write-tree)
git read-tree "$treeish" --reset -u
git read-tree "$index_bak" --reset

alijo de git puede ser la forma más rápida de limpiar el árbol de trabajo. y entonces git checkout -b $newbranch $commit-sha1-you-want para crear una rama con la que vas a trabajar. después de que todo tu trabajo haya terminado, git escondite pop para restaurar el árbol de trabajo.

¿Ha sido útil esta solución?