git clone не проверяет активную ветку - PullRequest
3 голосов
/ 03 августа 2011

У меня есть удаленный пустой репозиторий с двумя ветвями «master» и «testing», где HEAD обозначает «тестирование».При клонировании этого репозитория git проверяет «master», если «master» и «testing» находятся на одной и той же ревизии (то есть HEAD == testing == master).Только если 'testing' является одним (или более) коммитом (ами) позади или впереди, git clone проверяет ветку 'testing' на локальной стороне.Я попробовал это с git 1.7.5 на Mac OS X (10.6.8).

Приложение: Я только что попробовал то же самое с ненастроенным хранилищем:

mkdir A
cd A
git init
touch a
git add a
git commit -m "init repo A with a"
git checkout -b testing

, теперь снова вкорневой каталог:

cd ..
git clone A B
cd B
git branch -v -a
* master                 28f599b init A
  remotes/origin/HEAD    -> origin/master
  remotes/origin/master  28f599b init A
  remotes/origin/testing 28f599b init A

это «мастер»!Вернемся к репо А (мы все еще находимся в «тестировании» ветки):

cd ../A
touch b
git add b
git commit -m "add b in branch testing"

теперь «тестирование» - это один коммит вперед «мастер».Теперь давайте снова клонируем A:

cd ..
git clone A C
cd C
git branch -a -v
* testing                23bca39 add b in branch testing
  remotes/origin/HEAD    -> origin/testing
  remotes/origin/master  28f599b init A
  remotes/origin/testing 23bca39 add b in branch testing

Вы можете еще раз проверить это странное поведение, вернувшись к A, извлекая «master» и объединяя его с «testing» (чтобы все ветви имели одинаковую головку),Теперь клон A в D и D будет проверен на мастере!

Ответы [ 2 ]

1 голос
/ 03 августа 2011

git clone копирует все ветви и их историю, а SHA1 и не ссылки их голов. AFAIK refspecs не передаются, потому что они более новые для git, чем клонирование (очевидно), и протокол клонирования не сохраняет их ... это означает, что он угадывает (edit: это было подтверждено списком рассылки).

Ссылка на голову угадывается во время клонирования путем сопоставления его SHA1. В вашем случае SHA1 является неоднозначным, поскольку оба значения master и testing совпадают, поэтому master выбирается по соглашению. Насколько мне известно, это нигде не задокументировано, но должно быть.

Чтобы убедиться, что это так, перейдите к вашему репозиторию B example и запустите git ls-remote. Вывод даст вам SHA1s, а не refs:

1c3eebcd1bd3659a40f02880918d5fbd5614b51a    HEAD
1c3eebcd1bd3659a40f02880918d5fbd5614b51a    refs/heads/master
1c3eebcd1bd3659a40f02880918d5fbd5614b51a    refs/heads/testing

В качестве обходного пути,

git clone -b <branch_name>

клонирует и извлекает желаемую ветвь имя_в ветви, например, master или test.

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

0 голосов
/ 04 августа 2011

Получил ответ из списка рассылки git - @Shelhamer: вы правы

Да, это известная проблема.

Протокол git просто отправляет список ссылок и объектов, на которые они указывают к. Таким образом, местный клон вынужден угадывать, на какой ref указывает HEAD. Например, с чем-то вроде:

28f599b ... HEAD 1234abc ... refs / главы / мастер 28f599b ... ссылки / головы / тестирование

видно, что HEAD, вероятно, "тестирует". Но если он видит:

28f599b ... HEAD 28f599b ... ссылки / головы / мастера 28f599b ... ссылки / головы / тестирование

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

Реальным решением этой проблемы было бы расширение протокола git для передачи символьная справочная информация (а затем подождите, пока клиент и сервер не будут повышен). Некоторые патчи были выпущены в прошлом, но ничего не пришло этого Может быть, пришло время воскресить их.

В качестве обходного пути вы можете использовать «git clone -b testing ...», если знаете заблаговременно это «тестирование» - это то, что вы хотите.

См:

1. http://thread.gmane.org/gmane.comp.version-control.git/102039

2. http://article.gmane.org/gmane.comp.version-control.git/113567

...