Đẩy repo Git cục bộ sang điều khiển từ xa mới bao gồm tất cả các nhánh và thẻ


551

Tôi có một repo Git địa phương mà tôi muốn chuyển sang một repo từ xa mới (repo hoàn toàn mới được thiết lập trên Beanstalk, nếu điều đó quan trọng).
Repo địa phương của tôi có một vài chi nhánh và thẻ, và tôi muốn giữ lại tất cả lịch sử của mình.

Có vẻ như tôi về cơ bản chỉ cần làm một git push, nhưng điều đó chỉ tải lên masterchi nhánh.

Làm cách nào để đẩy mọi thứ để tôi có được bản sao đầy đủ của repo cục bộ trên điều khiển từ xa?


Câu trả lời ngắn nhất và dễ nhất - stackoverflow.com/a/39992258/6648326 .
MasterJoe2

Câu trả lời:


898

Để đẩy tất cả các chi nhánh của bạn , hãy sử dụng một trong hai (thay thế XÓA bằng tên của điều khiển từ xa, ví dụ "origin"):

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

Để đẩy tất cả các thẻ của bạn :

git push REMOTE --tags

Cuối cùng, tôi nghĩ bạn có thể thực hiện tất cả điều này trong một lệnh với:

git push REMOTE --mirror

Tuy nhiên, ngoài ra --mirror, cũng sẽ đẩy điều khiển từ xa của bạn, vì vậy đây có thể không chính xác như những gì bạn muốn.


53
--allthay vì *:*có vẻ thân thiện hơn
Idan K

56
chúa ơi ............. tôi đã xé toàn bộ internet và tôi phát hiện ra công tắc `--all` là AAAAALLLLLLLLLLLLLLL tôi cần!
Rakib

21
Chỉ cần lưu ý rằng git push REMOTE --alltrở về No refs in common and none specified;không làm gì., Trong khi git push REMOTE "*:*thực sự đẩy tất cả các chi nhánh đến điều khiển từ xa.
Im0rtality

10
Sử dụng --dry-run để kiểm tra những gì sẽ xảy ra, trong trường hợp bạn có các nhánh "tmp" hoặc "tính năng" cục bộ mà bạn không thực sự muốn cập nhật trong REMOTE
Jonno

55
Nếu điều khiển từ xa ban đầu vẫn có sẵn, đó là một ý tưởng hay để làm git clone --mirror old-remote-url; cd repo.git; git push --mirror new-remote-url.
Suzanne Dupéron

157

Trong trường hợp như tôi, bạn đã sử dụng một repo và hiện đang chuyển đổi nguồn gốc từ xa sang một repo khác, một cái trống mới ...

Vì vậy, bạn có repo của bạn và tất cả các nhánh bên trong, nhưng bạn vẫn cần kiểm tra các nhánh đó để git push --alllệnh thực sự đẩy chúng.

Bạn nên làm điều này trước khi bạn đẩy:

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

Theo dõi bởi

git push --all

4
Điều này cũng thực sự hữu ích, vì tôi phải kiểm tra tất cả các chi nhánh bằng tay. Điều này sẽ tốt cho lần sau.
Cory Imdieke

10
Lạ thay, git push '*:*'đẩy tất cả các chi nhánh. git push -allvừa đẩy thầy. Tôi đã vận chuyển repo từ github sang bitbucket.
jerrymouse

3
Thay vì kiểm tra từng chi nhánh, bạn chỉ nên thực hiện "git chi nhánh --track $ remote". Trong các repos lớn, việc kiểm tra một chi nhánh cũ đôi khi mất
Moataz Elmasry

2
Tôi đã phải thực hiện một thay đổi nhỏ để làm việc này: --track remotes/$remotethay vì --track $remote. Đây là dòng lệnh hoàn chỉnh:for remote in `git branch -r | grep -v master `; do git checkout --track remotes/$remote ; done
Adrian T

Cảm ơn, nó hoạt động với tôi, câu trả lời trên không hoạt động tốt.
Benyamin Jafari

90

Đây là một vấn đề khác tương tự với tình huống mà tôi gặp phải. Nó giải quyết vấn đề bạn có nhiều hơn một điều khiển từ xa, muốn sao chép tất cả các chi nhánh từ xa sourcesang điều khiển từ xa destinationnhưng không cần phải kiểm tra tất cả trước.

(Vấn đề tôi gặp phải với giải pháp của Daniel là nó sẽ từ chối kiểm tra một nhánh theo dõi từ sourcexa nếu trước đó tôi đã kiểm tra nó rồi, tức là nó sẽ không cập nhật chi nhánh địa phương của tôi trước khi đẩy)

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

Lưu ý: Nếu bạn không sử dụng CLI trực tiếp, bạn phải thoát khỏi các dấu sao:

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

