เหตุใดฉันจึงต้องผลักดันสาขาใหม่อย่างชัดเจน


180

ฉันใหม่gitและฉันกำลังฝึกซ้อม ฉันสร้างสาขาท้องถิ่น แต่ฉันเห็นว่าเมื่อฉันทำgit pushสาขาของฉันไม่ได้อัปโหลดไปยังที่เก็บ ฉันต้องทำจริง: git push -u origin --all.
ทำไมนี้ การเปลี่ยนแปลงใหม่ที่จะผลักดันเป็นค่าเริ่มต้นไม่ใช่สาขาใช่หรือไม่ ทำไมฉันต้องเรียกใช้คำสั่งที่สอง


15
โปรดทราบว่านี่คือการกำหนดค่า (การตั้งค่าpush.defaultดูman git-config) ถ้าคุณทำgit config --add push.default currentแล้วgit pushจะสร้างสาขาใน repo ระยะไกลโดยอัตโนมัติหากจำเป็น ทำไมนี่ไม่ใช่ค่าเริ่มต้นอธิบายในคำตอบ
sleske

@sleske ฉันเห็นด้วย สำหรับนโยบายอื่น ๆ ' current' และ ' upstream' ดูคำตอบของฉันเก่าstackoverflow.com/a/13751847/6309
VonC

ทำไมไม่ยอมรับคำตอบ?
laike9m

คำตอบ:


225

เหตุผลที่แท้จริงคือใน repo ใหม่ (git init) ไม่มีสาขา (ไม่masterไม่มีสาขาเลยไม่มีสาขา)

ดังนั้นเมื่อคุณกดเป็นครั้งแรกไปยังrepo upstream ที่ว่างเปล่า (โดยทั่วไปคือrepo เปล่า ) repo upstream นั้นไม่มีสาขาที่มีชื่อเดียวกัน

และ:

ในทั้งสองกรณีเนื่องจาก repo ที่ว่างเปล่าต้นน้ำไม่มีสาขา:

  • ไม่มีสาขาที่มีชื่อตรงกัน
  • ไม่มีสาขาต้นน้ำเลย (มีหรือไม่มีชื่อเดียวกัน! การติดตามหรือไม่)

นั่นหมายความว่าการกดครั้งแรกในพื้นที่ของคุณไม่มีความคิด

  • สถานที่ที่จะผลักดัน
  • สิ่งที่จะผลักดัน (เนื่องจากไม่พบสาขาอัปสตรีมใด ๆ ที่ถูกบันทึกเป็นสาขาการติดตามระยะไกลและ / หรือมีชื่อเดียวกัน)

ดังนั้นคุณต้องทำอย่างน้อย:

git push origin master

แต่ถ้าคุณทำอย่างนั้นคุณ:

  • จะสร้างmasterสาขาอัปสตรีมบนอัปสตรีม (ตอนนี้ repo ที่ไม่ว่าง): ดี
  • จะไม่บันทึกว่าสาขา ' master' ท้องถิ่นจำเป็นต้องผลักไปที่ upstream ( origin) ' master' (upstream branch): ไม่ดี

นั่นคือเหตุผลที่แนะนำสำหรับการกดครั้งแรกเพื่อทำ:

git push -u origin master

ที่จะบันทึกorigin/masterเป็นสาขาการติดตามระยะไกลและจะช่วยผลักดันต่อไปที่จะผลักดันโดยอัตโนมัติเพื่อmasterorigin/master

git checkout master
git push

และนั่นก็จะใช้ได้เช่นกันกับนโยบายการพุช ' current' หรือ ' upstream'
ในแต่ละกรณีหลังจากการเริ่มต้นgit push -u origin masterการกด git อย่างง่ายจะเพียงพอที่จะผลักดันมาสเตอร์ไปยังสาขาต้นน้ำด้านขวา


2
หลังจากจุดนี้ถัดไปgit pushก็คาดว่าสาขาจะมีอยู่แล้ว?
Cratylus

2
ใช่. มันจะผลักดันการปรับปรุงใด ๆ ไปยังสาขานั้นไปยังพื้นที่เก็บข้อมูลต้นน้ำ
RyPeck

@Cratylus ใช่เนื่องจากนโยบายการพุชเริ่มต้นใหม่ ' simple': กดไปที่สาขาอัปสตรีมใด ๆ ที่บันทึกไว้หากสาขาอัปสตรีมนั้นมีชื่อเดียวกับโลคอลท้องถิ่น git pushจะง่ายพอ
VonC

1
@ButtleButkus ขอบคุณ ฉันได้คืนลิงค์
VonC

3
สำหรับกรณีทั่วไปของผู้ถามของสาขาใหม่ 'new_branch' คุณควรใช้git push --set-upstream origin new_branchหรือgit push -u origin new_branchย่อให้สั้น ผู้-allถามใช้การเลี่ยงผ่านการตั้งชื่อสาขาใหม่โดยรวมทุกสาขา นี่เป็นคำตอบของเขา + Klas Mellbourn
Paul Masri-Stone

106

คุณทำไม่ได้ดูด้านล่าง

