2011-07-08 14 views
22

Después de superar algunos obstáculos al aprender Git, me encontré con un nuevo desafío: renombrar un directorio (localmente, en el directorio de trabajo).Cómo decirle a Git que es el mismo directorio, solo un nombre diferente

Cuando escribo git status, que muestra todos los archivos en el antiguo nombre de directorio (que existen con los mismos nombres exactos en el nuevo directorio) como suprimen y el nuevo nombre de directorio como "sin seguimiento".

¿Hay alguna manera de decirle a Git que "en realidad es el mismo directorio, solo un nombre diferente"?

¿Para que todos los archivos se enumeren por git status solo como modificado?

Para ejemplificar el problema, aquí es la salida que recibo de git status cuando se cambio el nombre de un directorio completo:

git status 
# On branch master 
# Changes not staged for commit: 
# (use "git add/rm <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
# deleted: old-dir-name/file1 
# deleted: old-dir-name/file2 
# deleted: old-dir-name/file3 
# 
# Untracked files: 
# (use "git add <file>..." to include in what will be committed) 
# 
# new-dir-name/ 
no changes added to commit (use "git add" and/or "git commit -a") 
~/sb/ws> 
+1

Acabo de probar esto y no tengo ese problema. En mi caja, Git identifica con éxito que cambié el nombre de una carpeta y continúa rastreando todos sus archivos sin informar nada sobre el estado de "git". – karlphillip

+0

@karlphillip ¿Cómo cambiaste el nombre de la carpeta? En mi caso, lo eliminé por completo y copié de una fuente diferente el mismo contenido pero con un nombre diferente. Eso hace una diferencia? – WinWin

+1

Probablemente. Acabo de renombrarlo con ** mv **: 'mv folder new_name'. Git es lo suficientemente inteligente como para detectar si creó archivos nuevos o simplemente renombró una carpeta.Pero cuando elimina el directorio y crea uno nuevo (aunque tiene los mismos archivos que el anterior), git considera que todos esos archivos son nuevos. En el futuro, simplemente renómbrelo con 'mv'. Puedo agregar esto como respuesta si te gustó. – karlphillip

Respuesta

11

Todas las respuestas aquí fueron muy útiles en el camino a la solución real para el escenario particular que estaba enfrentando.Estoy proporcionando lo que funcionó para mí en forma de pasos reales, es de esperar ayudar a otros que encuentran al mismo desafío:

  1. git mv <old-dir-name> <new-dir-name>
  2. git status (verificar que todos los archivos marcados renombraron, no "eliminado")
  3. git commit -a -m "git mv <old-dir-name> <new-dir-name>" (esto es un "falso" cometer, para preparar para el cambio de nombre real en los próximos pasos)
  4. git branch git_mv_20110708_1500_DO_NOT_USE (rama "falso", fecha y hora recordando que sólo hicimos esto como una solución )
  5. /bin/rm -Rf <new-dir-name>
  6. cp -Rp .../<new-dir-name> . (Copia sobre la carpeta actual con la nombre renombrado)
  7. git status (archivos más modificados ahora se marcará correctamente como modificado, no "eliminado". Los archivos que han sido renombrados serán marcados como y agregados, a pesar de tener el mismo contenido. - medidas repetidas 1-7 para esos archivos si se necesita seguimiento de cambio de nombre para ellos también)
  8. git add <untracked files>
  9. git commit -a -m "finally renamed this folder"
  10. git branch FOLDER_RENAMED :)

P. S. A gitk le encanta esto, pero Emacs todavía se confunde con los cambios de nombre. :(

3

Es necesario utilizar mv de git: http://www.kernel.org/pub/software/scm/git/docs/git-mv.html

git mv old_dir new_dir 

por lo que tendrá necesita mover el nuevo directorio de nuevo a viejo, y moverlo nuevamente con mv.

EDIT: Para contestar las respuestas a mi respuesta:

decidí probar esto a mí mismo. Creé dos archivos con texto distinto, y usé git mv en uno, y mv file file2, git add file2, git add -u en el otro. El mensaje de confirmación indicó que ambos fueron rastreados como renombrados. Por lo tanto, todo lo que mi consejo hace es guardar un paso, como decían los demás.

+7

Esto es equivalente a hacer 'git rm' en los nombres de archivos antiguos y' git add' en los nuevos. Git rastrea el contenido, no los cambios. Los cambios se deducen a pedido cuando los solicita. – hammar

+0

@d_r_w Mi comprensión de [esto] (http://stackoverflow.com/questions/1094269/whats-the-purpose-of-git-mv/1094392#1094392) es 'git mv' es solo una abreviatura que da como resultado el mismo problema: si uso 'gitk' para diferenciar entre la nueva versión y el nuevo nombre, no puedo porque están listados como dos archivos diferentes. – WinWin

+0

intente un 'git diff -M', y asegúrese de que detecta los cambios de nombre. – Novelocrat

16

Solo git add el directorio en su nuevo nombre. Git no rastrea explícitamente los nombres, solo los detecta más tarde. git mv puede ser marginalmente más eficiente de realizar (porque puede actualizar el índice directamente), pero el efecto es exactamente el mismo.

+0

Eso es exactamente lo que entiendo y por qué estoy preguntando: ¿Hay alguna manera de decirle a Git que cambie los nombres? Entonces, si utilizo 'gitk', por ejemplo, para diferenciar entre el nombre anterior y el nombre más reciente, ¿podré hacerlo? – WinWin

+2

@ WinWin: Eso depende de la herramienta. Por ejemplo, 'git diff' tiene una opción' -M' que le permite especificar qué cantidad de un archivo debe coincidir para que se muestre como un cambio de nombre. – hammar

+0

@hammar Esa es una gran opción, no lo sabía. ¿Está disponible para 'git status' y' git commit' también? – WinWin

0

El problema es una interfaz de usuario/experiencia del usuario problema, en lugar de un problema 'real' de git. Le he pedido a la misma pregunta how-to-work-with-subdirectory-renames-in-git y otra pregunta subyacente how-does-git-record-or-more-likely-represent-file-paths-and-names-for-its-blob

De hecho Git no lo hace realmente importa. Todos los mensajes que recibimos son sobre lo que 'diff' cree que pudo haber sucedido. Con otras opciones los mensajes serán diferentes pero el repositorio no será diferente (¡es la misma instantánea!).

Un estilo de opción es la opción subtree para diff (aunque es para un propósito diferente), como es --patience.

Existe la necesidad de una mejor opción de UI/UX que detecte con mayor facilidad los cambios de ruta (en función de los árboles en lugar de los blobs). Parte del problema es the subtle mistake en el argumento de Linus. Tiene razón en que el repositorio de Git debe no almacenar el cambio de nombre (cambio de ruta) explícitamente, sino que necesitamos una opción para permitir su descubrimiento adecuado.

Cuestiones relacionadas