Как ДЕЙСТВИТЕЛЬНО показывать логи переименованных файлов с помощью git? - PullRequest
114 голосов
/ 21 апреля 2011

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

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

git log --follow

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

Согласно Линусу Торвальдсу ключ --follow является "SVN Noob", и серьезные пользователи Git не используют его:

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

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

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

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

Ответы [ 5 ]

65 голосов
/ 21 апреля 2011

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

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

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

34 голосов
/ 12 апреля 2012

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

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

Важно найти «откуда это взялось» и мерзавца архитектура делает это очень хорошо - гораздо лучше, чем все остальное там & Hellip;

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

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

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

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

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

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

11 голосов
/ 08 сентября 2014

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

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

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

Дополнительная информация об инструментах интерфейса Git:

6 голосов
/ 14 апреля 2016

Примечание: git 2.9 (июнь 2016 г.) немного улучшит «глючную» природу git log --follow:

См. commit ca4e3ca (30 марта 2016 г.) от SZEDERГабор (szeder) .
(Объединено Junio ​​C Hamano - gitster - в коммит 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» после переименования.

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

2 голосов
/ 02 января 2015

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...