ฉันพบว่าคุณสมบัติ 'นี้' ค่อนข้างน่ารำคาญเพราะฉันไม่ได้พยายามที่จะเปิดตัวจรวดไปยังดวงจันทร์เพียงแค่ผลักสาขาแช่งของฉัน คุณอาจทำเช่นนั้นไม่งั้นคุณจะไม่มาที่นี่!

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

git config --global push.default current

ดังนั้นถ้าคุณทำสาขาเช่นนี้:

git checkout -b my-new-branch

จากนั้นทำคอมมิทบางส่วนแล้วทำ a

git push -u

เพื่อให้พวกเขาออกไปที่จุดเริ่มต้น (อยู่ที่สาขานั้น) และมันจะสร้างสาขาดังกล่าวให้คุณถ้าไม่มี

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


3
เมื่อฉันทำเช่นนี้ถ้าฉันดึง git ทันทีหลังจาก - ทั้งสองสาขาไม่ได้เชื่อมโยง :(
Alisso

นี่เป็นคำตอบเดียวที่แก้ไขปัญหาของฉัน
Raymond Chenon

2
เพื่อเชื่อมโยงพวกเขาใช้git push -u
Ben Creasy

ขอบคุณ! คำตอบนี้ควรได้รับการยอมรับว่าเป็นวิธีที่รวดเร็วและ 'สกปรก' ฉันค่อนข้างมั่นใจว่ามันใกล้เคียงกับความตั้งใจของ OP มากที่สุด
youngrrrr

3
> ฉันไม่ได้พยายามที่จะยิงจรวดไปยังดวงจันทร์ - ใช่
VCavallo

39

เอาต์พุตของgit pushเมื่อกดสาขาใหม่

> git checkout -b new_branch
Switched to a new branch 'new_branch'
> git push
fatal: The current branch new_branch has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin new_branch

Simple git pushถือว่าสมมติฐานว่ามีสาขาระยะไกลที่สาขาท้องถิ่นปัจจุบันกำลังติดตามอยู่ หากไม่มีสาขาระยะไกลดังกล่าวอยู่และคุณต้องการสร้างมันขึ้นมาคุณต้องระบุว่าใช้แฟล็ก-u(รูปแบบย่อ--set-upstream)

ทำไมถึงเป็นเช่นนั้น? ฉันเดาว่าผู้ใช้งานรู้สึกว่าการสร้างสาขาบนรีโมตเป็นการกระทำที่สำคัญที่ควรจะทำได้ยากโดยไม่ตั้งใจ git pushเป็นสิ่งที่คุณทำตลอดเวลา

"ไม่ใช่การเปลี่ยนแปลงใหม่ที่จะผลักดันโดยปริยายหรือ" ฉันจะบอกว่า "การเปลี่ยนแปลง" ใน Git คือการกระทำ สาขาเป็นตัวชี้ไปยังกระทำ สำหรับฉันมันสมเหตุสมผลกว่าที่จะคิดว่าการผลักดันเป็นสิ่งที่ผลักดันให้คอมมิชชันอื่น ๆ ความมุ่งมั่นใดที่ถูกผลักจะถูกกำหนดโดยสาขาที่คุณอยู่และความสัมพันธ์การติดตามของสาขานั้นไปยังสาขาในระยะไกล

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการติดตามสาขาในสาขาบทระยะไกลของหนังสือ Pro Git


ฉันไม่ได้รับ a fatalแต่ฉันได้ทำคอมมิชชันในสาขาแล้วเรื่องนี้?
Cratylus

@ Cratylus ไม่มันไม่สำคัญ การกระทำมีความปลอดภัยในที่เก็บของคุณและgit push -u originคัดลอกไปยังที่เก็บระยะไกล
Klas Mellbourn

ไม่ฉันหมายถึงความจริงที่ว่าฉันไม่ได้รับfatalข่าวสารเช่นเดียวกับที่คุณพูดถึงในคำตอบความแตกต่างนี้ขึ้นอยู่กับความจริงที่ว่าฉันทำอะไรบางอย่างกับสาขาหรือไม่?
Cratylus

@Cratylus ฉันไม่รู้ว่าทำไมคุณไม่ได้รับfatalข้อความ ฉันเดาว่าความแตกต่างขึ้นอยู่กับการใช้งานคอมไพล์ที่คุณใช้ ผลลัพธ์ของฉันมาจาก 1.8.1.msysgit.1 ทำงานบน Windows 8
Klas Mellbourn

ฉันมีรุ่นเดียวกัน แต่ใช้กับ Vista
Cratylus

4

ฉันไม่สามารถหาเหตุผลโดยผู้พัฒนาดั้งเดิมได้อย่างรวดเร็ว แต่ฉันสามารถคาดเดาการศึกษาจากประสบการณ์ Git สองสามปี

ไม่ไม่ใช่ว่าทุกสาขาจะเป็นสิ่งที่คุณต้องการผลักดันสู่โลกภายนอก มันอาจแสดงถึงการทดลองส่วนตัว

นอกจากนี้ควรgit pushส่งสาขาทั้งหมดที่ไหน Git สามารถทำงานกับรีโมตหลายตัวและคุณอาจต้องการมีชุดสาขาที่แตกต่างกันในแต่ละอัน เช่นโครงการกลาง GitHub repo อาจมีการเปิดสาขา ส้อม GitHub อาจมีสาขาหัวข้อสำหรับการตรวจสอบ; และเซิร์ฟเวอร์ Git ท้องถิ่นอาจมีสาขาที่มีการกำหนดค่าท้องถิ่น หากgit pushจะผลักสาขาทั้งหมดไปยังระยะไกลที่สาขาปัจจุบันติดตามโครงการประเภทนี้จะง่ายต่อการกรูขึ้น


1) It might represent a private experiment.Ok แต่เรื่องใหญ่คืออะไร? สาขา "หลัก" ที่ทุกคนทำงานmasterคือไม่ได้รับผลกระทบ ถ้าคุณหมายถึงการให้รหัสที่มาที่ซ่อนอยู่ 2) git push, without a remote, pushes to the current branch's remoteฉันได้สูญเสียคุณที่นี่ :(
Cratylus

