Как сказать Git, что это тот же каталог, просто другое имя
Пройдя через несколько препятствий на пути изучения Git, я столкнулся с новой проблемой: переименование каталога (локально, в рабочем каталоге).
Когда я печатаю git status
, в нем перечислены все файлы в старом имени каталога (которые существуют с теми же точными именами файлов в новом каталоге), что и удаленные, и новое имя каталога как "неотслеживаемые".
Есть ли способ сказать 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>
5 ответов
Все ответы здесь были очень полезны на пути к фактическому решению для конкретного сценария, с которым я столкнулся. Я предоставляю то, что сработало для меня, в форме реальных шагов, надеюсь, помогая другим, сталкивающимся с той же проблемой:
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
:)
PS gitk
любит это, но Emacs
все еще путают с переименованиями.:(
Просто git add
каталог с новым именем. Git явно не отслеживает переименования, он просто обнаруживает их позже. git mv
может быть немного более эффективным для выполнения (потому что он может обновлять индекс напрямую), но эффект точно такой же.
Вам нужно использовать git's mv: http://www.kernel.org/pub/software/scm/git/docs/git-mv.html
git mv old_dir new_dir
Поэтому вам нужно переместить новый каталог обратно в старый и перенести его с помощью mv.
РЕДАКТИРОВАТЬ: Чтобы ответить на ответы на мой ответ:
Я решил проверить это сам. Я создал два файла с отличным текстом и использовал git mv
на одном и mv file file2
, git add file2
, git add -u
с другой. Сообщение фиксации указывало, что оба были отслежены как переименования. Поэтому все, что я советую сделать, это сохранить шаг, как говорили другие.
Git 2.18 (Q2 2018) должен обнаружить, что "это тот же каталог, просто другое имя", потому что " git status
"научился обращать внимание на переменные конфигурации, связанные с пользовательским интерфейсом, такие как diff.renames
,
См. Коммит 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 status
:`diffopt.detect_rename`
С самого начала состояния git в a3e870f ("Добавить", зафиксировать "вспомогательный скрипт", 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
,`diffopt.rename_limit`
Точно так же есть опция diff.renamelimit, чтобы настроить этот предел для всех команд, кроме состояния git. С этим коммитом git status также будет чтить тех.
И то же самое предложение Git 2.18 status.renames
, что может быть полезно для тех, кто хочет это сделать, не отключая обнаружение переименования по умолчанию, выполняемое командой " git diff
"команда.
См. Коммит e8b2dc2 (11 мая 2018 г.) Бен Пирта ( benpeart
)
(Объединено Юнио С Хамано - gitster
- в комитете 5da4847 от 30 мая 2018 года)
добавить конфигурацию состояния и параметры командной строки для обнаружения переименования
После выполнения слияния, которое имеет конфликты
git status
по умолчанию попытается обнаружить переименования, что приведет к проверке многих объектов.
В виртуализированном репо эти объекты не существуют локально, поэтому логика переименования запускает их выборку с сервера. Это приводит к тому, что вызов состояния завершается на очень больших репозиториях против секунд с этим патчем.Добавить новый конфиг
status.renames
настройка, позволяющая отключить обнаружение переименования во время состояния и фиксации.
Этот параметр по умолчанию будет иметь значение diff.renames.Добавить новый конфиг
status.renamelimit
установка для включения ограничения времени, затрачиваемого на поиск неточных переименований во время статуса и фиксации.
Этот параметр будет по умолчанию равным значениюdiff.renamelimit
,добавлять
--no-renames
опция командной строки для состояния, которая позволяет переопределить настройку конфигурации из командной строки.
добавлять--find-renames[=<n>]
опция командной строки для состояния, которая позволяет обнаруживать переименования и, возможно, устанавливать индекс сходства.
Проблема в пользовательском интерфейсе / пользовательском опыте, а не в "реальной" проблеме для git. Я задал тот же вопрос " как работать с подкаталогом-переименовывает в git" и основной вопрос " как делать-git-запись-или-более-вероятно-представлять-путь-файлы-и-имена-" в-ее-сгустка
На самом деле Git на самом деле не волнует. Все сообщения, которые вы (мы) получаете, о том, что, по мнению "diff", могло произойти. С другими опциями сообщения будут отличаться, но хранилище не будет отличаться (это тот же снимок!).
Одним из вариантов стиля является subtree
Опция для сравнения (хотя это для другой цели), как это --patience
,
Существует потребность в лучшей опции UI/UX, которая бы легче обнаруживала пути обмена (основанные на деревьях, а не на BLOB-объектах). Часть проблемы - тонкая ошибка в аргументе Линуса. Он прав, что репозиторий Git не должен явно хранить переименование (pathchange), нам нужна опция, позволяющая правильно его обнаруживать.