điều này sẽ đẩy tất cả các nhánh ở xa sourceđến một nhánh đầu destination, có thể thực hiện một cú đẩy không nhanh về phía trước. Bạn vẫn phải đẩy các thẻ riêng biệt.


8
+1 Điều này làm việc cho tôi, nhân bản từ người này remotesang người khác. Cảm ơn!
Laurence

4
Tôi đã phải thoát khỏi các dấu sao:git push destination +refs/remotes/source/\*:refs/heads/\*
mattalxndr

2
Đối với tôi, vết thương này đã đẩy một nhánh gọi là CHÍNH, mà tôi không nghĩ là cố ý trong kịch bản này.
maxwellb

1
Câu trả lời này rất hữu ích với tôi. Sự đề cập duy nhất trong trang man git-đẩy (1) về việc sử dụng dấu sao này là trong một ví dụ nhỏ cho --prunetùy chọn này.
laindir 17/05/2016

4
Câu trả lời tuyệt vời, khác xa so với thông --mirrorsố thông thường mà mọi người khuyên dùng. Hoạt động hoàn hảo cho các tình huống mà bạn chỉ muốn giữ đồng bộ hai điều khiển từ xa cho mục đích tự động hóa hoặc kiểm toán.
Vinicius Xavier

15

Đây là cách ngắn gọn nhất mà tôi đã tìm thấy, với điều kiện đích đến trống rỗng. Chuyển sang một thư mục trống và sau đó:

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

Thay thế https://...cho file:///your/repovv khi thích hợp.


13

Các manpage cho git-pushlà đáng đọc. Kết hợp với trang web này, tôi đã viết như sau .git/config:

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

push = :nghĩa là "đẩy bất kỳ nhánh 'khớp' nào (tức là các nhánh đã tồn tại trong kho lưu trữ từ xa và có đối tác cục bộ)", trong khi đó push = refs/tags/*có nghĩa là "đẩy tất cả các thẻ".

Vì vậy, bây giờ tôi chỉ phải chạy git pushđể đẩy tất cả các nhánh phù hợp và tất cả các thẻ.

Đúng, đây không hoàn toàn là những gì OP muốn (tất cả các nhánh cần đẩy phải tồn tại ở phía xa), nhưng có thể hữu ích cho những người tìm thấy câu hỏi này trong khi googling cho "làm cách nào để đẩy các nhánh và thẻ cùng một lúc thời gian".


13

Trong trường hợp của tôi những gì đã làm việc là.

git push origin --all

4
Đơn giản và dễ dàng. Nó hoạt động! originlà bí danh cho kho lưu trữ Git URL từ xa.
Đỗ Như Vy

8

Phản chiếu một kho lưu trữ

Tạo một bản sao trần của kho lưu trữ.

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

Gương đẩy vào kho lưu trữ mới.

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

Xóa kho lưu trữ cục bộ tạm thời bạn đã tạo ở bước 1.

cd ..
rm -rf old-repository.git

Phản chiếu kho lưu trữ chứa các đối tượng Lưu trữ tệp lớn Git

Tạo một bản sao trần của kho lưu trữ. Thay thế tên người dùng mẫu bằng tên của người hoặc tổ chức sở hữu kho lưu trữ và thay thế tên kho lưu trữ mẫu bằng tên của kho lưu trữ mà bạn muốn sao chép.

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

Điều hướng đến kho lưu trữ mà bạn vừa nhân bản.

cd old-repository.git

Kéo vào các đối tượng Lưu trữ tệp lớn Git của kho lưu trữ.

git lfs fetch --all

Gương đẩy vào kho lưu trữ mới.

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

Đẩy các đối tượng lưu trữ tệp Git Large của kho lưu trữ vào máy nhân bản của bạn.

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

Xóa kho lưu trữ cục bộ tạm thời bạn đã tạo ở bước 1.

cd ..
rm -rf old-repository.git

Hướng dẫn trên đến từ Trợ giúp của Github: https://help.github.com/articles/d repeatating-a-reposeective /


1
Trong khi về mặt lý thuyết có thể trả lời câu hỏi, tốt hơn là nên bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Xem ở đây để được hướng dẫn cách viết câu trả lời "dựa trên liên kết" tốt hơn . Cảm ơn!
GhostCat

5

Tôi tìm thấy câu trả lời ở trên vẫn còn một số điều không rõ ràng, sẽ gây hiểu lầm cho người dùng. Đầu tiên, chắc chắn rằng git push new_origin --allgit push new_origin --mirrorkhông thể sao chép tất cả các nhánh xuất xứ, nó chỉ sao chép các nhánh tồn tại cục bộ của bạn với new_origin của bạn.

Dưới đây là hai phương pháp hữu ích tôi đã thử nghiệm:

1, nhân đôi bằng bản sao repo trần. git clone --bare origin_url, sau đó nhập thư mục và git push new_origin_url --mirror. Bằng cách này, bạn cũng có thể sử dụng git clone --mirror origin_url, cả hai --bare--mirrorsẽ tải xuống một repo trần, không bao gồm không gian làm việc. vui lòng tham khảo điều này

2, Nếu bạn có một repo git bằng cách sử dụng git clone, điều đó có nghĩa là bạn có không gian làm việc repo và git trần, bạn có thể sử dụng git remote add new_origin new_origin_url, và sau đó git push new_origin +refs/remotes/origin/\*:refs/heads/\*, và sau đógit push new_origin --tags

Bằng cách này, bạn sẽ có được một nhánh đầu thêm, không có ý nghĩa.


2

Để đẩy các nhánh và thẻ (nhưng không phải điều khiển từ xa):

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

Điều này sẽ tương đương với việc kết hợp các tùy chọn --tagsvà , mà git dường như không cho phép.--allgit push


Có một tùy chọn bổ sung để đẩy từ một điều khiển từ xa khác? Chẳng hạn với+refs/remotes/source/*
Yves Martin

2

Dựa trên câu trả lời @Daniel tôi đã làm:

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

2
Thậm chí tốt hơn, | grep -v mastercó thể được thay thế bằng | sed 's/\*//'(Tôi giả sử bạn đã loại trừ masterđể tránh một chút khó chịu được đặt *trước cho chi nhánh hiện được chọn) cho phép bạn bao gồm mastervà tránh mọi vấn đề khi masterkhông phải là chi nhánh hiện tại của bạn. Cũng xin lỗi vì đã hoại tử, chỉ là câu trả lời này đã giúp tôi hôm nay và tôi muốn chia sẻ sửa đổi của mình nếu nó có thể giúp những người khác ở vị trí của tôi ...
ToVine

