Git: безопасное создание репозиториев

Я мог бы воспользоваться некоторыми рекомендациями экспертов по git относительно того, как сделать операции push в безопасных репозиториях. В основном у меня есть план о том, как это сделать, и я мог бы воспользоваться некоторыми советами о том, является ли план вменяемым или нет:)

Обычно, когда вы перемещаетесь в не-пустой репозиторий в git, его рабочая копия и индекс не обновляются. Как я обнаружил, это может вызвать серьезные проблемы, если вы забудете позже обновить их вручную!

В нашей группе у нас есть несколько "центральных" репозиториев, к которым люди клонируют и возвращают, но многие люди также хотят иметь возможность создавать клоны своих клонов и толкать / тянуть между ними по мере необходимости в истинно распределенном режиме. Чтобы сделать это безопасным, я хочу убедиться, что каждый репозиторий, созданный с помощью "clone" или "init", имеет автоматически установленный хук post-receive, который обновит рабочий каталог и индекс после операции push для синхронизации с Новая ГОЛОВА.

Я обнаружил, что могу сделать это, создав каталог шаблонов с моим хуком post-receive в подкаталоге hooks, а затем заставив всех в моей группе сделать:

git config --global init.templatedir /path/to/template/dir

В настоящее время мой хук после получения выглядит так:

export GIT_WORK_TREE=..
git checkout -f HEAD

Это выглядит, как работать, как хотелось бы, но у меня есть некоторая неопределенность в отношении команды извлечения. Для целей синхронизации рабочего каталога и индекса с состоянием в HEAD эквивалентны "git checkout -f HEAD" и "git reset --hard HEAD"?

Я спрашиваю, потому что, хотя я знаю, что "git reset --hard HEAD" будет делать то, что я хочу, использование его в хуке post-receive значительно замедляет операции push в моем тестировании (кажется, делает новую проверку всех файлов, независимо от того, является ли файл грязным или чистым в рабочем каталоге). "git checkout -f HEAD" ВИДЕТЬ, чтобы сделать ту же самую вещь намного быстрее (получите мне чистый рабочий каталог и индекс, синхронизированный с HEAD), но я немного нервничаю, учитывая склонность команды checkout делать на лету сливается с незафиксированными изменениями рабочего каталога. Даст ли мне эта команда действительно рабочий каталог и индекс, которые точно соответствуют состоянию в HEAD во всех случаях (включая, например, удаление файлов, переименования и т. Д.)?

Спасибо заранее за любые советы!

2 ответа

Решение

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

У большинства людей есть свой обычный рабочий каталог, который является частным, и сделать его клон в публичном репо на том же диске, и поделиться им. При этом используются жесткие ссылки, поэтому вы едва используете дополнительное пространство. Вы помещаете свои изменения в общедоступное репо вашего коллеги, и он делает запрос в свой рабочий каталог, когда он готов принять изменения. С другой стороны, вы вносите свои изменения в ваше публичное репо, и ваш коллега вытаскивает их оттуда, когда он будет готов. Есть причина, почему трудно установить репозитории, не являющиеся открытыми.

Я предлагаю использовать post-update ловушка, указанная в записи Git FAQ " Почему я не вижу изменений в удаленном репо после"git push"? ".

Он сохранит поэтапные и неустановленные изменения (в отслеживаемых файлах) перед выполнением аппаратного сброса. Это безопаснее, чем обычная полная перезагрузка, но, как говорится в записи часто задаваемых вопросов, она все еще не охватывает все ситуации, которые могут возникнуть (например, индекс с существующим конфликтом не может быть сохранен; он не выполняет автоматическое объединение изменений на неизмененные файлы, такие как git checkout делает и т. д.).


Тем не мение, …
если вообще возможно, …
вам, вероятно, следует просто избегать нажатия на любую проверенную ветку в первую очередь.

Пересылка в не-пустой репозиторий - это нормально, если вы не продвигаетесь в извлеченную ветвь (в конце концов, задействованная переменная конфигурации receive.denyCurrentBranch не receive.denyNonBare ").

Последний абзац вышеупомянутой записи FAQ содержит ссылку (как в комментарии ниже, о которой упоминает Марк Лонгэйр) на другую запись, в которой описывается подход к отправке в не-пустое хранилище. Мотивация для входа - асимметричное сетевое соединение между двумя непокрытыми репозиториями, но этот метод может быть применен к любой ситуации, когда вам нужно / нужно перейти в непустой репозиторий.

В этой последней записи часто задаваемых вопросов приведен пример перехода на ветку удаленного отслеживания (в разделе refs/remotes/). Только ссылки под refs/heads/ можно проверить, не снимая ГОЛОВКУ (без использования git symoblic-ref), поэтому подталкиваю к чему-либо снаружи refs/heads/ должен быть безопасным, чтобы избежать "подталкивания к проверенной ветке".

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

Когда вам нужно отправить коммиты в не-голый репозиторий другого, отправьте их в refs/remotes/from/<your-username>/<branch>, Чтобы избежать конфликтов с обычными ветвями удаленного слежения, никто не должен определять пульт с именем from, Разветвленные ветви, как это будет отображаться в git branch -a (или же -r) и, соответственно, можно ссылаться без refs/remotes/ префикс. Тем не менее from псевдо-пульт не будет отображаться в git remote потому что нет remote.from.url переменная конфигурации.

Пример:

alice$ remote add betty bettys-machine:path/to/some/non-bare/repository
alice$ git push betty master:refs/remotes/from/alice/bug/123/master

betty$ git log --reverse -p origin/master..from/alice/bug/123/master
Другие вопросы по тегам