Подтвердить что ты не робот

Как сказать Git, что это тот же каталог, просто другое имя

После прохождения нескольких препятствий, изучающих Git, я столкнулся с новым вызовом: переименование каталога (локально, в рабочем каталоге).

Когда я набираю git status, он перечисляет все файлы в старом имени каталога (которые существуют с одинаковыми точными именами файлов в новом каталоге) как удален, а новое имя каталога - как "untracked".

Есть ли способ сообщить Git, что "это фактически тот же каталог, просто другое имя"?

Итак, все файлы будут перечислены в git status только как измененные?

Чтобы проиллюстрировать проблему, вот вывод, который я получаю от git status при переименовании целого каталога:

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>
4b9b3361

Ответ 1

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

  • git mv <old-dir-name> <new-dir-name>
  • git status (убедитесь, что все файлы отмечен переименован, а не "удален" )
  • git commit -a -m "git mv <old-dir-name> <new-dir-name>" (это "поддельная" фиксация, подготовка для реального переименования в следующем шаги)
  • git branch git_mv_20110708_1500_DO_NOT_USE ( "поддельная" ветвь с меткой времени напоминая, что мы сделали это только как обходной путь)
  • /bin/rm -Rf <new-dir-name>
  • cp -Rp .../<new-dir-name> . (копия над фактической папкой с переименованное имя)
  • git status (большинство измененных файлов теперь будут правильно отмечены как изменено, а не "удалено". Файлы, которые были переименованы, будут помечены как удаленные и добавленные, несмотря на то же содержание! - повторите шаги 1-7 для этих файлов, если для них также требуется переименовать отслеживание)
  • git add <untracked files>
  • git commit -a -m "finally renamed this folder"
  • git branch FOLDER_RENAMED:)

P.S. gitk любит это, но Emacs все еще путается с переименованиями.: (

Ответ 2

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

Ответ 3

Вам нужно использовать git mv: http://www.kernel.org/pub/software/scm/git/docs/git-mv.html

git mv old_dir new_dir

Итак, вам нужно переместить новый каталог обратно в старый и переместить его с помощью mv.

EDIT: Чтобы ответить на мои ответы:

Я решил проверить это сам. Я создал два файла с разным текстом и использовал git mv на одном, а mv file file2, git add file2, git add -u - с другой. Сообщение Commit указано, что оба они были отслежены как переименования. Поэтому все мои советы - это шаг, как говорили другие.

Ответ 4

Git 2.18 (Q2 2018) должен обнаружить "это тот же каталог, просто другое имя", потому что " git status " научился обращать внимание на переменные конфигурации конфигурации UI, такие как diff.renames.

См. Commit dc6b1d9 (04 мая 2018 года) Экхардом С. Маасом ('').
(Слияние с Юнио С Хамано - gitster - в совершении 1e174fd, 23 мая 2018 года)

wt-status: использовать настройки из git_diff_ui_config

Если вы сделаете что-то вроде:

- git add .
- git status
- git commit
- git show (or git diff HEAD)

можно было бы ожидать аналогичного выхода из git status и git show (или аналогичных программ, связанных с diff).
Обычно это не так, поскольку git status имеет жестко закодированные значения для опций, связанных с diff.

С этой фиксацией жестко закодированные настройки git_diff_ui_config из команды состояния в пользу значений, предоставляемых git_diff_ui_config.

Ниже приводятся некоторые замечания о конкретных вариантах, которые были жестко закодированы в git status:

'diffopt.detect_rename'

Начиная с самого начала git-статуса в a3e870f ("Добавить" commit "helper script", 2005-05-30, Git v0.99), git status всегда использовал обнаружение переименования, тогда как с командами, такими как show и log, приходилось его активировать с опцией командной строки.
После 5404c11 ("diff: активировать diff.renames по умолчанию", 2016-02-25, Git v2.9.0) по умолчанию ведет себя одинаково по совпадению, но изменение diff.renames на другие значения может нарушить согласованность между git status и другими команды снова.
С этим diff.renames управляют одинаковым поведением по умолчанию с diff.renames.

'diffopt.rename_limit'

Точно так же есть опция diff.renamelimit, чтобы настроить этот предел для всех команд, но git status. С этим статусом фиксации git также будет уважать их.


И тот же Git 2.18 предлагает status.renames, что может быть полезно для тех, кто хочет это сделать, не отключая обнаружение переименования по умолчанию, выполненное командой " git diff ".

См. Фиксацию e8b2dc2 (11 мая 2018 года) Бен benpeart (benpeart).
(Слияние с Юнио С Хамано - gitster - в совершении 5da4847, 30 мая 2018 года)

добавить конфигурацию состояния и параметры командной строки для определения переименования

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

Добавьте новый параметр config status.renames чтобы включить отключение переименования во время состояния и фиксации.
По умолчанию этот параметр будет равен значению diff.renames.

Добавьте новую конфигурацию status.renamelimit чтобы включить ограничение времени, затрачиваемого на поиск неточных переименований во время состояния и фиксации.
По умолчанию этот параметр будет diff.renamelimit значению diff.renamelimit.

Добавить --no-renames командной строки в состояние, которое позволяет переопределить настройку конфигурации из командной строки.
Добавьте --find-renames[=<n>] командной строки --find-renames[=<n>] в состояние, которое позволяет обнаруживать переименования и необязательно устанавливать индекс подобия.

Ответ 5

Проблема связана с проблемой пользовательского интерфейса/пользователя, а не с "реальной" проблемой для git. Я задал тот же вопрос how-to-work-with-subdirectory-renames-in-git и основной вопрос how-does-git-record-or-more-likely-represent-file-paths-and-names-for-its-blob

Фактически Git на самом деле не заботится. Все сообщения, которые вы (мы) получаем, касаются того, что могло бы произойти "diff". С другими вариантами сообщения будут отличаться, но репозиторий не будет отличаться (это тот же снимок!).

Один стиль опций - это опция subtree для diff (хотя для другой цели), как и --patience.

Существует потребность в улучшенном варианте UI/UX, который будет легче обнаруживать изменения пути (на основе деревьев, а не капли). Частью проблемы является тонкая ошибка в аргументе Linus. Он прав, что репозиторий Git должен не хранить переименование (pathchange) явно, скорее нам нужна опция, чтобы разрешить его правильное обнаружение.