• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Контроль истории Git

Count Zero

coder
Пользователь
Регистрация
18.06.2023
Сообщения
21
Реакции
11
Чтобы понять что тут изложено, нужно обладать хотя бы базовыми навыками работы с Git.

Система контроля версий (Git) хранит в хронологическом порядке все изменения выполненные в отслеживаемых git add файлах. Для каждого изменения git commit сохраняет diff с меткой времени, информацию об авторе и подобное. Diff - это разница между тем, каким знает файл Git и тем что лежит на диске. И по этой истории можно перемещаться вверх-вниз, откатывая или применяя изменения вновь.
Первый раз гит ничего не знает о файле, поэтому git checkout, при откате, удалит файл с диска. Но не из истории коммитов.
Удалить историю тоже можно, git reset позволит откатить изменения с уничтожением коммитов и покрывает кейс линейного отката всех изменений.
Последствия git reset необратимы!

Переписываение истории​

git_1.png


Допустим ситуацию. Был зафиксирован secret.py в котором находится какая-то чувствительная информация. И теперь у нас задача убрать эту информацию.

Первый способ - удалить файл. Если это позволительно.
Хелп команды git filter-branch встречает нас описанием применения

Lets you rewrite Git revision history by rewriting the branches mentioned in the <rev-list options>, applying custom filters on each revision.

И щедро одаривает примерами.

Suppose you want to remove a file (containing confidential information or copyright violation) from all commits:

git filter-branch --tree-filter 'rm secret.py' HEAD

Второй способ - перестроить историю.

git_2.png


Начинать следует от места первого инцедента. В случае на скрине, коммит add secret впервые упоминает чувствительные данные.

git_3.png


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

git_4.png


Такой контекст позволяет перезаписать чувствительные данные, выполнив amend-коммит.
После такого коммит add secret потерял темно-синий фон, потому что теперь в этом месте история разделяется. И появляется новая линия, которая сигнализирует о расхождении в истории.

Следующий шаг - это перемещение остальных коммитов из мастера в текущую ветку new-age.
Выбираются все коммиты, кроме add secret. Если выбрать этот коммит к ошибке не приведет, а добавит работы, на один merge-конфликт будет больше. И на один коммит будет больше.
Выбранные коммиты, нужно git cherry-pick-нуть и за-git merge-ить конфликты. Так как первая строка secret.py менялась много раз. И при пике коммита, в котором эта строка менялась, будет запрошено действие пользователя для принятия окончательного решения.

git_5.png


Результат cherry-pick.
Светло-синий фон это отмеченные из мастера коммиты для перемещения. Темно-синий - это коммиты в текущей ветке.

git_7.png


Текущий контекст: master - отмечаный на удаление и new-age - с результатом. Лучше сделать бекап мастера, затем удалить и создать ветку от new-age с имененм master.

Редактирование информации о коммитах​

git filter-branch можно попросить поменять что-то в коммитах, например имя пользователя или его email.
На случай если мыло просочиться в коммиты.

Bash:
git filter-branch --env-filter '
       if test "$GIT_AUTHOR_EMAIL" = "user@localhost"
       then
               GIT_AUTHOR_EMAIL=count0@example.com
       fi
' -- --all

git_7.png


На всех скринах выше выдно, что пользователь user@localhost, эта команда поменяет его на count0@localhost

git_8.png


И вот он результат.
 
Последнее редактирование:


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх