Me gustaría evitar llamar a los comandos de porcelana de mis guiones, pero ¿hay alguna manera de obtener algo del comportamiento de git checkout <commit>
usando solo comandos de plomería como checkout-index
? Estoy particularmente interesado en el efecto sobre la copia de trabajo: suponiendo que todo esté limpio, checkout
elimina archivos que fueron rastreados en el antiguo HEAD y ausentes en el nuevo. checkout-index
no parece tener ningún concepto de eliminación de archivos. Lo más parecido que se me ocurre sería llamar
git diff-tree -p <old> <new> | git apply
pero calcular toda la diferencia parece innecesariamente costoso. ¿Hay una mejor manera?
Estas buscando el dos arbol git read-tree -um
. Utiliza un árbol base, (generalmente lo alimentas HEAD
), un árbol de destino e (implícitamente) el índice y el árbol de trabajo. La tabla que describe su comportamiento fue difícil de entender para mí, así que tengo mi propia hoja de trucos, una reformateada que tiene más sentido para mí, de todos modos. En cualquier caso, implementa git checkout
.
git read-tree -um H M # `I` is the (implicit) index, GIT_INDEX_FILE
Legend
H Original tree (usually HEAD:)
I Indexed tree
M Merge target tree
H->I \
H->M } status in second relative to first
I->M /
"-" file exists in neither
new exists only in second
deleted exists only in first
same exists in both, unchanged
changed exists in both, different
(blank) irrelevant or all cases not otherwise given
keep keep current version
fail whole command fails, no changes
delete delete worktree file
H->I H->M I->M
same keep
deleted changed fail
deleted deleted delete
deleted same delete unless Index empty, else use M
same keep
same changed worktree clean: use M; dirty: fail
same deleted worktree clean: deleted; dirty: fail
new - keep
new new changed fail
changed changed changed fail
changed deleted fail
note: "index empty" identifies an initial checkout, where HEAD has been
set but never loaded. git can't currently distinguish between a
delete-everything index and an initial-checkout index.
Cualquier razón por la que no llames
git checkout ...
?–Oliver Charlesworth
23 de julio de 2014 a las 21:47
Sí, no hagas tu vida innecesariamente difícil.
– ThiefMaster
23 de julio de 2014 a las 21:56
En última instancia, quiero tener más control sobre cómo se realiza el pago. Por ejemplo,
checkout
puede eliminar archivos ignorados, y quiero evitar hacerlo (mayor seguridad). Pero quiero allanar archivos eliminados (seguridad disminuida), sin usar--force
pavimentar todo. Esto es parte de un script que usa git debajo de las cubiertas para almacenar árboles de archivos, ycheckout
está muy cerca de cómo quiero que se comporte mi script, pero no del todo. Pensé que si podría conseguircheckout
con los comandos de plomería podría ajustarlo desde allí, aunque avíseme si hay otra forma de obtener este control.– Jack O´Connor
23 de julio de 2014 a las 22:07
¿De verdad has probado eso
diff-tree
¿es lento?checkout
básicamente diferencia todo para averiguar qué hacer en primer lugar. (Por supuesto,checkout
no crea parches y luego los aplica, y probablemente tú tampoco deberías hacerlo).–Edward Thomson
23 de julio de 2014 a las 23:52
@EdwardThomson
diff-tree
es probablemente lo que quiero, pero no estoy seguro de en qué canalizar su salida. ¿Hay alguna forma de aplicar esta diferencia a la copia de trabajo además de lagit apply
hackear arriba? Sería bastante fácil escribir una secuencia de comandos de Python para tomar la lista de eliminaciones y realizarlas, pero me preocupa que sea lento.– Jack O´Connor
24 de julio de 2014 a las 7:57