git shallow clone (clone --depth) пропускает удаленные ветки

104

После клонирования удаленного репозитория он не показывает никаких удаленных веток с помощью параметра -a. В чем может быть проблема? Как это отладить? В этом фрагменте не показаны две удаленные ветки:

$ git clone --depth 1 git://git.savannah.gnu.org/pythonwebkit.git
$ cd pythonwebkit
$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
$ git --version
git version 1.8.3.1

Пробовал ту же команду на другом компьютере, работает хорошо:

$ git clone --depth 1 git://git.savannah.gnu.org/pythonwebkit.git
Receiving objects: 100% (186886/186886), 818.91 MiB | 3.44 MiB/s, done.
$ cd pythonwebkit/
$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/debian
  remotes/origin/master
  remotes/origin/python_codegen
$ git --version
git version 1.7.1

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

Любые предложения или подсказки будут более чем приветствоваться.

Изменить: Сводка ответа: Начиная с версии git 1.8.3.2, «--depth» и «--no-single-branch» необходимо использовать вместе, чтобы получить такое же поведение, как и раньше. Это считается исправлением ошибки.

Минхуа
источник
3
masterэто ваш местный филиал. remotes/origin/master- соответствующая удаленная ветка. В чем именно заключается вопрос?
michas
1
Возможно, вы забыли многословие? Попробуйтеgit branch -avv
jthill
Для michas и т. Д.: Мы обычно не называем master веткой, извините за путаницу. добавлено «не отображаются две удаленные ветки». To jthill: спасибо за напоминание, вы правы.
минхуа
1
Спасибо за представление git clone --depth=1 --no-single-branch, это то, что мне нужно в большинстве случаев.
Алиреза Мохамади,

Ответы:

62

Поведение правильное, после последней ревизии главная ветка (поскольку это HEAD первичного удаленного) является единственной удаленной веткой в ​​репозитории:

florianb$ git branch -a
        * master
          remotes/origin/HEAD -> origin/master
          remotes/origin/master

Полный клон предлагает новые (все) ветки:

florianb$ git branch -a
        * master
          remotes/origin/HEAD -> origin/master
          remotes/origin/debian
          remotes/origin/master
          remotes/origin/python_codegen

Мелкие клоны

Из-за поверхностного описания в технической документации, « git-clone --depth 20 repo[...] результат [s в] цепочках фиксации длиной не более 20». Таким образом, неглубокий клон должен содержать запрошенную глубину коммитов, начиная с конца ветки.

В дополнение к этому в документации git cloneпо --single-branchопции описывается:

"Клонировать только историю, ведущую к вершине одной ветви, либо заданной --branchпараметром, либо удаленной основной ветвью, на которую HEADуказывает. При создании неглубокого клона с этой --depthопцией это значение по умолчанию, если только --no-single-branchне задано получение историй рядом с кончики всех ветвей ".

Поэтому неглубокий клон ( с на глубине -option) только выбирает только один единственный филиал (в вашей запрошенной глубине).


К сожалению, оба варианта ( --depthи --single-branch) были ошибочными в прошлом, и использование мелких клонов влечет за собой нерешенные проблемы (как вы можете прочитать по ссылке, которую я разместил выше), что вызвано данной перезаписью истории. В целом это приводит к несколько сложному поведению в особых случаях.

Флориан Нойманн
источник
1
florianb: какая у тебя версия git? спасибо, что попробовали. Я сделал --depth 1 на 1.7.1, только сейчас он показывает все удаленные ветки. обновил вопрос этим. +1 за проверку проблемы.
Минхуа
1
@minghua: Я использую 1.8.4 - я проведу небольшое расследование, есть ли патч по этой проблеме.
Флориан Нойманн
1
@minghua: я отредактировал, чтобы отразить новые открытия о «мелководных клонах».
Флориан Нойман
1
Практически идеально, за исключением одного: что означает фраза «репо-собственник решил отрезать остальные ветви»? Я думаю, что эти ветки все еще существуют.
Минхуа
2
--no-single-branch также клонирует все теги. Мы можем избежать этого, создав новое репо, используя ту же конфигурацию для выборки всех пультов, т. Е. fetch = +refs/heads/*:refs/remotes/origin/*И запустив git fetch --depth 1(без --tags). Мы также можем добавить определенные теги для извлечения, используя config, например fetch = +refs/tags/v2.0.0:refs/tags/v2.0.0.
Сэм Уоткинс,
218

После выполнения неглубокого клона, чтобы иметь возможность проверять другие ветки удаленно ,

  1. Беги (спасибо @jthill):

    git remote set-branches origin '*'
    
  2. После этого сделайте git fetch -v

  3. в заключение git checkout the-branch-i-ve-been-looking-for


Шаг 1 также можно выполнить вручную путем редактирования .git/config.

Например, измените следующую строку с:

fetch = +refs/heads/master:refs/remotes/origin/master

на (заменить masterна *):

fetch = +refs/heads/*:refs/remotes/origin/*
Марло
источник
59
Вы также можете использовать git remote set-branches origin '*'для всех веток, заменив *для одной ветки.
jth
Спасибо! Это спасло мне день.
Стивен Сюй,
Что -vvvзначит в git fetch -vvv? Я не нашел никакой информации об этом в git-fetch doc
guo
@guo - это уровень регистрации verbosityили . Это не из метода. debuggitfetch
marlo
1
@ kawing-chiu, это полезно, если у вас так много веток, а размер слишком велик для «подключения к Интернету» раньше, и теперь вы можете позволить себе получить все эти ветки. :)
marlo
67

Прочитав ответы и комментарий от @jthill, мне лучше всего сработало использование set-branchesпараметра в git remoteкоманде:

$ git clone --depth 1 https://github.com/dogescript/dogescript.git
$ git remote set-branches origin 'remote_branch_name'
$ git fetch --depth 1 origin remote_branch_name
$ git checkout remote_branch_name

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

алехандроднм
источник
18
Возможно, было бы лучше использовать git remote set-branches --add origin 'remote_branch_name'новую ветку в дополнение к существующим, а не заменять их в удаленном списке ветвей (или шаблонах ветвей) для извлечения в файле .git / config.
Дамблдад
2
OMG, одинарная цитата 'важнаgit remote set-branches --add origin 'remote_branch_name'
выходные,
@Weekend Я не мог заставить это работать, пока я не
отказался
@PandaWood Вы, вероятно, используете Windows. Знак «$» в ответе означает Bash (в Unix или Cygwin / MSYS).
Юнвэй У
Я не вижу необходимости в одинарных кавычках в документации, и, по крайней мере, на macOS все работает нормально без кавычек .
Николай