Leí que al cambiar el nombre de los archivos en git , debe confirmar cualquier cambio, realizar su cambio de nombre y luego organizar su archivo renombrado. Git reconocerá el archivo por el contenido, en lugar de verlo como un nuevo archivo sin seguimiento, y mantendrá el historial de cambios.
Sin embargo, haciendo esto esta noche, terminé volviendo a hacerlo git mv
.
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
Cambiar el nombre de mi hoja de estilo en Finder de iphone.css
amobile.css
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
# Changed but not updated:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# deleted: css/iphone.css
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# css/mobile.css
Entonces git ahora piensa que eliminé un archivo CSS y agregué uno nuevo. No es lo que quiero, deshaga el cambio de nombre y deje que git haga el trabajo.
> $ git reset HEAD .
Unstaged changes after reset:
M css/iphone.css
M index.html
De vuelta a donde empecé.
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
Vamos a usar git mv
en su lugar.
> $ git mv css/iphone.css css/mobile.css
> $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# renamed: css/iphone.css -> css/mobile.css
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: index.html
#
Parece que estamos bien. Entonces, ¿por qué git no reconoció el cambio de nombre la primera vez cuando usé Finder?
add+rm
omv
bien, produce el mismo resultado. Git luego usa su detección de cambio de nombre / copia para hacerle saber que fue un cambio de nombre. La fuente que citó también es inexacta. Realmente no importa si modifica + renombra en la misma confirmación o no. Cuando realiza una diferencia entre la modificación y el cambio de nombre, la detección de cambio de nombre lo verá como un cambio de nombre + modificación, o si la modificación es una reescritura total, se mostrará como agregado y eliminado, pero no importa cómo lo haya realizado. eso.git mv old new
Actualiza automáticamente el índice. Cuando cambie el nombre fuera de Git, tendrá que hacergit add new
ygit rm old
organizar los cambios en el índice. Una vez que haya hecho estogit status
, funcionará como espera.public_html
directorio, que se rastrean en git. Habiendo realizadogit add .
ygit commit
, todavía mostraba un montón de archivos 'eliminados'git status
. Realicé unagit commit -a
y las eliminaciones se confirmaron, pero ahora no tengo historial en los archivos que vivenpublic_html
ahora. Este flujo de trabajo no es tan suave como me gustaría.Respuestas:
Para
git mv
la página del manual diceEntonces, al principio, debe actualizar el índice por su cuenta (mediante el uso
git add mobile.css
). Sin embargogit status
, aún mostrará dos archivos diferentesPuede obtener un resultado diferente ejecutando
git commit --dry-run -a
, lo que da como resultado lo que espera:No puedo decirte exactamente por qué vemos estas diferencias entre
git status
ygit commit --dry-run -a
, pero aquí hay una pista de Linus :A
dry-run
utiliza los mecanismos de cambio de nombre reales, mientras quegit status
probablemente no.fuente
git add mobile.css
. Sin élgit status -a
, solo habría "visto" la eliminación deliphone.css
archivo rastreado anteriormente , pero no habría tocado el nuevomobile.css
archivo no rastreado . Además,git status -a
no es válido con Git 1.7.0 y versiones posteriores. "" Git status "ya no es" git commit --dry-run "." en kernel.org/pub/software/scm/git/docs/RelNotes-1.7.0.txt . Úselogit commit --dry-run -a
si desea esta funcionalidad. Como han dicho otros, solo actualice el índice ygit status
funcionará como lo espera el OP.git commit
, no confirmará el archivo renombrado y el árbol de trabajo sigue siendo el mismo.git commit -a
derrota prácticamente todos los aspectos del flujo de trabajo / modelo de pensamiento de git: cada cambio está comprometido. ¿Qué sucede si solo desea cambiar el nombre del archivo, pero confirmar los cambiosindex.html
en otra confirmación?mobile.css
lo que debería haber mencionado. Pero ese es el punto de mi respuesta: la página del manual dice esothe index is updated
cuando lo usasgit-mv
. Gracias por lastatus -a
aclaración, usé git 1.6.4git status
no estaba detectando el cambio de nombre. ¡La ejecucióngit commit -a --dry-run
después de agregar mis "nuevos" archivos mostró los cambios de nombre y finalmente me dio confianza para comprometerme!git status
ahora se comporta comogit commit
.Debe agregar los dos archivos modificados al índice antes de que git lo reconozca como un movimiento.
La única diferencia entre
mv old new
ygit mv old new
es que git mv también agrega los archivos al índice.mv old new
entoncesgit add -A
habría funcionado también.Tenga en cuenta que no puede usarlo simplemente
git add .
porque eso no agrega eliminaciones al índice.Vea la diferencia entre "git add -A" y "git add".
fuente
git add -A
enlace, muy útil, ya que estaba buscando ese acceso directo.git add .
no añadir el traslado al índice.Lo mejor es probarlo por ti mismo.
Ahora git status y git commit --dry-run -a muestra dos resultados diferentes donde git status muestra bbb.txt cuando se elimina un nuevo archivo / aaa.txt, y los comandos --dry-run muestran el cambio de nombre real.
Ahora ve y haz el check-in.
Ahora puede ver que el archivo ha cambiado de nombre y que lo que se muestra en estado de git es incorrecto.
Moraleja de la historia: si no está seguro de si se cambió el nombre de su archivo, emita un "git commit --dry-run -a". Si muestra que el archivo se renombra, está listo para comenzar.
fuente
Para git 1.7.x, los siguientes comandos me funcionaron:
No había necesidad de git add, ya que el archivo original (es decir, css / mobile.css) ya estaba en los archivos confirmados anteriormente.
fuente
tienes que acceder al
git add css/mobile.css
nuevo archivo ygit rm css/iphone.css
, por lo tanto, git lo sabe. entonces mostrará la misma salida engit status
puede verlo claramente en la salida de estado (el nuevo nombre del archivo):
y (el antiguo nombre):
Creo que detrás de escena
git mv
no es más que un script de envoltura que hace exactamente eso: eliminar el archivo del índice y agregarlo con un nombre diferentefuente
git rm css/iphone.css
porque pensé que esto eliminaría la historia existente. Tal vez estoy malinterpretando el flujo de trabajo en git.git rm
no eliminará el historial. Solo elimina una entrada del índice para que la próxima confirmación no tenga la entrada. Sin embargo, seguirá existiendo en los compromisos ancestrales. De lo que puede estar confundido es que (por ejemplo)git log -- new
se detendrá en el punto donde se comprometiógit mv old new
. Si desea seguir los cambios de nombre, usegit log --follow -- new
.Pensemos en sus archivos desde la perspectiva de git.
Tu repositorio tiene (entre otros)
y está bajo control de git:
Prueba esto con:
Cuando tu lo hagas
Desde la perspectiva de git,
Entonces, git aconseja sobre los archivos que ya conoce ( iphone.css ) y los nuevos archivos que detecta ( mobile.css ), pero solo cuando los archivos están en el índice o HEAD git comienza a verificar su contenido.
En este momento, ni "iphone.css deletion" ni mobile.css están en el índice.
Agregue la eliminación de iphone.css al índice
git te dice exactamente lo que sucedió: ( iphone.css se elimina. No pasó nada más)
luego agregue un nuevo archivo mobile.css
Esta vez, tanto la eliminación como el nuevo archivo están en el índice. Ahora git detecta que el contexto es el mismo y lo expone como un cambio de nombre. De hecho, si los archivos son 50% similares, lo detectará como un cambio de nombre, lo que le permite cambiar un poco mobile.css mientras mantiene la operación como un cambio de nombre.
Ver esto es reproducible en
git diff
. Ahora que sus archivos están en el índice, debe usarlos--cached
. Edite mobile.css un poco, agréguelo al índice y vea la diferencia entre:y
-M
es la opción "detectar cambios de nombre" paragit diff
.-M
significa-M50%
(50% o más de similitud hará que git lo exprese como un cambio de nombre) pero puede reducir esto a-M20%
(20%) si edita mucho mobile.css.fuente
Paso 1: cambie el nombre del archivo de oldfile a newfile
Paso 2: git commit y agrega comentarios
Paso 3: empuje este cambio a servidor remoto
fuente
git mv
, el nuevo archivo ya está en el índice.Ahí es donde te equivocaste.
Solo después de agregar el archivo, git lo reconocerá por el contenido.
fuente
No diste los resultados de tu movimiento de búsqueda. Creo que si hiciste el movimiento a través del Finder y luego lo hiciste
git add css/mobile.css ; git rm css/iphone.css
, git calcularía el hash del nuevo archivo y solo entonces te darías cuenta de que los hash de los archivos coinciden (y, por lo tanto, es un cambio de nombre).fuente
En casos en los que realmente tiene que cambiar el nombre de los archivos manualmente, por ejemplo. usando una secuencia de comandos para cambiar el nombre de un lote de archivos por lotes, luego usando
git add -A .
funcionó para mí.fuente
Para usuarios de Xcode: si cambia el nombre de su archivo en Xcode, verá que el icono de la insignia cambia para agregarse. Si realiza una confirmación utilizando XCode, en realidad creará un nuevo archivo y perderá el historial.
Una solución alternativa es fácil, pero debe hacerlo antes de comprometerse a usar Xcode:
renombrado: Project / OldName.h -> Project / NewName.h renombrado: Project / OldName.m -> Project / NewName.m
Luego regrese a XCode y verá que la insignia cambió de A a M y se guarda para confirmar cambios adicionales al usar xcode ahora.
fuente