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