Mover files en el repository de Git

Quiero reestructurar mis files y carpetas en Git Repo sin perder las Historias.

El repository actual de Git se ha migrado desde SVN y tiene los historiales de SVN.

Ahora, cuando trato de mover los files alnetworkingedor del repository de Git, estoy perdiendo el historial actual de Git, pero tengo los viejos antecedentes de SVN que se migraron de SVN. Pero, quiero tener todas las historias cuando muevo los files y las carpetas.

He probado git mv, log –follow, solo cortar y pegar, etc … pero nada hace un seguimiento de las nuevas historias de Git.

Estoy confundido de varias respuestas en Internet. Nada funciona para mí, por desgracia. 🙁

¿Cualquier sugerencia?

Gracias, Vashni

Git no rastrea el historial de files.

Git rastrea el contenido y mantiene el historial de commit .

Lo que esto significa es que si tienes algunas confirmaciones existentes, y luego mueves los files y haces nuevas confirmaciones con las confirmaciones existentes como su historial, las nuevas confirmaciones tienen las confirmaciones anteriores como su historial de compromisos.

Los files movidos no tienen historial, pero los files antiguos tampoco tenían historial. Cuando utilizas el git log estás viendo el historial de commits , comenzando con el que te nombre, si no especificas una confirmación inicial, el git log comienza con HEAD y luego regresas desde allí a commits anteriores.

Esto es cierto incluso si usa git log -- path : todavía está mirando el historial de commits. Simplemente le ha indicado a git que le muestre solo un subset del historial de confirmaciones, es decir, confirma dónde ha cambiado la path entre esa confirmación y su confirmación pnetworkingecesora. Es decir, si ve commit 1234567 en el logging, esto significa que git diff --name-status 1234567^ 1234567 le mostrará un cambio en el estado del file nombrado por path (entre otros cambios de nombre y estado) .

(La syntax commit ^ , que es cualquier nombre válido para una confirmación seguida de un carácter simple ^ , significa encontrar el padre del compromiso, es decir, el compromiso que estaba vigente justo antes de commit se haya realizado la commit . También puede escribir esto como commit ~1 .)

Cuando agrega --follow (y nombra una única path ), esto le dice a git log una cosa más: si el cambio de estado para la path dada es un cambio de nombre, el git log puede cambiar la forma en que se ve en las confirmaciones anteriores. Ya sabemos que, dado que git log está mostrando este compromiso, el git diff mostrará un nombre y un estado para ese file. En la mayoría de los casos, el estado del file será simplemente M , lo que indica que el file ya existía y se modificó. Pero si el estado es R , esto indica que git diff calculó que entre la confirmación principal y esta confirmación, el file fue renombrado .

Sin --follow , git log probablemente ya no verá la path nombrada (porque el diff lo calculó como cambiado de nombre), y dejará de mostrar commits. (Puede retomarse nuevamente con confirmaciones incluso anteriores si algún otro contenido tiene la misma ruta en esas confirmaciones anteriores, pero esto depende de las confirmaciones anteriores, y no es tan común). Con --follow , sin embargo, el git log toma nota del hecho de que git diff decidió, cuando hizo la diferencia justo ahora, que el file había sido renombrado. Luego deja de search la path bajo ese nombre, y comienza a search la ruta que git diff decidió que se había cambiado el nombre del contenido .

Es decir, supongamos que el git log compara la confirmación ab93513 anterior (padre) con la confirmación ab93513 más reciente (hijo). Supongamos además que git diff decide que el contenido de dir1/dir2/old.txt en commit ab93513 convirtió en el contenido del file dir8/dir9/new.txt . Y, finalmente, supongamos que solicitó a git log que le muestre dir8/dir9/new.txt con la opción --follow . Entonces, dado que el cambio de git diff calcula en este punto es "contenido similar, renombre ocurrido", git log cambia de search dir8/dir9/new.txt a search dir1/dir2/old.txt .

La key de este process es la detección de cambio de nombre. Dado que git no rastrea el historial de files, debe detectar el cambio de nombre. La detección de renombrados es bastante confiable, pero no perfecta, y depende de cómo configure git, y de si los contenidos de los files coinciden exactamente o simplemente "suficientemente similarmente". Y --follow , en git log , solo sigue un path a la vez (y solo hacia atrás a través de la historia; esto realmente debería funcionar cuando usas --reverse , pero el código es que implementa– el --follow es un truco horrible y solo funciona en una dirección de time).