ความแตกต่างระหว่างการชำระเงิน git - แทร็กกำเนิด / สาขาและการชำระเงิน git -b กำเนิดสาขา /


209

มีใครทราบถึงความแตกต่างระหว่างสองคำสั่งนี้เพื่อสลับและติดตามสาขาระยะไกลหรือไม่?

git checkout -b branch origin/branch
git checkout --track origin/branch

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

มีความแตกต่างในทางปฏิบัติหรือไม่?

ขอบคุณ!

คำตอบ:


282

คำสั่งทั้งสองมีผลเหมือนกัน ( ขอบคุณคำตอบของ Robert Siemer ที่ชี้ให้เห็น )

ความแตกต่างในทางปฏิบัติเกิดขึ้นเมื่อใช้สาขาท้องถิ่นที่ชื่อแตกต่างกัน

  • git checkout -b mybranch origin/abranchจะสร้างmybranchและติดตามorigin/abranch
  • git checkout --track origin/abranchจะสร้าง ' abranch' ไม่ใช่สาขาที่มีชื่ออื่น

(นั่นคือตามที่แสดงความเห็นโดยSebastian Grafหากสาขาท้องถิ่นไม่ได้มีอยู่แล้ว
ถ้ามันคุณจะต้องgit checkout -B abranch origin/abranch)


หมายเหตุ: ด้วย Git 2.23 (Q3 2019) ที่จะใช้คำสั่งใหม่git switch :

git switch -c <branch> --track <remote>/<branch>

หากสาขามีอยู่ในการควบคุมระยะไกลหลายตัวและหนึ่งในนั้นถูกตั้งชื่อโดยcheckout.defaultRemoteตัวแปรการกำหนดค่าเราจะใช้สาขานั้นเพื่อจุดประสงค์ในการแก้ความกำกวมแม้ว่าสิ่ง<branch>นั้นจะไม่ซ้ำกันในการรีโมททั้งหมด
ตั้งค่าเป็นเช่นcheckout.defaultRemote=originเพื่อเช็คสาขาระยะไกลจากที่นั่นเสมอหาก<branch>คลุมเครือ แต่มีอยู่ในรีโมต 'ต้นทาง'

ที่นี่ ' -c' คือใหม่ ' -b'


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

# git config branch.<branch-name>.remote origin
# git config branch.<branch-name>.merge refs/heads/branch

git checkout -b branch origin/branch จะ:

  • สร้าง / การตั้งค่าไปยังจุดอ้างอิงโดยbranchorigin/branch
  • สร้างสาขาbranch(มีgit branch) origin/branchและติดตามสาขาที่ห่างไกลการติดตาม

เมื่อสาขาในพื้นที่เริ่มต้นจากสาขาการติดตามระยะไกล Git จะจัดตั้งสาขา (โดยเฉพาะรายการbranch.<name>.remoteและbranch.<name>.mergeการกำหนดค่า)เพื่อที่git pullจะรวมเข้ากับสาขาการติดตามระยะไกลอย่างเหมาะสม
ลักษณะการทำงานนี้อาจเปลี่ยนแปลงได้ผ่านการbranch.autosetupmergeตั้งค่าสถานะส่วนกลาง การตั้งค่าที่สามารถแทนที่ด้วยการใช้--trackและตัวเลือกและการเปลี่ยนแปลงในภายหลังโดยใช้สาขาคอมไพล์--no-track--set-upstream-to


และgit checkout --track origin/branchจะทำเช่นเดียวกับgit branch --set-upstream-to):

 # or, since 1.7.0
 git branch --set-upstream upstream/branch branch
 # or, since 1.8.0 (October 2012)
 git branch --set-upstream-to upstream/branch branch
 # the short version remains the same:
 git branch -u upstream/branch branch

นอกจากนี้ยังจะตั้งค่าอัปสตรีมสำหรับ ' branch'

(หมายเหตุ: git1.8.0 จะเลิกใช้แล้วgit branch --set-upstreamแทนที่ด้วยgit branch -u|--set-upstream-to: ดูgit1.8.0-rc1 ประกาศ )


