Przekaż lokalne repozytorium Git na nowy pilot, w tym wszystkie gałęzie i tagi


551

Mam lokalne repozytorium Git, które chciałbym przekazać do nowego zdalnego repozytorium (zupełnie nowe repozytorium skonfigurowane na Beanstalk, jeśli to ma znaczenie).
Moje lokalne repozytorium ma kilka gałęzi i tagów i chciałbym zachować całą moją historię.

Wygląda na to, że po prostu muszę to zrobić git push , ale to tylko przesyła mastergałąź.

Jak wypchnąć wszystko, aby uzyskać pełną replikę mojego lokalnego repozytorium na pilocie?


Najkrótsza i najłatwiejsza odpowiedź - stackoverflow.com/a/39992258/6648326 .
MasterJoe2

Odpowiedzi:


898

Aby wypchnąć wszystkie gałęzie , użyj jednego z nich (zamień REMOTE na nazwę pilota, na przykład „origin”):

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

Aby wypchnąć wszystkie tagi :

git push REMOTE --tags

Wreszcie myślę, że możesz to wszystko zrobić za pomocą jednego polecenia za pomocą:

git push REMOTE --mirror

Jednak dodatkowo --mirrorpopchnie również piloty, więc może nie być to dokładnie to, czego chcesz.


53
--allzamiast *:*wydaje się bardziej przyjazny
Idan K

