Передача локального репозитория Git на новый пульт, включая все ветви и теги


551

У меня есть локальное Git-репо, которое я хотел бы перенести в новое удаленное репо (новое репо, настроенное на Beanstalk, если это имеет значение).
В моем локальном репо есть несколько веток и тегов, и я бы хотел сохранить всю свою историю.

Похоже, мне просто нужно сделать git push, но это только загружает masterветку.

Как мне все подтолкнуть, чтобы я получил полную копию моего локального репо на пульте?


Самый короткий и простой ответ - stackoverflow.com/a/39992258/6648326 .
MasterJoe2

Ответы:


898

Чтобы протолкнуть все ваши ветви , используйте любую (замените REMOTE на имя пульта, например «origin»):

git push REMOTE '*:*'
git push REMOTE --all

Чтобы вставить все ваши теги :

git push REMOTE --tags

Наконец, я думаю, что вы можете сделать все это одной командой:

git push REMOTE --mirror

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


53
--allвместо того, чтобы *:*казаться более дружелюбным
Идан К

56
Боже мой ............. я порвал весь интернет и обнаружил, что ключ "--all" - это AAAAALLLLLLLLLLLLLL Мне нужно!
Ракиб

21
Просто отметив, что git push REMOTE --allвернул No refs in common and none specified;ничего не делая., В то время как на git push REMOTE "*:*самом деле подтолкнул все ветви к удаленному.
Бессмертие

10
Используйте --dry-run для проверки того, что произойдет, если у вас есть локальные ветки "tmp" или "feature", которые вы не хотите обновлять в REMOTE
Jonno

55
Если оригинальный пульт все еще доступен, это хорошая идея git clone --mirror old-remote-url; cd repo.git; git push --mirror new-remote-url.
Сюзанна Дюперон

157

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

Итак, у вас есть репо и все ветки внутри, но вам все равно нужно проверить эти ветки, чтобы git push --allкоманда тоже подтолкнула их.

Вы должны сделать это, прежде чем нажать:

for remote in `git branch -r | grep -v master `; do git checkout --track $remote ; done

С последующим

git push --all

4
Это также очень полезно, так как мне пришлось оформить все ветки вручную. Это будет хорошо в следующий раз.
Кори Имдике

10
Странно, git push '*:*'подтолкнули все ветки. git push -allпросто толкнул мастера. Я перевозил репо из GitHub в Bitbucket.
Jerrymouse

3
Вместо того, чтобы проверять каждую ветку, вы должны просто сделать «git branch --track $ remote». В огромных репозиториях проверка старой ветки занимает
какое-

2
Я должен был сделать небольшое изменение, чтобы это работало: --track remotes/$remoteвместо --track $remote. Вот полная командная строка:for remote in `git branch -r | grep -v master `; do git checkout --track remotes/$remote ; done
Адриан Т

Спасибо, это работает для меня, приведенный выше ответ также не работает.
Беньямин Джафари

90

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

(Проблема, с которой я столкнулся при решении Даниэля, состояла в том, что он отказывался бы извлекать ветку отслеживания с sourceудаленного компьютера, если я уже проверил ее ранее, то есть она не будет обновлять мою локальную ветвь до отправки)

