2012-03-16 3 views
2

Как я могу переписать нашу историю фиксации, чтобы гарантировать, что определенные ключевые слова никогда не появятся?Найти/Заменить в Git Commit Log

фона: у нас есть три уровня репозиториев:

  1. Местных - наша среды разработки.
  2. Внутренняя - нашей команды частный GH хранилище
  3. Client - Производство/конечный клиент. Все наши настоящие имена, электронные письма и т. Д. Никогда не должны быть здесь.

я уже нашел, что git-filter-branch может помочь переписать историю, чтобы вырезать имена, используя что-то вроде этого ...

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='safeusername'; GIT_AUTHOR_EMAIL='[email protected]'; GIT_COMMITTER_NAME='safeusername'; GIT_COMMITTER_EMAIL='[email protected]';" HEAD 

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

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

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

Спасибо!

+0

Yikes. Просьба взаимодействовать между репозиториями, где настоящие имена/электронные письма * не могут быть присутствующими, а репозитории, в которых они должны присутствовать, должны ... быть рискованными, если не сказать больше. – Cascabel

+0

К счастью, я держу их в отдельных каталогах и комбинирую любые фильтры, которые я могу использовать в сценарии push. Кроме того, это один из способов. Я никогда не буду извлекать код из клиентских репозиториев - когда-либо. Надеюсь, это упростит (или менее страшно). –

+1

Только вид: вы по-прежнему перемещаете данные в направлении, которое, возможно, утечки информации. Вам действительно нужен * репозиторий * на стороне клиента, со всеми (возможно, переписанными) обязательствами, которые вы совершили в своих внутренних репозиториях? – Cascabel

ответ

0

Хорошо, так что общий поток вы хотите для делать что-то вроде этого:

  • клон/тянуть в неизмененном репо (возможно, новый один каждый раз, когда, возможно повторное использование)
  • запустить фильтр ветвп, Поколдует
  • проверить, что все безопасно
  • публиковать клиентские операции РЕПО

Так первый: магия. Вы хотите использовать git filter-branch --commit-filter my-commit-filter-script. Он вызывается непосредственно вместо commit-tree, принимает необходимые аргументы и сообщение commit на stdin. Так что вы хотите сделать что-то вроде этого:

#!/bin/bash 

GIT_AUTHOR_NAME=$(sanitize "$GIT_AUTHOR_NAME") 
# ... similar for AUTHOR_EMAIL, COMMITTER_(NAME|EMAIL) 

sed 's/scary-string/safe-string/' | 
git commit-tree "[email protected]" 

То есть, изменить имена и электронные письма с помощью соответствующих переменных окружения, запускать любые фильтрации вам нужно на сообщении, и трубы его вместе с фиксации дерева вызов, который был бы запущен нормально. sanitize предназначен для функции/скрипта, который выполняет частное и общедоступное отображение имен/электронных писем; если все, что вы хотите сделать, это изменить их все на одно имя, то этот бит очень прост. И команда sed, предположительно, может быть чем-то странным, что, например, читает таблицу преобразований. Этот бит зависит от вас, в зависимости от сложности дезинфекции, которую вам нужно сделать.

Если вы доверяете своей фильтрации сообщений фиксации, то вы делаете это на этом этапе. Если вы хотите проверить, вы можете сделать это вручную, или вы можете самостоятельно искать «опасные» строки. Например, если у вас есть файл dangerous-strings.txt, вы можете сделать git log --pretty="%an %ae %cn %ce%n%B" [branches] | grep -f dangerous-strings.txt.(Команда журнала печатает имя автора/коммиттера/электронную почту, за которым следует сообщение фиксации.)

Затем опубликуйте как обычно - нажмите, предположительно.

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

  • Вместо переписывания фиксаций, новых фиксаций. Сообщение может быть просто быстрой информацией о версии (включая SHA1 внутренней фиксации, которую она представляет), или может включать в себя краткое изложение введенных коммитов (только субъектов). Вы можете сделать это, сохранив филиал в издательстве и используя git merge --squash [--log], или совершив новое в отдельном репо, после копирования вещей.

  • Сохраните свое репо в форме, которая не нуждается в преобразовании. Это кажется невозможным для OP, но если ваша ситуация другая, сохраните ее просто. Менее рискованно, меньше работы.

+0

Спасибо! Я смогу проверить это коротко ... –

+0

Не совсем работает для меня - вот что я использую/что он выводит: https://gist.github.com/2127452 Если я не могу получить он работает именно так, я могу пойти с вашим альтернативным предложением и экспортировать его, а затем выгрузить его в новый репозиторий. Из любопытства и обучения я определенно хочу, чтобы это было первым, хотя. FYI - «pre-push», я имею в виду, что я запускаю его вручную, а не как git-hook. –

+0

Хм, я должен признать, что я не тестировал его, и сегодня у меня не может быть времени. Тем временем, поскольку он напечатал заявление об использовании, я бы предложил вести запись stdin, то, что вы передаете в commit-tree, и аргументы, и видеть, что что-то явно не так. – Cascabel