การลงทะเบียนสาขาต้นน้ำสำหรับสาขาท้องถิ่นจะ:

  • บอกคอมไพล์ที่จะแสดงให้เห็นความสัมพันธ์ระหว่างสองสาขาในgit statusgit branch -vและ
  • ชี้นำgit pull โดยไม่ขัดแย้งที่จะดึงจากต้นน้ำเมื่อสาขาใหม่จะถูกตรวจสอบจาก

ดูที่ " คุณจะทำให้สาขา git ที่มีอยู่ติดตามสาขาระยะไกลได้อย่างไร " สำหรับข้อมูลเพิ่มเติม


1
@VonC ฉันกำลังมองหารายละเอียดเล็ก ๆ น้อย ๆ ที่คุณพูดถึงเป็นข้อมูลพิเศษ ในกรณีของฉันฉันอยากรู้ว่าทำไมฉันถึงมีสาขาของฉันอนุญาตให้ฉันgit pullในขณะที่บางสาขาจะขอให้รีโมตสาขาดึงออกมา ปรากฎว่าหากคุณในครั้งแรกที่คุณกำลังตรวจสอบสาขาระยะไกลที่เพื่อนของคุณสร้างขึ้น git จะดำเนินการต่อและเพิ่มbranch.<BNAME>.remote=originไปยัง gitconfig ในพื้นที่ git pullซึ่งจะช่วยให้คุณกับปัญหา อย่างไรก็ตามหากคุณเป็นคนหนึ่งที่สร้างสาขาgit checkout -b BNAMEดังนั้นก็ไม่รู้จักคอมไพล์แน่นอน ดังนั้นคุณควรระบุระยะไกล
batilc

@batilc "ปรากฎว่าหากคุณเป็นครั้งแรกที่กำลังตรวจสอบสาขาระยะไกลที่เพื่อนของคุณสร้างขึ้น"; ใช่อ่านgit-scm.com/docs/git-checkoutฉันเห็น: " If <branch>ไม่พบ แต่มีสาขาการติดตามอยู่ในระยะไกลหนึ่ง (เรียกว่า<remote>) ด้วยชื่อที่ตรงกันให้ถือว่าเทียบเท่ากับ$ git checkout -b <branch> --track <remote>/<branch>"
VonC

@VonC ฉันพบการกำหนดค่าที่ดีกว่าสำหรับสิ่งนี้ การตั้งค่าbranch.autoSetupMergeให้alwaysดำเนินการสิ่งที่เรากำลังพูดถึง การตั้งค่านี้เป็นค่าเริ่มต้นtrueซึ่งหมายถึงการติดตามจะดำเนินการเฉพาะเมื่อตรวจสอบสาขาระยะไกล trueไม่ตั้งค่าการติดตามสำหรับสาขาที่สร้างในเครื่อง
batilc

@batilc ฉันเห็นด้วย ฉันมักจะไม่ใช้งานตลอดเวลาเนื่องจากฉันต้องการตั้งค่าการติดตามอย่างชัดเจน แต่ในกรณีของคุณนั่นควรเป็นการตั้งค่าที่เหมาะสม
VonC

1
"git branch - set-upstream-to branch upstream / branch" ไม่ใช่ไวยากรณ์ที่ถูกต้อง มันควรจะเป็น: "สาขา git - การตั้งค่าต้นน้ำถึงต้นน้ำ / สาขา"
maharvey67

33

ไม่มีความแตกต่างเลย!

1) git checkout -b branch origin/branch

หากไม่มี--trackและไม่มี--no-track, --trackจะถือว่าเป็นค่าเริ่มต้น branch.autosetupmergeเริ่มต้นสามารถเปลี่ยนแปลงได้ด้วยการตั้งค่า

ผล 1) git checkout -b branch --track origin/branchพฤติกรรมเช่น

2) git checkout --track origin/branch

“ เพื่ออำนวยความสะดวก” --trackโดยไม่ต้อง-bบอกเป็นนัย-bและการโต้เถียง-bว่าจะเป็น "สาขา" remote.origin.fetchคาดเดาถูกขับเคลื่อนโดยการกำหนดค่าตัวแปร

