Как ДЕЙСТВИТЕЛЬНО показывать журналы переименованных файлов с помощью git?

Я относительно новичок в git, раньше я использовал Subversion.

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

git log --follow

в командной строке, я могу просмотреть весь журнал через переименования.

По словам Линуса Торвальдса, переключатель -follow - это "уловщик SVN noob", серьезные пользователи git не используют его:

- follow - это полный хак, предназначенный только для удовлетворения пользователей ex-SVN, которые никогда не знал что-нибудь о вещах вроде родительские или красивые графики в любом случае.

Это не совсем фундаментально, но текущая реализация "--follow" действительно быстро препроцессорная вещь болтовал на ревизии ходьбе логикой, а не чем-либо действительно интегральный.

Он буквально был разработан как "SVN noob", а не как "реальный gitфункциональности". Идея заключалась в что вы уберетесь от (сломанного) мышление, которое переименовывает материя в большой картине.

Мой вопрос. Как пользователи хардкора git получают историю файлов, когда они были переименованы? Каков "реальный" способ сделать это?

Ответы

Ответ 1

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

Переименование файла - это небольшой частный случай "содержимого", перемещающийся между путями. У вас может быть функция, которая перемещается между файлами, которые пользователь git может отслеживать с помощью функции "pickaxe" (например, log -S).

Другие изменения "пути" включают объединение и разбиение файлов; git действительно не заботится о том, какой файл вы переименовали и какой из них вы считаете скопированным (или переименованным и удаленным), он просто отслеживает полное содержимое вашего дерева.

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

Ответ 2

У меня точно такая же проблема, с которой вы столкнулись. Несмотря на то, что я не могу дать вам ответа, я считаю, что вы можете читать это письмо Linus написал еще в 2005 году, это очень уместно и может дать вам подскажите, как справиться с проблемой:

& hellip; Я утверждаю, что любой SCM, который пытается отслеживать переименования, в корне если это не сделано по внутренним причинам (т.е. дельта), именно потому, что переименования не имеют значения. Они вам не помогают, и они все равно не заинтересованы.

Важно то, что "откуда это взялось", и gitархитектура делает это очень хорошо - намного лучше, чем что-либо еще там. & Hellip;

Я нашел ссылку на это сообщение в блоге, которое также может быть полезно для вас, чтобы найти жизнеспособное решение:

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

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

  • Конец действительно ввел блок кода. Автор сообщения был изобретателем этой прекрасной функции, которую вы искали для своего происхождения (или виновной стороной, которая представила ошибку); или
  • Блок кода не существует в файле, но пять идентичных его копий существовали в разных файлах, все из которых исчезли после коммита. Автор транзакции реорганизует дублированный код, вводя одну вспомогательную функцию; или
  • (как особый случай) Перед фиксацией файла, который в настоящее время содержит блок кода, который вас интересует сам, не существует, но существует другой файл с почти идентичным содержимым, а блок кода, который вы заинтересованный, вместе со всем остальным содержимым в файле, существовавшим тогда, существовал в этом другом файле. Он ушел после совершения. Автор сообщения переименовал файл, предоставив ему небольшую модификацию.

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

Пожалуйста, держите нас в курсе ваших успехов на этом.

Ответ 3

Я заметил, что большинство графических плагинов git front-end и IDE, похоже, не могут отображать историю файла, если файл был переименован

Вы будете рады узнать, что некоторые популярные инструменты git UI теперь поддерживают это. Существуют десятки инструментов git UI, поэтому я не буду перечислять их все, но, например:

  • SourceTree, при просмотре журнала файлов, имеет флажок "Следовать за переименованными файлами" в левом нижнем углу
  • TortoiseGit имеет флажок "follow renames" в окне журнала в левом нижнем углу.

Дополнительная информация о инструментах пользовательского интерфейса git:

Ответ 4

Примечание: git 2.9 (June2016) немного улучшит "баггский" характер git log --follow:

См. commit ca4e3ca (30 марта 2016 г.) SZEDER Gábor (szeder).
(слияние Junio ​​C Hamano - gitster - в commit 26effb8, 13 апреля 2016 г.)

diffcore: исправить порядок итерации идентичных файлов при обнаружении переименования

Если два пути "dir/A/file" и "dir/B/file" имеют идентичный контент и родительский каталог переименовывается, например. 'git mv dir other-dir', тогда diffcore сообщает о следующих точных переименованиях:

renamed:    dir/B/file -> other-dir/A/file
renamed:    dir/A/file -> other-dir/B/file

(обратите внимание на инверсию здесь: B/file -> A/file и A/file -> B/file)

Хотя технически это не так, это путает не только пользователя, но также и для команд git, которые принимают решения на основе переименования информации, например. 'git log --follow other-dir/A/file' следует 'dir/B/file' после переименования.

Это поведение является побочным эффектом commit v2.0.0-rc4 ~ 8 ^ 2 ~ 14 (diffcore-rename.c: упростить поиск точных переименований, 2013-11-14): Источники хранения хеш-карт возвращают записи из одного и того же ведра, т.е. источники, соответствующие текущему пункту назначения, в порядке LIFO.
Таким образом, итерация сначала исследует "other-dir/A/file" и "dir/B/file", а при поиске идентичного содержимого и базового имени сообщает точное переименование.

Ответ 5

В Linux я проверил, что SmartGit и GitEye могут отслеживать переименования, следуя истории конкретного файла. Однако, в отличие от gitk и GitEye, SmartGit показывает отдельный просмотр файлов и репозиторий (который содержит структуру каталогов, но не список файлов, содержащихся внутри)