Как получить полную копию репо с помощью git - PullRequest
0 голосов
/ 27 октября 2019

Я клонировал удаленное репо и хочу иметь собственную копию на локальном git-сервере.

Итак, я сделал:

git clone ssh...

Я создал новое репо на своем сервере

git init --bare

Я добавил новый сервер

git remote add bm ssh...

Чем я нажал на новый пульт

git push --mirror bm

Теперь я могу видеть на моем голом сервере репо:

[gitmini@blaumeise simulavr]$ git branch -a
* master
  remotes/bm/master
  remotes/savannah/HEAD
  remotes/savannah/devel-tomk
  remotes/savannah/master
  remotes/savannah/oldstable
  remotes/savannah/python_3
  remotes/savannah/rel-1.0
  remotes/savannah/rel-1.1
  remotes/savannah/sbi_cbi_rework

Выглядит хорошо, я думаю.

Но теперь я выписался с моего локального сервера

  git clone ssh...

и получаю только:

  git branch -a

[krud@blaumeise simulavr]$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

Iуже сделал: git fetch --all и git pull --all, ничего не изменилось.

Что-то не так с моим собственным репозиторием сервера или что-то не так во время клонирования? Что я могу сделать в такой плохой ситуации.

Я уже прочитал: Как получить все ветки Git

Ответы [ 2 ]

2 голосов
/ 27 октября 2019

git clone по умолчанию копирует только (локальные) ветви и теги другого Git. Вы можете получить дополнительные ссылки, включая имена для удаленного отслеживания, такие как remotes/savannah/oldstable. Но обычно это не очень хорошая идея. Вместо этого, в вашем пустом хранилище, сделайте оно с ответвлениями с этими именами.

Сначала все это немного сложно, но в конце концов все начинаетсясмысл. Эти имена возникают из-за использования двух отдельных репозиториев Git. Каждый репозиторий Git имеет свои имена ветвей, поэтому:

  • A имя ветви - это ссылка, полное имя которой начинается с refs/heads/. Таким образом, refs/heads/master представляет ветвь master и т. Д.

  • A имя удаленного отслеживания - это ссылка, полное имя которой начинается с refs/remotes/. Следующая часть полного имени совпадает с именем remote , и после этого (и еще один слеш) вы получаете имя ветки , взятое из другого Git.

Это обычный шаблон использования для обычных клонов. Существует какой-то существующий репозиторий, который кто-то (или многие кто-то) настроил где-то в сети (например, на GitHub), и у него есть несколько веток: master, develop, feature/A, feature/B и тд. Вы клонируете этот репозиторий на свою собственную машину (ноутбук или что-то еще) и хотели бы, чтобы ваш Git запомнил для вас их веток, но не создал связку (локальных) веток. Теперь вы, возможно, решите выполнить какую-то работу, которую вы хотите отправить им позже, как часть feature/A, поэтому вы создаете ваше имя feature/A, для которого нужно делать новые коммиты для отправкиих и рекомендую поместить их в их feature/A. Вы вообще не работаете с feature/B, поэтому вы не получаете feature/B и не используете master, поэтому вы можете удалить свой собственный master.

. делать иметь несколько новых коммитов, вы будете использовать:

git push origin feature/A

, чтобы отправлять ваши новые коммиты на их Git, и сразу же - как часть git push - спросите у их Git для установки их feature/A ветви для запоминания этих новых коммитов.

Это не то, что вам нужно здесь

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

git clone --mirror <url> [<path>]

Теперь у вас есть на вашем ноутбукеголый клон (--mirror подразумевает --bare) с именами no origin/* для удаленного слежения. Вместо этого Git создал в вашей копии своего репозитория обычные старые имена веток, а не имена для удаленного отслеживания, соответствующие их именам ветвей. Таким образом, у вас есть таких же дюжин названий ветвей, которые у них есть.

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

Теперь, когда у вас есть клон, имеющий все ветви, сейчас вы можете создать пустой репозиторий на сервере (или на GitHub). Теперь вы можете запустить:

git push --all <url-of-server-repository>

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

(Если вы сделали git push из локального репозиторияэто уже все готово, вы не хотите или не должны удалять локальный клон, и вы можете использовать git remote add перед git push. См. ниже.)

Вышеэто несколько расточительно!

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

Вам не нужно делать зеркальный клон . Это только для удобства.

Вместо этого вы можете:

  • сделать обычный клон
  • создать локальные ветви, необходимые для представления всехимена для удаленного отслеживания
  • используйте git push --all, чтобы отправить их все на сервер
  • удалить все локальные имена, которые вы сделали (но оставьте все, что у вас не было

Или вместо вышеперечисленного вы можете:

  • сделать (или иметь) обычный клон
  • использовать git pushбез --all: вместо этого используйте refspecs , чтобы переместить имена удаленного отслеживания на своем конце в имена ветвей на их конце.

Этот последний метод в некотором роде самый лучший, но требует понимания refspecs.

refspec - это, во второй простейшей форме, пара ссылок - полные имена, такие как refs/heads/master или refs/remotes/feature/A - разделены двоеточием :. Имя слева от двоеточия - source , а имя справа - destination . Refspecs ведут себя одинаково, хотя и не одинаково, как в git fetch, так и git push: ссылка source предоставляет хэш коммита в отправляющем Git, а ссылка назначения предоставляет name дляустановить в получение Git. Так как git push отправляет из ваш Git-репозиторий в их Git-репозиторий, вы можете использовать свои имена для удаленного слежения слева, а имена их ветвей справа:

# after creating an empty repository on github
git remote add origin <url-on-github>
git push origin master   # send your refs/heads/master to theirs
git push origin refs/remotes/savannah/devel-tomk:refs/heads/devel-tomk
git push origin refs/remotes/savannah/python_3:refs/heads/python_3

(при условии, что вы хотите, чтобы ваше удаленное отслеживание savannah/devel-tomk стало их ветвью devel-tomk и т. Д.).

Вы можете поместить все refspecs в одну большую строку git push, носмехотворно легко напечатать ее, что раздражает: например,

git push origin master refs/remotes/savannah/devel-tomk:refs/heads/devel-tomk refs/remotes/savannah/python_3:refs/heads/python_3

, если я ничего не опечатывал.

0 голосов
/ 27 октября 2019

Вы не создали копию всего репо. Вы только создали репо с мастер-веткой.

По умолчанию push-уведомление толкает только одну ветку. Попробуйте добавить флаг --all

git push --mirror --all bm
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...