ผล 2) git checkout -b branch --track origin/branchพฤติกรรมเช่น

อย่างที่คุณเห็น: ไม่มีความแตกต่าง

แต่มันจะดีขึ้นกว่าเดิม:

3) git checkout branch

ยังเทียบเท่ากับgit checkout -b branch --track origin/branchถ้า“สาขา” ยังไม่มี แต่“ต้นกำเนิด / สาขา” ไม่1


คำสั่งทั้งสามตั้งค่า "ต้นน้ำ" ของ "branch" เป็น "ต้นทาง / สาขา" (หรือล้มเหลว)

ต้นน้ำถูกนำมาใช้เป็นจุดอ้างอิงของการโต้แย้งน้อยgit status, git push, git mergeและทำให้git pull(ถ้ากำหนดค่าเช่นนั้น (ซึ่งเป็นค่าเริ่มต้นหรือเกือบเริ่มต้น))

เช่นgit statusบอกให้คุณรู้ว่าคุณอยู่ข้างบนหรือข้างหลังไกลแค่ไหนหากมีการกำหนดค่าไว้

git pushมีการกำหนดค่าให้กดสาขาปัจจุบันอัปสตรีมโดยค่าเริ่มต้น2ตั้งแต่ git 2.0

1 ... และถ้า "ต้นกำเนิด" เป็นรีโมทเดียวที่มี "สาขา"
2ค่าเริ่มต้น (ชื่อ "ง่าย") ยังบังคับใช้สำหรับชื่อสาขาทั้งสองให้เท่ากัน


5

ดูเหมือนว่าหนังสือเล่มนี้จะระบุว่าคำสั่งเหล่านั้นให้ผลเช่นเดียวกัน:

กรณีง่าย ๆ คือตัวอย่างที่คุณเพิ่งเห็นใช้ git checkout -b [branch] [remotename] / [branch] หากคุณมี Git เวอร์ชัน 1.6.2 หรือใหม่กว่าคุณสามารถใช้ - ติดตามชวเลขได้:

$ git checkout --track origin/serverfix 
Branch serverfix set up to track remote branch serverfix from origin. 
Switched to a new branch 'serverfix' 

ในการตั้งค่าสาขาในพื้นที่ที่มีชื่อแตกต่างจากสาขาระยะไกลคุณสามารถใช้เวอร์ชันแรกที่มีชื่อสาขาในพื้นที่แตกต่างกันได้อย่างง่ายดาย:

$ git checkout -b sf origin/serverfix

มันมีประโยชน์มากโดยเฉพาะอย่างยิ่งเมื่อการทุบตีสำเร็จหรือ bash หรือ oh-my-zsh ของคุณสามารถดึงorigin/serverfixชื่อให้คุณได้ - เพียงต่อท้าย--track(หรือ-t) และคุณก็ไปแล้ว


-1

คุณไม่สามารถสร้างสาขาใหม่ด้วยคำสั่งนี้

git checkout --track origin/branch

หากคุณมีการเปลี่ยนแปลงที่ไม่ได้จัดเตรียมไว้

นี่คือตัวอย่าง:

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   src/App.js

no changes added to commit (use "git add" and/or "git commit -a")

// TRY TO CREATE:

$ git checkout --track origin/new-branch
fatal: 'origin/new-branch' is not a commit and a branch 'new-branch' cannot be created from it

อย่างไรก็ตามคุณสามารถสร้างสาขาใหม่ได้อย่างง่ายดายด้วยการเปลี่ยนแปลงแบบไม่มีฉากพร้อมgit checkout -bคำสั่ง:

$ git checkout -b new-branch
Switched to a new branch 'new-branch'
M       src/App.js

โปรดจำไว้ว่าทั้งสองคำสั่งในคำถามนั้นมีไว้สำหรับติดตามสาขาระยะไกลที่มีอยู่ ( origin/branch)
5659

@Green การทดสอบที่คุณทำอยู่กับแทนorigin/new-branch origin/branchคุณรู้หรือไม่?
Robert Siemer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.