@Cratylus: 1) ในโปรเจ็กต์ที่มีนักพัฒนาหลายสิบคนที่ทุกสาขาโฆษณา lib คุณจะได้รับ repos ยุ่งมาก ฉันทำงานในโครงการดังกล่าวและฉันก็ไม่อยากไปทำงานgit fetchหลายร้อยสาขาทุกครั้ง 2) ฉันหมายถึงgit pushพฤติกรรมเริ่มต้นของ มันจะผลักดันไปยังรีโมตที่สาขาปัจจุบันกำลังติดตามหากมี
Fred Foo

3

HEAD สั้นสำหรับสาขาปัจจุบันดังนั้น git push -u origin HEAD ใช้งานได้ ตอนนี้เพื่อหลีกเลี่ยงการพิมพ์นี้ทุกครั้งที่ฉันใช้นามแฝง:

git config - alias.global ทั่วโลก 'push -u origin HEAD'

หลังจากนี้ทุกครั้งที่ฉันต้องการผลักดันสาขาที่สร้างขึ้นผ่านสาขา git -b ฉันสามารถผลักดันโดยใช้:

git pp

หวังว่านี่จะช่วยประหยัดเวลาสำหรับใครบางคน!


2

เมื่อตรวจสอบครั้งแรก

ขั้นตอนที่ 1: git remote -v
// หากพบ git เริ่มต้นแล้วลบหรือข้ามขั้นตอนที่ 2

ขั้นตอนที่ 2: git remote rm origin
// จากนั้นกำหนดค่าที่อยู่อีเมลของคุณทั่วโลกคอมไพล์

ขั้นตอนที่ 3: git config --global user.email "youremail@example.com"

ขั้นตอนที่ 4: git initial

ขั้นตอนที่ 5: git commit -m "Initial Project"
// ถ้าเพิ่ม repo โครงการแล้วข้ามขั้นตอนที่ 6

ขั้นตอนที่ 6: git remote add origin %repo link from bitbucket.org%

ขั้นตอนที่ 7: git push -u origin master


1

ฉันเพิ่งพบปัญหานี้อีกมาก

ฉันมีสาขาชื่อfeat/XYZ-1234-some-descriptionเพราะฉันทำงานกับ Jira ปัญหา 1234 ในระหว่างการทำงานฉันสร้างปัญหา Jira ใหม่เพื่อติดตามงานชิ้นเล็ก ๆ และเมื่อฉันมาที่จะผลักฉันตัดสินใจที่จะผลักดันชื่อสาขาด้วยหมายเลขปัญหาใหม่นี้ ใน:

git push -u origin feat/XYZ-5678-a-different-description # failed

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

git branch -m feat/XYZ-1234-some-description feat/XYZ-5678-a-different-description
git push -u origin feat/XYZ-5678-a-different-description # now works

หลังจากอ่านเพิ่มอีกนิดฉันก็รู้ว่าฉันสามารถตั้งค่าsrcบน git push, ไม่ว่าจะเป็นชื่อสาขาปัจจุบันหรือHEADตามความเหมาะสม:

git push -u origin feat/XYZ-1234-some-description:feat/XYZ-5678-a-different-description # also works

-1

หากคุณเปิดใช้งานเพื่อผลักดันการเปลี่ยนแปลงใหม่จากสาขาใหม่ของคุณเป็นครั้งแรก และรับข้อผิดพลาดด้านล่าง:

*git push -f
fatal: The current branch Coding_Preparation has no upstream branch.

เพื่อผลักดันสาขาปัจจุบันและตั้งค่ารีโมตเป็นอัปสตรีมใช้

git push -u origin new_branch_name


** Successful Result:** 
 git push -u origin Coding_Preparation
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 599 bytes | 599.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'Coding_Preparation' on GitHub by visiting: ...
 * [new branch]      Coding_Preparation -> Coding_Preparation
Branch 'Coding_Preparation' set up to track remote branch 'Coding_Preparation' from 'origin'.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.