git push destination +refs/remotes/source/*:refs/heads/*

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

git push destination +refs/remotes/source/\*:refs/heads/\*

это подтолкнет все ветви в удаленном направлении sourceк головному ответвлению destination, возможно, выполняя ускоренную перемотку вперед. Вы все еще должны нажимать метки отдельно.


8
+1 Это сработало для меня, клонирование от одного remoteк другому. Спасибо!
Лоуренс

4
Я должен был избежать звездочек:git push destination +refs/remotes/source/\*:refs/heads/\*
mattalxndr

2
Для меня это привело к появлению ветки под названием HEAD, которую я не считаю намеренной в этом сценарии.
maxwellb

1
Этот ответ был невероятно полезным для меня. Единственное упоминание в справочной странице git-push (1) об использовании звездочек в крошечном примере для этой --pruneопции.
laindir

4
Отличный ответ, значительно отличающийся от обычного --mirrorпараметра, который все рекомендуют. Идеально подходит для сценариев, где вы просто хотите синхронизировать два пульта дистанционного управления для целей автоматизации или аудита.
Виниций Ксавьер

15

Это самый краткий способ, который я нашел, при условии, что пункт назначения пуст. Переключитесь на пустую папку и затем:

# Note the period for cwd >>>>>>>>>>>>>>>>>>>>>>>> v
git clone --bare https://your-source-repo/repo.git .
git push --mirror https://your-destination-repo/repo.git

Подставим https://...для file:///your/repoт.д. в зависимости от обстоятельств.


13

Руководство git-pushстоит прочитать. В сочетании с этим сайтом я написал следующее в моем .git/config:

[remote "origin"]
    url = …
    fetch = …
    push = :
    push = refs/tags/*

Это push = :означает «проталкивать любые« совпадающие »ветви (т. Е. Ветви, которые уже существуют в удаленном репозитории и имеют локальный аналог), а push = refs/tags/*означает« проталкивать все теги ».

Так что теперь мне нужно только запустить git pushвсе соответствующие ветви и все теги.

Да, это не совсем то, что хотел OP (все ветви, которые нужно нажать, должны уже существовать на удаленной стороне), но может быть полезно для тех, кто находит этот вопрос во время поиска в Google «Как я нажимаю ветви и теги одновременно? время".


13

В моем случае, что сработало.

git push origin --all

4
Просто и легко. Оно работает! originпсевдоним удаленного URL Git-репозитория.
До Нху Вы

8

Зеркальное отображение хранилища

Создайте голый клон репозитория.

git clone --bare https://github.com/exampleuser/old-repository.git

Зеркало-толчок в новый репозиторий.

cd old-repository.git
git push --mirror https://github.com/exampleuser/new-repository.git

Удалите временный локальный репозиторий, созданный на шаге 1.

cd ..
rm -rf old-repository.git

Зеркалирование репозитория, содержащего объекты Git Large File Storage

Создайте голый клон репозитория. Замените пример имени пользователя на имя человека или организации, которая владеет репозиторием, и замените пример репозитория именем репозитория, который вы хотите дублировать.

git clone --bare https://github.com/exampleuser/old-repository.git

Перейдите в репозиторий, который вы только что клонировали.

cd old-repository.git

Вытащите объекты хранилища Git Large File Storage.

git lfs fetch --all

Зеркало-толчок в новый репозиторий.

git push --mirror https://github.com/exampleuser/new-repository.git

Поместите объекты хранилища Git Large File Storage в свое зеркало.

git lfs push --all https://github.com/exampleuser/new-repository.git

Удалите временный локальный репозиторий, созданный на шаге 1.

cd ..
rm -rf old-repository.git

Приведенная выше инструкция взята из справки Github: https://help.github.com/articles/duplicating-a-repository/


1
Хотя это может теоретически ответить на вопрос, было бы предпочтительным включить сюда основные части ответа и предоставить ссылку для справки. Смотрите здесь инструкции, как писать лучшие ответы на основе ссылок. Спасибо!
GhostCat

5

Я нашел выше ответы все еще есть некоторые неясные вещи, которые могут ввести пользователей в заблуждение. Во-первых, уверен, что git push new_origin --allиgit push new_origin --mirror не может дублировать все ветви происхождения, это просто дублировать ваши местные существовавшие ветви к вашему new_origin.

Ниже приведены два полезных метода, которые я протестировал:

1, дублировать клоном голого репо. git clone --bare origin_url, затем войдите в папку, и git push new_origin_url --mirror. Таким образом, вы также можете использовать git clone --mirror origin_urlоба, --bareи --mirrorзагрузит голое хранилище, не включая рабочее пространство. пожалуйста, отошлите это

2, если у вас есть git-репо с помощью git clone, что означает, что у вас есть голое репо и git-рабочее пространство, вы можете использовать git remote add new_origin new_origin_url, а затем git push new_origin +refs/remotes/origin/\*:refs/heads/\*, а затемgit push new_origin --tags

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


2

Чтобы подтолкнуть ветви и теги (но не удаленные):

git push origin 'refs/tags/*' 'refs/heads/*'

Это было бы эквивалентно объединению параметров --tagsи --allдля git push, которые, по-видимому, git не позволяет.


Есть ли дополнительная опция для нажатия с другого пульта? Например с+refs/remotes/source/*
Ив Мартин

2

На основании ответа @Daniel я сделал:

for remote in \`git branch | grep -v master\`
do 
    git push -u origin $remote
done

2
Более того, | grep -v masterможет быть заменено на | sed 's/\*//'(я полагаю, что вы исключили, masterчтобы избежать неприятных *мелочей, добавленных к текущей выбранной ветви), что позволяет вам включать masterи избегать любых проблем, когда masterваша текущая ветка не выбрана. Также извините за некропостинг, просто этот ответ помог мне сегодня, и я хотел поделиться своей модификацией, если она может помочь другим в моем положении ...
ToVine

