Получение Git для подтверждения ранее перемещенных файлов


я переместил кучу файлов вручную, не думая, и не могу найти способ заставить git признать, что файлы просто перемещены, а не на самом деле разные файлы. Есть ли способ сделать это, кроме удаления старого и добавления нового (и, таким образом, потери истории) или повторения всех изменений с помощью git-mv?

5 60

5 ответов:

Я думаю, что он уже делает это. Теперь я могу ошибаться, но я читал, что git отслеживает файлы на основе их содержимого, а не на основе их положения в файловой системе или на основе Дельта/различий. В стеке я думаю, что он показывает это, как если бы файлы были удалены, а затем повторно добавлены, но я думаю, что я пробовал это один раз, и он все еще поддерживал историю, из-за вышеупомянутого способа, которым git отслеживает вещи.

все равно было бы полезно для кого-то, чтобы проверить, если я прав или не. Извините, если я неправильно понял ваш вопрос.

чтобы git удалил файлы, которые уже удалены или перемещены, просто введите

git add -u

git не отслеживает историю отдельных файлов и не обрабатывает перемещения и копии специально, то есть нет специальных метаданных, указывающих на то, что произошло перемещение или копирование. Вместо этого каждая фиксация git представляет собой полный снимок рабочего дерева.

если вы хотите увидеть движения в git log вы можете поставить -M в дополнение к опции, которая перечисляет, какие файлы были изменены, например

git log --summary -M

git будут смотреть на соседние деревья в фиксации история и вывод, если какие-либо файлы перемещаются по каждой фиксации.

чтобы найти копии, а также переименовать вы можете использовать -C вариант, вы можете поставить его дважды, чтобы сделать git сложнее искать возможные источники копирования за счет некоторой производительности.

git log --summary -M -C -C

обратите внимание, что поскольку git не хранит историю файлов (только историю фиксации), даже если вы сделали git rm и git mv файл, вы не потеряете ни истории. Все изменения в пути будут по-прежнему записываться и отображаться в виде git log.

чтобы лучше понять, почему Git делает переименовать обнаружения вместо (более распространенного) явного отслеживания переименования, и как git logпуть ограничения работает, вы можете прочитать Читать окончательный инструмент отслеживания контента Линуса сообщение в блоге от Junio C Hamano, сопровождающего Git (и ссылки в нем).

вы можете переместить/переименовать новый файл обратно в его старое имя и путь за пределами git, а затем использовать git mv чтобы поставить только ход; например, в bash:

mv $NEW $OLD && git mv $OLD $NEW

это несколько громоздко1, особенно если вы должны сделать это вручную. Но в номере, что он оставляет другие изменения, такие как изменение пространства имен и имя класса не проиндексированы, так что вы можете проверить их и только их, когда вы хотите сделать так.


1я надеюсь найти лучшую альтернативу и обновлю свой ответ, когда найду его.

пример: Я переместил кучу файлов fom oldDir до newDir и начал с упоением с некоторыми другими изменениями. Теперь я хочу проверить, какие еще изменения были сделаны. Используя gitxargsпоглазеть и Баш привело к следующему (на одном линия):

git status --short |
gawk '/^\?\?/ && match(, /newDir\/(*.\.cs)/, a) {print "newDir/" a[1] " " "oldDir/" a[1]}' |
xargs -n 2 bash -c 'mv  ; git mv  '

теперь git status показывает переименования как " изменения, подлежащие фиксации "и текстовые изменения в разделе"изменения, не поставленные для фиксации"