1

Tôi thấy rằng không ai trong số này dường như làm việc đúng với tôi. Hãy thoải mái thực hiện điều này cho đến chết nhưng vì một số lý do không thể có được các tùy chọn khác để hoạt động đúng.

Kết quả dự kiến ​​là một repo "nhân bản" sang một điều khiển từ xa khác (tức là từ Github đến một nhà cung cấp khác):

  • Tất cả các chi nhánh được tạo trên điều khiển từ xa mới
  • Tất cả lịch sử chi nhánh được tạo trên điều khiển từ xa mới
    • (điều này đã bị bỏ lỡ trên mọi giải pháp tôi đã thử)
  • Tất cả các thẻ được tạo trên điều khiển từ xa mới
  • Nguồn di chuyển qua (nhất định)
  • Không phá hủy (tạm dừng tùy chọn --mirror)

Vấn đề chính tôi đang thấy là tất cả các chi nhánh từ xa đã không được tạo lại trong điều khiển từ xa mới. Nếu một lệnh đã làm, điều khiển từ xa mới không có lịch sử chi nhánh (tức là thực hiện git checkout branch; git logsẽ không hiển thị các cam kết chi nhánh dự kiến).

Tôi nhận thấy git checkout -b branchnameKHÔNG giống như git checkout branchname(cái sau là thứ tôi cần). Tôi nhận thấy git checkout --track branchnameđã không xuất hiện để kéo lịch sử chi nhánh.

Giải pháp của tôi (dựa trên 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

Lệnh bên dưới sẽ đẩy tất cả các nhánh ( bao gồmgit branch -a cả các nhánh mà bạn chưa bao giờ thanh toán nhưng hiện diện trong repo git của bạn, bạn có thể thấy chúng bằng cách )

git push origin '*:*'

LƯU Ý: Lệnh này có ích khi bạn di chuyển dịch vụ kiểm soát phiên bản ( tức là di chuyển từ Gitlab sang GitHub )


1
Di chuyển giữa các dịch vụ kiểm soát phiên bản và đây chính xác là những gì tôi đang tìm kiếm, chúc mừng!
Luka poljarić

1

Tôi đang trong quá trình chuyển đổi từ dịch vụ kiểm soát phiên bản này sang dịch vụ khác và cần sao chép tất cả các kho lưu trữ bao gồm tất cả các chi nhánh, thẻ và lịch sử.

Để đạt được điều trên tôi đã làm tiếp theo:

  • kiểm tra thủ công tất cả các chi nhánh vào kho lưu trữ cục bộ (tập lệnh để kiểm tra tất cả được hiển thị bên dưới),
  • git push origin '*:*'

tập lệnh .sh được sử dụng để kiểm tra tất cả các nhánh vào kho lưu trữ cục bộ:

for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
   git branch --track ${branch#remotes/origin/} $branch
done
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.