1

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

Ожидаемый результат - репо, «клонированный» на другой пульт (т. Е. С Github на другого провайдера):

  • Все филиалы созданы на новом пульте
  • Вся ветка истории создается на новом пульте
    • (это было пропущено при каждом решении, которое я пробовал)
  • Все теги созданы на новом пульте
  • Источник движется (дано)
  • Неразрушающий (пауза в опции --mirror)

Основная проблема, с которой я столкнулся, заключалась в том, что все удаленные ветви не воссоздались в новом пульте. Если команда сделала, у нового удаленного не было истории ветвления (т.е.git checkout branch; git log Выполнение не показывало ожидаемые коммиты ветвления).

Я заметил, что git checkout -b branchnameэто не то же самое, что git checkout branchname(последнее, что мне было нужно). Я заметил, git checkout --track branchnameчто, кажется, не тянет ветку истории.

Мое решение (основанное на powershell):

Function Git-FetchRemoteBranches {
$originalbranch = (git symbolic-ref HEAD).split("/")[-1]

Foreach ($entry in (git branch -r)) {

If ($entry -like "*->*") {
  $branch = $entry.split("->")[2].split("/")[1]
}
  else {$branch = $entry.split("/")[1]}

Write-Host "--Trying git checkout " -NoNewline
Write-Host "$branch" -Foreground Yellow

git checkout $branch

Remove-Variable branch -Force

""}

#Switch back to original branch, if needed
If ( ((git symbolic-ref HEAD).split("/")[-1]) -ne $originalbranch) {
"Switching back to original branch"
git checkout $originalbranch
Remove-Variable originalbranch -Force
}
}

git clone http://remoterepo
cd remoterepo
Git-FetchRemoteBranches
git remote add newremote
git push newremote --all
git push newremote --tags #Not sure if neeeded, but added for good measure

1

Команда ниже будет выдвигать все ветви ( включая те, которые вы никогда не проверяли, но присутствовали в вашем git-репо, вы можете просмотреть ихgit branch -a )

git push origin '*:*'

ПРИМЕЧАНИЕ. Эта команда удобна при переносе службы контроля версий ( т.е. при переходе с Gitlab на GitHub ).


1
Миграция между службами контроля версий и это именно то, что я ищу, ура!
Лука Шполярич

1

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

Чтобы достичь выше, я сделал следующее:

  • вручную извлекать все ветки в локальный репозиторий (скрипт для проверки всех показанных ниже),
  • git push origin '*:*'

Скрипт .sh используется для извлечения всех веток в локальный репозиторий:

for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
   git branch --track ${branch#remotes/origin/} $branch
done
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.