56
mój Boże ............. Zerwałem cały internet i dowiedziałem się, że przełącznik `--allall 'to AAAAALLLLLLLLLLLLL Potrzebowałem!
Rakib

21
Po prostu zauważam, że git push REMOTE --allpowrócił, No refs in common and none specified;nie robiąc nic., Podczas gdy w git push REMOTE "*:*rzeczywistości zepchnął wszystkie gałęzie na odległość.
Im0rtality

10
Użyj --dry-run, aby sprawdzić, co się stanie, na wypadek, gdybyś miał lokalnie gałęzie „tmp” lub „feature”, których tak naprawdę nie chcesz aktualizować ZDALNIE
Jonno

55
Jeśli oryginalny pilot jest nadal dostępny, warto to zrobić git clone --mirror old-remote-url; cd repo.git; git push --mirror new-remote-url.
Suzanne Dupéron

156

W przypadku takim jak ja, że ​​nabyłeś repozytorium i teraz przełączasz zdalne pochodzenie na inne repo, nowe puste ...

Masz więc repozytorium i wszystkie gałęzie w środku, ale nadal musisz sprawdzić te gałęzie, aby git push --allpolecenie również je wypchnęło.

Powinieneś to zrobić przed pchnięciem:

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

Śledzony przez

git push --all

4
Jest to również bardzo pomocne, ponieważ musiałem ręcznie sprawdzić wszystkie gałęzie. To będzie dobre na następny raz.
Cory Imdieke

10
O dziwo git push '*:*'pchnął wszystkie gałęzie. git push -allwłaśnie popchnął mistrza. Transportowałem repozytorium z github do bitbucket.
jerrymouse

3
Zamiast sprawdzać każdą gałąź, powinieneś po prostu zrobić „git branch --track $ remote”. W dużych repozytoriach sprawdzanie starej gałęzi zajmuje czasem
Moataz Elmasry

2
Musiałem dokonać niewielkiej zmiany, aby to zadziałało: --track remotes/$remotezamiast --track $remote. Oto pełna linia poleceń:for remote in `git branch -r | grep -v master `; do git checkout --track remotes/$remote ; done
Adrian T

Dzięki, to działa dla mnie, powyższa odpowiedź również nie działa.
Benyamin Jafari

90

Oto kolejne spojrzenie na to samo, które działało lepiej w sytuacji, w której byłem. Rozwiązuje problem, w którym masz więcej niż jednego pilota, chciałbyś sklonować wszystkie gałęzie z pilota sourcedo pilotadestination ale bez konieczności wcześniejszego sprawdzania ich wszystkich.

(Problem, który miałem z rozwiązaniem Daniela, polegał na tym, że odmówiłby wyewidencjonowania oddziału śledzenia ze sourcezdalnego, jeśli już go wcześniej sprawdziłem, tj. Nie zaktualizowałby mojego lokalnego oddziału przed wypchnięciem)

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

Uwaga: Jeśli nie używasz bezpośredniego interfejsu CLI, musisz uciec od gwiazdek:

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

spowoduje to popchnięcie wszystkich gałęzi na odległość sourcedo gałęzi głównej destination, prawdopodobnie wykonując push nie do przodu. Nadal musisz przesuwać tagi osobno.


8
+1 To działało dla mnie, klonując od jednego remotedo drugiego. Dzięki!
Laurence

4
Musiałem uciec od gwiazdek:git push destination +refs/remotes/source/\*:refs/heads/\*
mattalxndr

2
Dla mnie to skończyło się pchaniem gałęzi o nazwie HEAD, co nie wydaje mi się celowe w tym scenariuszu.
maxwellb

1
Ta odpowiedź była dla mnie niezwykle przydatna. Jedyną wzmianką na stronie podręcznika git-push (1) o tym użyciu gwiazdek jest mały przykład tej --pruneopcji.
laindir

4
Doskonała odpowiedź, zupełnie inna niż zwykły --mirrorparametr, który wszyscy zalecają. Działa idealnie w scenariuszach, w których chcesz synchronizować dwa piloty do celów automatyzacji lub kontroli.
Winicjusz Ksawery

15

To najbardziej zwięzły sposób, jaki znalazłem, pod warunkiem, że miejsce docelowe jest puste. Przejdź do pustego folderu, a następnie:

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

W razie https://...potrzeby zamień na file:///your/repoitp.


13

Strona man git-pushjest warta przeczytania. W połączeniu z tą witryną napisałem w moim .git/config:

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

Te push = :środki „push żadnych oddziałów«dopasowywania»(tj gałęzie, które już istnieją w zdalnym repozytorium i mieć lokalny odpowiednik)”, natomiastpush = refs/tags/* środki „push wszystkie znaczniki”.

Więc teraz muszę tylko uruchomić, git pushaby wypchnąć wszystkie pasujące gałęzie i wszystkie tagi.

Tak, nie jest to dokładnie to, czego chciał OP (wszystkie odgałęzienia do wypychania muszą już istnieć po drugiej stronie), ale mogą być pomocne dla tych, którzy znajdą to pytanie podczas szukania w Google „jak wypychać gałęzie i znaczniki jednocześnie czas".


13

W moim przypadku zadziałało.

git push origin --all

4
Proste i łatwe. To działa! originjest aliasem zdalnego repozytorium Git adresu URL.
Do Nhu Vy

8

Kopia lustrzana repozytorium

Utwórz czysty klon repozytorium.

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

Odbicie lustrzane do nowego repozytorium.

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

Usuń tymczasowe lokalne repozytorium utworzone w kroku 1.

cd ..
rm -rf old-repository.git

Odbicie lustrzane repozytorium zawierającego obiekty Git Large File Storage

Utwórz czysty klon repozytorium. Zastąp przykładową nazwę użytkownika nazwą osoby lub organizacji, która jest właścicielem repozytorium, i zastąp przykładową nazwę repozytorium nazwą repozytorium, które chcesz powielić.

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

Przejdź do sklonowanego właśnie repozytorium.

cd old-repository.git

Pobierz obiekty Git Large File Storage repozytorium.

git lfs fetch --all

Odbicie lustrzane do nowego repozytorium.

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

Wepchnij obiekty Git Large File Storage repozytorium do swojego lustra.

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

Usuń tymczasowe lokalne repozytorium utworzone w kroku 1.

cd ..
rm -rf old-repository.git

Powyższa instrukcja pochodzi z Pomocy Github: https://help.github.com/articles/duplicating-a-repository/


1
Chociaż teoretycznie może to odpowiedzieć na pytanie, lepiej byłoby zawrzeć tutaj istotne części odpowiedzi i podać odnośnik. Zobacz tutaj , aby uzyskać instrukcje jak pisać lepsze „Link” na bazie odpowiedzi. Dzięki!
GhostCat,

5

Znalazłem powyższe odpowiedzi wciąż zawierają pewne niejasne rzeczy, które wprowadzą użytkowników w błąd. Po pierwsze, to pewne git push new_origin --alligit push new_origin --mirror nie może powielić wszystkich gałęzi pochodzenia, po prostu powielił istniejące gałęzie lokalne do nowego_orygina.

Poniżej znajdują się dwie przydatne metody, które przetestowałem:

1, zduplikowane przez klon nagie repo. git clone --bare origin_url, a następnie wejdź do folderu i. git push new_origin_url --mirrorW ten sposób możesz również korzystać z git clone --mirror origin_urlobu tych funkcji --barei --mirrorpobierać nagie repozytorium, nie uwzględniając obszaru roboczego. proszę odnieść się do tego

2, jeśli masz repozytorium git za pomocą git clone, co oznacza, że ​​masz nagie repozytorium i git obszar roboczy, możesz użyć git remote add new_origin new_origin_url, a następnie git push new_origin +refs/remotes/origin/\*:refs/heads/\*, a następniegit push new_origin --tags

W ten sposób otrzymasz dodatkową gałąź głowy, co nie ma sensu.


2

Aby wypychać gałęzie i tagi (ale nie piloty):

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

Byłoby to równoznaczne z łączeniem opcji --tagsi --alldla git push, na które git nie pozwala.


Czy istnieje dodatkowa opcja wypychania z innego pilota? Na przykład z+refs/remotes/source/*
Yves Martin

2

Na podstawie odpowiedzi @Daniel zrobiłem:

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

2
Co więcej, | grep -v mastermożna go zastąpić | sed 's/\*//'(Zakładam, że zostałeś wykluczony, masteraby uniknąć nieprzyjemnych *rzeczy, które są dołączone do aktualnie wybranej gałęzi), co pozwala ci uwzględnić masteri uniknąć problemów, gdy masternie jest to aktualnie wybrana gałąź. Przepraszam również za nekropostę, po prostu ta odpowiedź pomogła mi dzisiaj i chciałem podzielić się moją modyfikacją, jeśli może pomóc innym na moim stanowisku ...
ToVine

1

Odkryłem, że żadne z nich nie działało poprawnie dla mnie. Zapraszam do wypalenia tego na śmierć, ale z jakiegoś powodu inne opcje nie mogły działać poprawnie.

Oczekiwanym rezultatem było „sklonowanie” repozytorium do innego pilota (tj. Z Github do innego dostawcy):

  • Wszystkie gałęzie są tworzone na nowym pilocie
  • Cała historia oddziału jest tworzona na nowym pilocie
    • (tego brakowało przy każdym wypróbowanym przeze mnie rozwiązaniu)
  • Wszystkie tagi są tworzone na nowym pilocie
  • Przesuwa się źródło (dane)
  • Nieniszczące (wstrzymywanie opcji --mirror)

Głównym problemem, który widziałem, było to, że wszystkie odległe gałęzie nie zostały odtworzone w nowym pilocie. Jeśli polecenie tak, nowy pilot nie ma historii rozgałęzienia (tzn. Wykonuje poleceniegit checkout branch; git log nie pokazywałoby oczekiwanych zatwierdzeń gałęzi).

Zauważyłem, że git checkout -b branchnameNIE jest to samo co git checkout branchname(to drugie jest tym, czego potrzebowałem). Zauważyłemgit checkout --track branchname że nie zmieniłem historii oddziału.

Moje rozwiązanie (oparte na 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

Poniższe polecenie popchnie wszystkie gałęzie (w tym te, których nigdy nie wymeldowałeś, ale są obecne w repozytorium git, możesz je zobaczyć wedługgit branch -a )

git push origin '*:*'

UWAGA: To polecenie jest przydatne podczas migracji usługi kontroli wersji ( tj. Migracji z Gitlab do GitHub )


1
Migracja między usługami kontroli wersji i właśnie tego szukam, na zdrowie!
Luka Špoljarić

1

Byłem w trakcie przechodzenia z jednej usługi kontroli wersji do drugiej i musiałem sklonować wszystkie repozytoria, w tym wszystkie gałęzie, tagi i historię.

Aby osiągnąć powyższe, zrobiłem następnie:

  • ręcznie kasuj wszystkie oddziały do ​​lokalnego repozytorium (skrypt kasujący wszystkie pokazane poniżej),
  • git push origin '*:*'

Skrypt .sh służący do pobrania wszystkich gałęzi do lokalnego repozytorium:

for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
   git branch --track ${branch#remotes/origin/} $branch
done
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.