Как получить ветку удаленного отслеживания, чтобы быть в курсе удаленного источника в пустом Git-репозитории? - PullRequest
8 голосов
/ 15 января 2011

Я пытаюсь сохранить чистую копию Git-репозитория и у меня возникают некоторые проблемы с обновлением веток удаленного отслеживания.Я создаю ветки удаленного отслеживания следующим образом:

git branch -t 0.1 origin/0.1

Похоже, это делает то, что мне нужно сделать на тот момент времени.Тем не менее, если я внесу изменения в origin и затем извлеку их с помощью репо, все начнет разваливаться.Мой рабочий процесс выглядит следующим образом:

git fetch origin

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

git diff 0.1 refs/remotes/origin/0.1

Что мне нужно сделать, чтобы обновить ветку отслеживания с помощью обновлений пульта?Я чувствую, что, должно быть, где-то пропущен шаг или флаг.

Обновлено: дополнительное уточнение

Обычно можно было бы вставить в пустой репозиторий, а незапустите git fetch изнутри.Если вы сможете это сделать, жизнь станет намного проще.

Вот несколько пояснений по рабочему процессу.

Публичный репозиторий проекта git размещен на GitHub.Я управляю проектом (вики, вопросы, форумы) с помощью Redmine.Redmine требует локального репозитория для работы.Когда GitHub получает изменения, он пингует Redmine.Затем Redmine пытается извлечь изменения из их источника (GitHub).

Это прекрасно работает, если я просто работаю с мастером, но он не работал с моими ветвями отслеживания.Изменения были импортированы, но не были перечислены в ветви в обозревателе хранилища Redmine, потому что локальные ветви не обновлялись.

Я уверен, что мог бы решить эту проблему по-другому, но найти (универсальный)решение для установки и запуска трекинга определенно было моим предпочтением, так как большинство связанных с git плагинов для Redmine предполагают, что такие вещи, как «git fetch origin» - это все, что нужно сделать.

См. принятый ответ для полногорешение.Решение --mirror кажется именно тем, что необходимо в этом случае.

Ответы [ 2 ]

17 голосов
/ 15 января 2011

Как правило, можно вставить пустой репозиторий, а не запускать git fetch из него.Если вы сможете это сделать, жизнь станет намного проще.

Если у вас есть для извлечения, а не для толчка, и вы просто хотите создать зеркало происхождения в своем голом хранилище,Вы можете полностью избежать удаленного отслеживания ветвей.Если вы запускаете это зеркало с нуля, Charles Bailey ниже указывает, что git сделает все эти настройки за вас, если вы изначально клонируете репозиторий с git clone --mirror.

В противном случае,Вы можете получить аналогичный эффект с помощью:

git fetch origin +refs/heads/*:refs/heads/*

+ означает, что это перезапишет состояние ваших локальных веток с тех, что с удаленного.Без + обновления, которые не являются ускоренными слияниями, будут отклонены.Однако, если это просто зеркало, это не должно иметь значения.(Вы можете настроить это как действие по умолчанию на git fetch origin, установив для переменной конфигурации remote.origin.fetch значение +refs/heads/*:refs/heads/*. Если вы также хотите отразить теги и ветви удаленного отслеживания от источника, вы можете использовать +refs/*:refs/* вместо.)

Однако, если, как вы изначально просили, вы хотите поддерживать удаленные отслеживания филиалов и выборочно объединять их в локальные филиалы, вы можете использовать следующие шаги, но я не обязательно рекомендую их, если выВы единственный, кто использует этот голый репозиторий. (Примечание: изначально здесь я предложил использовать «git symbolic-ref HEAD refs /heads / what» для переключения ветки и «git reset --soft» для изменения ссылки - однако, Charles Bailey в комментариях отмечается, что можно использовать «git update-ref refs /heads / whats refs / remotes / origin / what», для которого не нужно сначала переключать ветку.)

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

  1. Вы можете проверить, что эквивалентное слияние будет ускоренным (то есть, что история origin/master включает master), сравнив git merge-base master origin/master с git show-ref master - они должны быть одинаковыми.Или вы можете использовать is-ancestor сценарий в этом вопросе , который выполняет эти команды с некоторыми дополнительными проверками.)
  2. Наконец, вы можете обновить текущую ветку (в данном случае master)) чтобы указать origin/master с помощью git update-ref refs/heads/master refs/remotes/origin/master

Однако, как я уже говорил в начале, я думаю, что реальное решение, которое вы хотите, это либо:

  • Pushingвместо этого в ваш пустой репозиторий или
  • Точное зеркальное отражение удаленного открытого репозитория, как я описал выше

Надеюсь, это пригодится.

1 голос
/ 15 января 2011

Когда вы fetch, удаленные изменения обновляют вашу собственную локальную ссылку для удаленного, origin/0.1 (это никогда не вызывает никаких конфликтов, так как origin/0.1 никогда не размещает локальные изменения).Чтобы импортировать эти изменения, вы можете git reset refs/remotes/origin/0.1 из 0.1, что заставит ветвь HEAD (0.1) указывать на тот же коммит, что и удаленная ветвь.

Обратите внимание, что при этом вы потеряетелюбые изменения 0.1 не поступают с пульта.

...