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
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 clean
incluso 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 aaa1
y 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 aaa1
son 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).
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ésaaa1
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
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.
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.
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