Git: Поиск файлов, в которых изменен только serialVersionUID - PullRequest
0 голосов
/ 04 марта 2019

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

final static long serialVersionUID = -4268385597939353497L;

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

Примечание: это установлено в камне, и я знаю, что «не проверять сгенерированный код в системе контроля версий и т. Д.».

Как я могу определить все файлы, где только serialVersionUID изменился? Изменено означает, что файлы изменены в рабочей копии, но еще не зафиксированы.

Моя цель - вернуть эти файлы с помощью ловушки перед фиксацией.

У меня естьзайдите либо

git diff -U10000 --raw MyFile.java

, который дает мне разность всего файла, либо

git diff -U0 --raw --word-diff=porcelain MyFile.java

, который дает мне "заголовок разницы" плюс список изменений.

1 Ответ

0 голосов
/ 04 марта 2019

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

Здесь важнообратите внимание, что здесь есть три копии каждого файла:

  • тот, что находится в вашем текущем коммите, HEAD:MyFile.java (используйте git show HEAD:MyFile.java, чтобы увидеть этот);
  • тот, который в вашем предложил следующий коммит , :MyFile.java (снова, используйте git show, чтобы увидеть его);и
  • в вашем рабочем дереве , MyFile.java, которое вы можете просматривать и редактировать напрямую.

Команда git diff выполнит командуВообще, для сравнения выберите два из трех .

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

Использование git diff --cached сообщает Gitсравнить файл (ы) в HEAD с файлом (ами) в индексе.Использование git diff HEAD говорит Git сравнивать файл (ы) в HEAD с файлом (ами) в рабочем дереве.Так вот как вы выбираете, какие пары файлов будут сравниваться.Но несмотря ни на что, каждый git diff просто выбирает одну пару файлов или один набор пар, если вы разрешаете Git сравнивать все файлы.

Если вы запускаете git commit -a- и я рекомендую вам не здесь - это примерно эквивалентно git add -u && git commit, за исключением того, что он создает временный индекс с обновленными файлами.Ситуация становится особенно сложной в различных хуках фиксации, поскольку теперь существует несколько разных индексных файлов с разными предлагаемыми следующими коммитами.Вот почему я рекомендую избегать git commit -a здесь.Уже достаточно сложно работать с тремя копиями файла и использовать сложные варианты фиксации, такие как -a или --only или --include, выбрасывающие четвертый и даже иногдапятый набор копий в миксе.

(Git может обрабатывать только один индексный файл за раз. Стандарт git commit имеет только один стандартный индексный файл. Стандартный индексный файл имеет копии файлов, которыебудет или будет переходить к следующему коммиту. 1 Опции заставляют Git создавать дополнительные временные индексные файлы, в которые он строит предложенный новый коммит, а затем запускать остальные операции - включая ваши перехватчики - с помощью $GIT_INDEX_FILE установлен в среде, чтобы эти подкоманды смотрели на какой бы временный индекс ни использовался. Если все идет хорошо и git commit завершает создание нового коммита, один из этих различных файлов временного индекса с любым подходящим содержимымосновываясь на опциях и аргументах, становится новым индексом, после чего вы возвращаетесь к нормальной ситуации.Это всего три копии каждого файла.)

Поскольку ваш план заключается в том, чтобы работать в режиме предварительной фиксации, вы, вероятно, должны сравнить HEAD файлы с предлагаемыми для использованиязафиксировать файлы в индексе, т. е. вам, вероятно, следует использовать git diff --cached здесь.Однако, если вы намереваетесь сделать это с помощью компьютерной программы , а не как что-то, что человек просматривает на досуге, вам вообще не следует использовать git diff.Команда front-end git diff предназначена для использования people , поэтому она разбивает на страницы и окрашивает вывод и делает все, что просто раздражает компьютерные программы.Git называет эти модные интерфейсы фарфоровыми командами .

EaТип ch git diff реализуется серверной командой plumbing .Сантехническая команда, которая сравнивает фиксацию - технически, дерево - с индексом git diff-index, которому все еще нужно --cached, чтобы сказать ей выполнить желаемое сравнение: git diff-index --cached HEAD производит предсказуемый результат, которыйне зависит от предпочтительного пейджера каждого пользователя, стилей цвета и т. д.

(Если вы пишете этот хук исключительно для собственного использования, вы можете использовать git diff или git diff-index, так как вы можетекомпенсировать ваши собственные git diff настройки. Но в некотором смысле лучше в любом случае использовать сантехническую команду - тогда вам не нужно ничего компенсировать.)

Что бы вы ни выбрали здесь, вам все равно придетсянаписать свой собственный код для интерпретации различий.Вместо этого вы можете написать программу, которая просто извлекает два представляющих интерес файла - HEAD:MyFile.java и :MyFile.java, то есть - из текущего коммита и из индекса, и сравнивать их в своей собственной программе, вместо использования * 1106.* совсем.Вы можете извлечь файлы, используя git show, но есть небольшой недостаток, что это другая фарфоровая команда.Вы можете использовать git cat-file -p, которая является основной сантехнической командой, чтобы извлекать файлы напрямую, без выполнения git show.

На самом деле синтаксический анализ кода Java был бы самым надежным методом, так что вы неЭто может привести к глупому изменению форматирования.Более хакерский метод, такой как допущение, что все должно совпадать, за исключением одной строки определенной формы, будет не слишком сложным, скажем, в awk (прочитайте оба файла по одной строке за раз, убедитесь, что только одна строка отличается в двухфайлы и что он имеет ожидаемую форму).Кажется, что все это проще, чем пытаться разобрать вывод diff, хотя, если вы хотите разобрать вывод diff, неконтекстный diff без Git может быть проще.

Наконец, относительно:

Моя цель - вернуть эти файлы с помощью ловушки перед фиксацией.

Этот можно сделать ОК (Git будет обрабатывать его правильно, для некоторого определения "правильно "), но это также немного удивляет многих пользователей Git.Git-хуки вроде этого не должны изменять вещи.Цель людей, пишущих Git, заключается в том, чтобы такие хиты Git просто проверяли вещей.Если что-то не проходит этап проверки, ловушка должна выйти из ненулевого значения, что приведет к остановке git commit.Предполагается, что любое исправление может быть выполнено с помощью некоторой операции без перехвата.

Обратите внимание, что git commit --no-verify пропускает хук перед фиксацией полностью.


1 Технически, индекс имеет ссылки на копий каждого файла только для чтения.Поскольку эти копии предназначены только для чтения, ими можно поделиться.Таким образом, «копирование» индекса обходится дешево, потому что он действительно просто копирует все ссылки.Кроме того, каждый файл, который находится в предложенном новом коммите, который на 100% бит-бит идентичен файлу, который уже находится в некотором существующем коммите, на самом деле является просто ссылкой на этот файл, поскольку каждый файл, сохраненный в каждом коммите, сам полностью читается.только.

...