Как я могу использовать git для создания только одной строки в файле для фиксации, все из script?

Я пишу простой pre-commit git hook, который обновляет год в заголовках авторских прав для файлов, поставленных для фиксации.

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

Я не вижу никаких параметров в руководстве git add, чтобы вы могли создавать определенные строки.

Я полагаю, что могу git stash save --keep-index применить мое изменение, git add файл, а затем git stash pop, но это кажется довольно грубым. Любые лучшие подходы?

Ответ 1

Здесь другое возможное решение:

  • Перед запуском вашей модификации авторских прав script сделайте git status, чтобы получить список файлов, которые он собирается совершить. Сохраните список файлов. Сделайте фиксацию.

  • Затем запишите оставшиеся (несвязанные) изменения и примените ваш script к списку файлов, сохраненных выше. Используйте git commit --amend, чтобы изменить предыдущую фиксацию.

  • Наконец, всплывающее окно, чтобы восстановить индекс. При необходимости разрешите конфликты.

Я не знаю, как сказать git add добавлять только определенные строки. Как бы вы описали строки, которые нужно добавить? По номеру строки? Похоже, что это возможно в узком наборе обстоятельств и не в целом полезно.

Ответ 2

Вы можете исправить поэтапную версию файла на отдельном этапе, например.

blobid=$(git show :"$filepath" | copyright-filter | git hash-object -w --stdin)

if $? -eq 0; then

    git update-index --cacheinfo 100644 "$blobid" "$filepath" &&
    copyright-filter "$filepath"

fi

Я бесстыдно предположил, что ваш script называется copyright-filter и работает как фильтр или на месте, в зависимости от его аргументов.

Ответ 3

Глядя на источник на git add --interactive, он выглядит так, как он изменяет индекс с помощью git apply --cached. Предполагая, что ваше авторское право является первым шрифтом любого diff, внесите изменения и используйте:

git diff -- file | 
awk 'second && /^@@/ {exit} /^@@/ {second=1} {print}' |
git apply --cached

Если эта вторая строка (awk script захватывает только первый diff hunk). Вы также можете построить выход diff вручную или использовать другие правила для выбора hunk.