Perbedaan antara git checkout --track asal / cabang dan git checkout -b asal cabang / cabang

209

Adakah yang tahu perbedaan antara kedua perintah ini untuk beralih dan melacak cabang jarak jauh?

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

Saya pikir keduanya melacak cabang jauh sehingga saya bisa mendorong perubahan saya ke cabang asal, kan?

Apakah ada perbedaan praktis ??

Terima kasih!

yorch
sumber

Jawaban:

282

Kedua perintah memiliki efek yang sama ( terima kasih atas jawaban Robert Siemer karena menunjukkannya ).

Perbedaan praktis muncul ketika menggunakan cabang lokal yang bernama berbeda :

  • git checkout -b mybranch origin/abranchakan membuat mybranchdan melacakorigin/abranch
  • git checkout --track origin/abranchhanya akan membuat ' abranch', bukan cabang dengan nama yang berbeda.

(Yaitu, seperti dikomentari oleh Sebastian Graf , jika cabang lokal belum ada.
Jika ya, Anda perlu git checkout -B abranch origin/abranch)


Catatan: dengan Git 2.23 (Q3 2019), itu akan menggunakan perintah barugit switch :

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

Jika cabang ada di beberapa jarak jauh dan salah satunya dinamai oleh checkout.defaultRemotevariabel konfigurasi, kami akan menggunakannya untuk tujuan disambiguasi, bahkan jika <branch>tidak unik di semua jarak jauh.
Setel ke eg checkout.defaultRemote=originuntuk selalu checkout cabang jarak jauh dari sana jika <branch>ambigu tetapi ada pada remote 'asal'.

Di sini, ' -c' adalah yang baru ' -b'.


Pertama, beberapa latar belakang: Pelacakan berarti bahwa cabang lokal memiliki hulu yang disetel ke cabang jarak jauh:

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

git checkout -b branch origin/branch akan:

  • buat / reset branchke titik yang dirujuk oleh origin/branch.
  • buat cabang branch(dengan git branch) dan lacak cabang pelacakan jarak jauh origin/branch.

Ketika cabang lokal dimulai dari cabang pelacakan jarak jauh, Git mengatur cabang (khususnya entri konfigurasi branch.<name>.remotedan branch.<name>.merge) sehingga git pullakan bergabung dengan tepat dari cabang pelacakan jarak jauh.
Perilaku ini dapat diubah melalui branch.autosetupmergeflag konfigurasi global . Pengaturan yang dapat diganti dengan menggunakan --trackdan --no-trackpilihan, dan diubah kemudian menggunakan cabang git --set-upstream-to.


Dan git checkout --track origin/branchakan melakukan hal yang sama seperti 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

Ini juga akan mengatur hulu untuk ' branch'.

(Catatan: git1.8.0 akan usang git branch --set-upstreamdan menggantinya dengan git branch -u|--set-upstream-to: lihat git1.8.0-rc1 mengumumkan )


Memiliki cabang hulu yang terdaftar untuk cabang lokal akan:

  • beri tahu git untuk menunjukkan hubungan antara dua cabang di git statusdangit branch -v .
  • mengarahkan git pull tanpa argumen untuk menarik dari hulu ketika cabang baru diperiksa .

Lihat " Bagaimana Anda membuat cabang git yang ada melacak cabang jarak jauh? " Untuk informasi lebih lanjut.

VONC
sumber
1
@VonC Saya telah mencari detail kecil yang kebetulan Anda sebutkan sebagai informasi tambahan. Dalam kasus saya, saya ingin tahu mengapa saya memiliki beberapa cabang yang memungkinkan git pull, sedangkan beberapa cabang meminta cabang jarak jauh untuk menariknya. Ternyata jika Anda, pertama kali, memeriksa cabang jarak jauh yang dibuat rekan Anda, git melanjutkan dan menambah branch.<BNAME>.remote=origingitconfig lokal. Yang kemudian memungkinkan Anda untuk mengeluarkan git pull. Namun, jika Anda yang membuat cabang git checkout -b BNAME, maka git -dari saja- tidak tahu. Jadi, Anda harus menentukan remote-nya.
batilc
@batilc "Ternyata jika Anda, di pertama kali, memeriksa cabang jarak jauh yang dibuat rekan Anda,"; ya, membaca git-scm.com/docs/git-checkout , saya melihat: " If <branch>tidak ditemukan tetapi ada cabang pelacakan di persis satu remote (sebut saja <remote>) dengan nama yang cocok, perlakukan setara dengan $ git checkout -b <branch> --track <remote>/<branch>"
VonC
@VonC Saya menemukan konfigurasi yang lebih baik untuk ini. mengatur branch.autoSetupMergeuntuk alwayshanya melakukan apa yang kita bicarakan. Pengaturan ini default untuk true, yang berarti pelacakan akan dilakukan hanya ketika memeriksa cabang jauh. truetidak menyiapkan pelacakan untuk cabang yang dibuat secara lokal.
batilc
@ birilc saya setuju. Saya cenderung tidak selalu menggunakan, karena saya lebih suka mengatur pelacakan secara eksplisit, tetapi dalam kasus Anda, itu harus menjadi pengaturan yang tepat.
VonC
1
"git branch --set-upstream-to branch upstream / branch" bukan sintaks yang benar. seharusnya: "git branch --set-upstream-to upstream / branch branch"
maharvey67
33

