pago git . no está eliminando los archivos que se agregaron después de la confirmación

7 minutos de lectura

avatar de usuario de mullhausen
mullhausen

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 hago 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. Es README dice Thank you for reading. Hagamos esa comprobación:

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

(agrego 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 de pRaNaY
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 cualquiera. 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> 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 de mullhausen
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

git checkout --no-overlay (git 2.22.0, junio de 2019)

Con esta opción en ejecución:

git checkout --no-overlay <commit> <directory>

elimina todos los archivos que se agregaron en <directory> después <commit>. Desearía que ese fuera el comportamiento predeterminado, pero c’est la vie.

la opcion era agregado por Thomas Gummerer en 091e04bc8cbb0c89c8112c4784f02a44decc257e que entró en git v2.22.0.

Prueba:

#!/usr/bin/env bash
set -eu

rm -rf tmp
mkdir tmp
cd tmp
git init

mkdir a
touch a/a
git add .
git commit -m a

mkdir b
touch b/b
git add .
git commit -m b

git checkout HEAD~ .
echo 'overlay'
ls -l . a b

git checkout --no-overlay HEAD~ .
echo 'no overlay'
ls -l . a b

Resultado:

git checkout HEAD~ .
echo 'overlay'
ls -l . a b
echo

git checkout --no-overlay HEAD~ .
echo 'no overlay'
ls -l . a b
echo

Producción:

Initialized empty Git repository in /home/ciro/test/git/tmp/.git/
[master (root-commit) 216d22e] a
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a/a
[master a36e67b] b
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 b/b
overlay
.:
total 2
drwxrwxr-x 2 ciro ciro 3 Jan 17 08:40 a
drwxrwxr-x 2 ciro ciro 3 Jan 17 08:40 b

a:
total 1
-rw-rw-r-- 1 ciro ciro 0 Jan 17 08:40 a

b:
total 1
-rw-rw-r-- 1 ciro ciro 0 Jan 17 08:40 b

no overlay
ls: cannot access 'b': No such file or directory
.:
total 1
drwxrwxr-x 2 ciro ciro 3 Jan 17 08:40 a

a:
total 1
-rw-rw-r-- 1 ciro ciro 0 Jan 17 08:40 a

Entonces vemos que b/b solo se elimina con --no-overlay. El directorio b luego también se elimina como de costumbre en los comandos de git porque se habría quedado vacío como resultado del comando de git.

Probado en Ubuntu 22.10, Git 2.37.2.

Avatar de usuario de ElpieKay
elpiekay

alijo de git puede ser la forma más rápida de limpiar el árbol de trabajo. y luego 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?