ผลักดัน Git repo ท้องถิ่นไปยังรีโมทใหม่รวมถึงทุกสาขาและแท็ก


551

ฉันมี repo Git ในท้องถิ่นที่ฉันต้องการผลักดันไปยัง repo ระยะไกลใหม่
repo ในพื้นที่ของฉันมีกิ่งไม้และแท็กบางส่วนและฉันต้องการเก็บประวัติทั้งหมดของฉันไว้

ดูเหมือนว่าโดยทั่วไปฉันแค่ต้องทำgit pushแต่เพียงอัพโหลดmasterสาขาเท่านั้น

ฉันจะผลักทุกอย่างเพื่อให้ได้ repo ของฉันในระยะไกลได้อย่างไร


ที่สั้นที่สุดและง่ายที่สุดคำตอบ - 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แทนที่จะ*:*ดูเหมือนเป็นมิตรมากขึ้น
Idan K

56
พระเจ้าของฉัน ............. ฉันฉีกขาดทั้งอินเทอร์เน็ตและฉันพบสวิตช์ "- ทั้งหมด" คือ AAAAALLLLLLLLLLLLLLLL ฉันต้องการ!
Rakib

21
เพียงสังเกตว่าสิ่งที่git push REMOTE --allส่งคืนNo refs in common and none specified;ไม่ได้ทำอะไรเลยในขณะที่git push REMOTE "*:*ผลักสาขาทั้งหมดไปยังระยะไกล
Im0rtality

10
ใช้ - ทำแห้งเพื่อตรวจสอบสิ่งที่จะเกิดขึ้นในกรณีที่คุณมีสาขา "tmp" หรือ "ฟีเจอร์" ในพื้นที่ที่คุณไม่ต้องการอัปเดตใน
ระยะไกลจริงๆ

55
git clone --mirror old-remote-url; cd repo.git; git push --mirror new-remote-urlถ้าระยะไกลเดิมยังคงมีอยู่มันเป็นความคิดที่ดีที่จะทำ
Suzanne Dupéron

156

ในกรณีเช่นฉันที่คุณได้รับ repo และตอนนี้ได้เปลี่ยนแหล่งกำเนิดระยะไกลเป็น repo ที่แตกต่างกันใหม่ที่ว่างเปล่าใหม่ ...

ดังนั้นคุณจึงมี repo และสาขาทั้งหมดอยู่ภายใน แต่คุณยังต้องเช็คเอาต์สาขาเหล่านั้นเพื่อให้git push --allคำสั่งผลักดันพวกนั้นด้วย

คุณควรทำสิ่งนี้ก่อนกด:

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

ติดตามโดย

git push --all

4
สิ่งนี้มีประโยชน์จริง ๆ เพราะฉันต้องเช็คเอ้าท์ทุกสาขาด้วยตนเอง นี่จะเป็นสิ่งที่ดีสำหรับครั้งต่อไป
Cory Imdieke

10
แปลกgit push '*:*'ผลักสาขาทั้งหมด git push -allเพิ่งผลักต้นแบบ ฉันกำลังขนย้าย repo จาก github ไปยัง bitbucket
jerrymouse

3
แทนที่จะตรวจสอบทุกสาขาคุณควรทำ "git branch - track $ remote" ใน repos ขนาดใหญ่การตรวจสอบสาขาเก่าจะใช้เวลา
Moataz Elmasry

2
ฉันได้เพื่อให้การเปลี่ยนแปลงขนาดเล็กสำหรับการทำงาน: แทน--track remotes/$remote --track $remoteนี่คือบรรทัดคำสั่งที่สมบูรณ์:for remote in `git branch -r | grep -v master `; do git checkout --track remotes/$remote ; done
Adrian T

ขอบคุณมันใช้งานได้สำหรับฉันคำตอบข้างต้นไม่ได้ผลเช่นกัน
Benyamin Jafari

90

นี่คืออีกสิ่งหนึ่งในสิ่งเดียวกันซึ่งทำงานได้ดีกว่าสำหรับสถานการณ์ฉันแก้ไขปัญหาที่คุณมีรีโมตมากกว่าหนึ่งต้องการโคลนทุกสาขาในรีโมตsourceเป็นรีโมตdestinationแต่ไม่ต้องตรวจสอบทั้งหมดก่อน

(ปัญหาที่ฉันมีกับโซลูชันของ Daniel คือมันจะปฏิเสธที่จะเช็คเอาต์สาขาการติดตามจากsourceระยะไกลหากฉันได้ตรวจสอบก่อนหน้านี้แล้วเช่นจะไม่อัปเดตสาขาในพื้นที่ของฉันก่อนที่จะกด)

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

หมายเหตุ: หากคุณไม่ได้ใช้ direct CLI คุณต้องหนีเครื่องหมายดอกจัน:

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) man page ของการใช้เครื่องหมายดอกจันนี้เป็นเพียงตัวอย่างเล็ก ๆ สำหรับ--pruneตัวเลือก
laindir