Tidak ada perbedaan sama sekali!

1) git checkout -b branch origin/branch

Jika tidak ada --trackdan tidak --no-track, --trackdiasumsikan sebagai default. Default dapat diubah dengan pengaturan branch.autosetupmerge.

Akibatnya, 1) berperilaku seperti git checkout -b branch --track origin/branch.

2) git checkout --track origin/branch

"Sebagai kenyamanan", --tracktanpa -bmenyiratkan -bdan argumen untuk -bdiduga adalah "cabang". Tebakan didorong oleh variabel konfigurasi remote.origin.fetch.

Akibatnya, 2) berperilaku seperti git checkout -b branch --track origin/branch.

Seperti yang Anda lihat: tidak ada perbedaan.

Tapi itu menjadi lebih baik:

3) git checkout branch

juga setara dengan git checkout -b branch --track origin/branchjika "cabang" belum ada tetapi "asal / cabang" tidak 1 .


Ketiga perintah mengatur "hulu" dari "cabang" menjadi "asal / cabang" (atau gagal).

Hulu digunakan sebagai titik referensi argumen-kurang git status, git push, git mergedan dengan demikian git pull(jika dikonfigurasi seperti itu (yang merupakan default atau hampir default)).

Misalnya git statusmemberitahu Anda seberapa jauh di belakang atau di depan Anda hulu, jika ada yang dikonfigurasi.

git pushdikonfigurasikan untuk mendorong cabang saat ini ke atas secara default 2 sejak git 2.0.

1 ... dan jika "asal" adalah satu-satunya remote yang memiliki "cabang"
2 default (bernama "sederhana") juga memberlakukan untuk kedua nama cabang menjadi sama

Robert Siemer
sumber
5

Buku ini tampaknya menunjukkan bahwa perintah-perintah itu menghasilkan efek yang sama:

Kasus sederhana adalah contoh yang baru saja Anda lihat, menjalankan git checkout -b [branch] [remotename] / [branch]. Jika Anda memiliki Git versi 1.6.2 atau lebih baru, Anda juga dapat menggunakan singkatan --track:

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

Untuk mengatur cabang lokal dengan nama yang berbeda dari cabang jarak jauh, Anda dapat dengan mudah menggunakan versi pertama dengan nama cabang lokal yang berbeda:

$ git checkout -b sf origin/serverfix

Itu sangat berguna ketika penyelesaian bash atau oh-my-zsh git Anda dapat menarik origin/serverfixnama untuk Anda - cukup tambahkan --track(atau -t) dan Anda sedang dalam perjalanan.

Menepuk
sumber
-1

Anda tidak dapat membuat cabang baru dengan perintah ini

git checkout --track origin/branch

jika Anda memiliki perubahan yang tidak dipentaskan.

Berikut ini contohnya:

$ 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

Namun Anda dapat dengan mudah membuat cabang baru dengan perubahan yang tidak dipentaskan dengan git checkout -bperintah:

$ git checkout -b new-branch
Switched to a new branch 'new-branch'
M       src/App.js
hijau
sumber
perlu diingat bahwa kedua perintah dalam pertanyaan adalah untuk melacak cabang jarak jauh yang sudah ada ( origin/branch)
yorch
@ Hijau Tes yang Anda lakukan adalah dengan origin/new-branchalih - alih origin/branch. Apakah Anda sadar akan hal itu?
Robert Siemer