4
คำตอบที่ยอดเยี่ยมแตกต่างจาก--mirrorพารามิเตอร์ปกติที่ทุกคนแนะนำ ทำงานได้อย่างสมบูรณ์แบบสำหรับสถานการณ์ที่คุณเพียงต้องการให้รีโมททั้งสองของ sync'd สำหรับการดำเนินการอัตโนมัติหรือการตรวจสอบ
Vinicius Xavier

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

manpage สำหรับgit-pushมีค่าอ่าน เมื่อรวมกับเว็บไซต์นี้ฉันได้เขียนสิ่งต่อไปนี้ใน.git/config:

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

push = :หมายถึง "ผลักดัน 'จับคู่' ทุกสาขา (เช่นสาขาที่มีอยู่แล้วในพื้นที่เก็บข้อมูลระยะไกลและมีคู่ท้องถิ่น)" ในขณะที่push = refs/tags/*หมายถึง "ผลักดันแท็กทั้งหมด"

ดังนั้นตอนนี้ฉันต้องวิ่งgit pushไปผลักดันกิ่งไม้ที่ตรงกันทั้งหมดและแท็กทั้งหมด

ใช่นี่ไม่ใช่สิ่งที่ OP ต้องการ (สาขาทั้งหมดที่ต้องกดจะต้องมีอยู่ในฝั่งระยะไกล) แต่อาจเป็นประโยชน์สำหรับผู้ที่พบคำถามนี้ในขณะที่ googling สำหรับ "ฉันจะกดกิ่งและแท็กได้อย่างไรในเวลาเดียวกัน เวลา".


13

ในกรณีของฉันสิ่งที่ทำงานคือ

git push origin --all

4
ง่ายและสะดวก มันได้ผล! originเป็นชื่อแทนสำหรับที่เก็บ Git URL ระยะไกล
อย่านู Vy

8

ทำมิเรอร์ที่เก็บ

สร้างโคลนเปล่าของที่เก็บ

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

Mirror-push ไปยังที่เก็บใหม่

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

Mirror-push ไปยังที่เก็บใหม่

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 ซ้ำโดย repo เปลือยโคลน git clone --bare origin_urlจากนั้นป้อนโฟลเดอร์และgit push new_origin_url --mirrorด้วยวิธีนี้คุณยังสามารถใช้git clone --mirror origin_urlทั้งสอง--bareและ--mirrorจะดาวน์โหลด repo เปล่าโดยไม่รวมพื้นที่ทำงาน โปรดอ้างอิงสิ่งนี้

2, ถ้าคุณมี repo คอมไพล์โดยใช้git clone, ซึ่งหมายความว่าคุณมี repo และพื้นที่ทำงานคอมไพล์เปล่า, คุณสามารถใช้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/*
Yves Martin

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ไม่ใช่สาขาที่คุณเลือกในปัจจุบัน นอกจากนี้ยังขอโทษสำหรับการจัดทำ necroposting เป็นเพียงคำตอบนี้ช่วยฉันในวันนี้และฉันต้องการที่จะแบ่งปันการเปลี่ยนแปลงของฉันถ้ามันสามารถช่วยคนอื่นในตำแหน่งของฉัน ...
ToVine

1

ฉันพบว่าสิ่งเหล่านี้ดูเหมือนจะทำงานไม่ถูกต้องสำหรับฉัน รู้สึกอิสระที่จะทำให้เรื่องนี้กลายเป็นความตาย แต่ด้วยเหตุผลบางอย่างทำให้ตัวเลือกอื่นไม่สามารถทำงานได้อย่างถูกต้อง

ผลลัพธ์ที่คาดหวังคือ repo "cloned" ไปยังรีโมตอื่น (เช่นจาก Github ไปยังผู้ให้บริการรายอื่น):

  • ทุกสาขาถูกสร้างบนรีโมตใหม่
  • ประวัติสาขาทั้งหมดถูกสร้างขึ้นบนรีโมทใหม่
    • (สิ่งนี้พลาดทุกวิธีที่ฉันลอง)
  • แท็กทั้งหมดถูกสร้างขึ้นบนรีโมทใหม่
  • แหล่งที่มาย้ายไป (ที่กำหนด)
  • ไม่ทำลาย (หยุดชั่วคราวเพื่อตัวเลือก - กระจก)

ปัญหาสำคัญที่ฉันเห็นคือทั้งสาขาระยะไกลไม่ได้ถูกสร้างขึ้นในรีโมทใหม่ หากคำสั่งทำรีโมตใหม่จะไม่มีประวัติสาขา (เช่นการทำ a 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 branch -aสาขาที่คุณไม่เคยเช็คเอาท์ แต่อยู่ใน repo git ของคุณคุณสามารถดูได้ )

git push origin '*:*'

หมายเหตุ: คำสั่งนี้มีประโยชน์เมื่อคุณย้ายบริการควบคุมเวอร์ชัน ( เช่นย้ายจากGitlabไปยังGitHub )


1
การโยกย้ายระหว่างบริการควบคุมเวอร์ชันและนี่คือสิ่งที่ฉันกำลังค้นหาไชโย!
Luka Špoljarić

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.