Mengapa saya perlu melakukan `--set-upstream` sepanjang waktu?

1468

Saya membuat cabang baru di Git:

git branch my_branch

Mendorongnya:

git push origin my_branch

Sekarang katakan seseorang membuat beberapa perubahan pada server dan saya ingin menarik dari origin/my_branch. Saya lakukan:

git pull

Tapi saya mendapatkan:

You asked me to pull without telling me which branch you
want to merge with, and 'branch.my_branch.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. 'git pull <repository> <refspec>').
See git-pull(1) for details.

If you often merge with the same branch, you may want to
use something like the following in your configuration file:

    [branch "my_branch"]
    remote = <nickname>
    merge = <remote-ref>

    [remote "<nickname>"]
    url = <url>
    fetch = <refspec>

See git-config(1) for details.

Saya belajar bahwa saya dapat membuatnya bekerja dengan:

git branch --set-upstream my_branch origin/my_branch

Tetapi mengapa saya perlu melakukan ini untuk setiap cabang yang saya buat? Bukankah sudah jelas bahwa jika saya mendorong my_branchke dalam origin/my_branch, maka saya ingin menarik origin/my_branchke dalam my_branch? Bagaimana saya bisa menjadikan ini perilaku default?

Ram Rachum
sumber
21
Default untuk branch.autosetupmergeberarti bahwa konfigurasi hulu untuk cabang baru hanya secara otomatis ditetapkan ketika membuat cabang dari cabang pelacakan jarak jauh (misalnya <remote-name>/<branch-name>) (lihat git-config (1) ). Anda mungkin membuat cabang dari cabang lokal yang ada. Jika Anda secara efektif bercabang langsung dari ujung cabang jarak jauh (meskipun berada di cabang lokal), maka Anda dapat menggunakan git branch my_branch <remote-name>/<branch-name>untuk secara otomatis mengatur konfigurasi upstream.
Chris Johnsen
20
FYI, --set-upstreamopsi ini sudah tidak digunakan lagi. Anda harus menggunakan --trackatau --set-upstream-tosebagai gantinya.
Sean the Bean
139
jika --set-upstreamsudah usang, maka mungkin git devs harus menghapusnya dari pesan bantuan yang ditampilkan ketika Anda menjalankan git pushtanpa opsi dan tidak ada upstream diatur?
Christopher Hunter
17
@ChristopherHunter Sudah lebih dari setahun sejak komentar Anda dan masih mengatakan itu. Apakah ini hanya umpan balik yang ceroboh atau mungkin ada alasan teknis yang bijak untuk mempertahankannya agar tidak kita ketahui?
Konrad Viltersten
15
@ChristopherHunter git branch --set-upstreamsudah tidak digunakan lagi. git push --set-upstreamtidak.
Brian Gordon

Jawaban:

1538

Cara pintas, yang tidak bergantung pada mengingat sintaks untuk git branch --set-upstream 1 adalah melakukan:

git push -u origin my_branch

... pertama kali Anda mendorong cabang itu. Atau, untuk mendorong ke cabang saat ini ke cabang dengan nama yang sama (berguna untuk alias):

git push -u origin HEAD

Anda hanya perlu menggunakan -usatu kali, dan itu mengatur hubungan antara cabang Anda dan cabang origindi dengan cara yang sama seperti git branch --set-upstreamhalnya.

Secara pribadi, saya pikir itu hal yang baik untuk mengatur hubungan antara cabang Anda dan satu di remote secara eksplisit. Sayang sekali aturannya berbeda untuk git pushdangit pull .


1 Mungkin terdengar konyol, tapi saya sangat sering lupa untuk menentukan cabang saat ini, dengan asumsi itu adalah default - tidak, dan hasilnya paling membingungkan :)

Pembaruan 2012-10-11 : Rupanya saya bukan satu-satunya orang yang merasa mudah salah! Terima kasih kepada VonC untuk menunjukkan bahwa git 1.8.0 memperkenalkan yang lebih jelas git branch --set-upstream-to, yang dapat digunakan sebagai berikut, jika Anda berada di cabang my_branch:

git branch --set-upstream-to origin/my_branch

... atau dengan opsi pendek:

git branch -u origin/my_branch

Perubahan ini, dan alasannya, dijelaskan dalam catatan rilis untuk git 1.8.0, kandidat rilis 1 :

Memang tergoda untuk mengatakan git branch --set-upstream origin/master, tetapi itu memberitahu Git untuk mengatur cabang lokal origin/masteruntuk berintegrasi dengan cabang yang saat ini diperiksa, yang sangat tidak mungkin apa yang dimaksud pengguna. Opsi ini sudah tidak digunakan lagi; gunakan opsi baru --set-upstream-to(dengan pendek dan manis -u) sebagai gantinya.

Mark Longair
sumber
95
Perhatikan juga bahwa meskipun Anda lupa saat -upertama kali mendorong, Anda dapat menjalankan lagi dorongan dengan bendera itu dan itu akan mulai melacak.
Henrik N
70
Tak satu pun dari ini memenuhi kasus penggunaan menggunakan git push tanpa argumen. Tetap bahwa saya masih harus ingat untuk 'git push -u origin my-branch' saat memindahkan cabang baru saya ke remote untuk pertama kalinya.
Karl the Pagan
19
Saya benci mengingat sintaks itu juga, jadi saya membuat alias berikut:alias gpo="git push --set-upstream origin $(git branch | awk '/^\* / { print $2 }')"
lillialexis
99
Ini semua baik-baik saja, tapi saya masih berpikir keluhan OP itu valid. Anda memulai cabang lokal, mengerjakannya, mendorongnya ke asal untuk berbagi (tanpa argumen); mengapa itu tidak mengatur hulu? Apakah sebenarnya diinginkan karena alasan tertentu TIDAK untuk mengatur upstream saat mendorong cabang baru ke remote?
GaryO
23
Sama sekali tidak layak waktu dev. Mengapa itu tidak dilakukan secara otomatis saja?
sudo
1346

Anda dapat mewujudkannya dengan sedikit mengetik. Pertama, ubah cara kerja push Anda:

git config --global push.default current

Ini akan menyimpulkan origin my_branchbagian, sehingga Anda dapat melakukan:

git push -u

Yang mana keduanya akan membuat cabang jauh dengan nama yang sama dan melacaknya.

Zamith
sumber
4
Kenapa git dapat menyimpulkan originketika menjalankan git push -ucabang yang baru dibuat di repositori yang baru dibuat? Apakah asumsi repositori telah dikloning sehingga cabang saat ini diatur ke remote origin?
Piotr Dobrogost
73
Ini harus menjadi default. Begitu banyak hal dalam git yang bisa lebih ramah pengguna jika hanya dikirimkan dengan default yang lebih baik.
phreakhead
13
Sadarilah bahwa 'saat ini' sedikit tidak aman daripada menggunakan 'sederhana' untuk melakukan hal yang sama, lihat stackoverflow.com/questions/23918062/…
Air
30
Ya, tetapi ketika Anda mencoba, pullAnda harus menentukan dari mana. The -uset up pelacakan cabang antara asal dan repo lokal Anda.
Zamith
7
Meskipun sedikit nyaman, ini masih mengamanatkan bahwa perintah yang berbeda dijalankan untuk yang pertama dan satu push- satunya - yang mengalahkan seluruh poin dari pertanyaan ini. Singkatnya, tidak ada jawaban yang bagus. Bahwa pengembang Git bersikeras mempertahankan Awkward User eXperience (AUX) ini dalam menghadapi perbedaan pendapat masyarakat yang luas ... ... mencerahkan. Dan mengecilkan hati. (Sebagian besar mengecilkan hati.)
Cecil Curry
87

Anda bisa saja

git checkout -b my-branch origin/whatever

di tempat pertama. Jika Anda mengatur branch.autosetupmergeatau branch.autosetuprebase(favorit saya) ke always(standarnya adalah true), my-branchakan secara otomatis melacak origin/whatever.

Lihat git help config.

cdunn2001
sumber
5
Ini menghasilkan "fatal: Tidak dapat memperbarui jalur dan beralih ke cabang 'cabang saya' pada saat yang sama."
Karl the Pagan
12
Ngomong-ngomong, saya biasanya hanya git checkout -t origin/whatever, yang juga memilih whateversebagai nama cabang baru. Sangat mudah!
cdunn2001
2
@cdunn Yang ini ideal, tetapi hampir tidak konsisten. Bendera harus disebut -u/ --set-upstream.
Tobu
1
git checkout -t origin/whatevertidak berfungsi untuk saya ketika mencoba membuat cabang baru:fatal: Cannot update paths and switch to branch 'whatever' at the same time.
wisbucky
1
git checkout -b my-branch origin/whateverjuga memiliki kesalahan yang sama (saya mencoba membuat cabang baru yang tidak ada di lokal atau jarak jauh): fatal: Cannot update paths and switch to branch 'whatever' at the same time.
wisbucky
81

Ini adalah penggunaan saya yang paling umum untuk The Fuck .

$ git push
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin master

$ fuck
git push --set-upstream origin master [enter/↑/↓/ctrl+c]
Counting objects: 9, done.
...

Juga, menyenangkan untuk mengetik kata-kata umpatan di terminal Anda.

Tamlyn
sumber
Ini perlu porting ke Windows (atau setidaknya git-bash).
BrianHVB
1
nah penemuan kecil ini baru saja membuat saya senang. terima kasih
Ivan Durst
Alat luar biasa, terima kasih!
Yurii
81

Anda dapat mengatur upstream lebih sederhana dengan dua cara. Pertama saat Anda membuat cabang:

git branch -u origin/my-branch

atau setelah Anda membuat cabang, Anda dapat menggunakan perintah ini.

git push -u origin my-branch

Anda juga dapat bercabang, memeriksa dan mengatur upstream dalam satu perintah:

git checkout -b my-branch -t origin/my-branch

Preferensi pribadi saya adalah melakukan ini dalam perintah dua langkah:

git checkout -b my-branch
git push -u origin my-branch
Tzen
sumber
1
Jawaban bagus! Mengatasi kedua kasus penggunaan umum. Setelah berjalan git branch -u origin/my-branchsaya bisa berlari git pulluntuk menarik perubahan saya.
Benjamin Atkin
2
"git checkout -b my-branch -t origin / my-branch" ini tidak berfungsi jika 'origin / my-branch' belum ada.
Spongman
1
Anda sebenarnya bisa melakukannya git checkout -t origin/my-branchtanpa -b my-branch, itu hanya akan secara otomatis menyimpulkan my-branchuntuk nama cabang lokal. Namun, seperti @Spongman sebutkan, perintah ini tidak berfungsi jika origin/my-branchtidak ada terlebih dahulu.
wisbucky
Ya, akan bekerja @ sial, -t berfungsi dengan baik. Namun secara pribadi, bahkan dua tahun setelah saya menulis balasan itu, saya masih lebih suka membagi dalam dua baris dengan checkout -b dan push -u. Ini lebih eksplisit dan tidak ada kesalahan pada checkout -b ketika saya tidak memiliki remote - yang sering terjadi ketika bereksperimen :)
Tzen
2
git push -u origin/my-branchgagal untuk saya dengan fatal: 'origin/my-branch' does not appear to be a git repository. Ini bekerja:git push -u origin my-branch
stason
48

Kamu bisa menggunakan:

git config --global branch.autosetupmerge selalu

yang akan menautkan cabang hulu setiap kali Anda membuat atau checkout cabang baru.

Lihat https://felipec.wordpress.com/2013/09/01/advanced-git-concepts-the-upstream-tracking-branch/

Ini juga berfungsi dengan baik branch.autosetuprebase, jika Anda mengikuti alur kerja yang lebih fokus pada rebase, tetapi jangan gunakan ini kecuali Anda tahu apa yang Anda lakukan, karena itu akan mengubah perilaku tarik Anda menjadi rebase, yang dapat menyebabkan hasil yang aneh.

Daniel
sumber
8
Tidak berfungsi, saya masih menerima --set-upstreampesan
Dorian
2
@Dorian, Anda harus mengatur ini sebelum Anda membuat cabang. Lihat stackoverflow.com/a/9753268/263998
cdunn2001
8
tetapi ini tidak mengatur cabang pelacakan sebagai remote dengan cabang yang sama, tetapi ke cabang lokal saat ini .. jadi ketika Anda menekannya akan mencoba untuk mendorong ke cabang LOCAL Anda sebelum membuat cabang baru ..
Arnold Roa
1
Ini bahkan memiliki perilaku yang lebih aneh daripada default. Jika Anda mendasarkan pekerjaan dari cabang, itu bertindak sangat aneh.
Beefster
1
Hati - hati dengan pengaturan ini !! Setelah mengaturnya, Anda mendapatkan perilaku ini. 1. Beralih ke master. 2. Lari git checkout -b new_branch. 3. Tambahkan komit ke cabang itu. 4 git push origin new_branch.. Ini mendorong yang komit ke mastercabang asal (bukan ke cabang baru asal disebut new_branch).
stwr667
38

Omong-omong, pintasan untuk mendorong cabang saat ini ke jarak jauh dengan nama yang sama:

$ git push -u origin HEAD
djanowski
sumber
22

Saya pribadi menggunakan alias berikut ini di bash

dalam file ~ / .gitconfig

[alias]
    pushup = "!git push --set-upstream origin $(git symbolic-ref --short HEAD)"

dan dalam file ~ / .bashrc atau ~ / .zshrc

alias gpo="git pushup"
alias gpof="gpo -f"
alias gf="git fetch"
alias gp="git pull"
Amrit Shrestha
sumber
1
Saya hanya perlu hcange .gitconfig, maka saya bisa menggunakan perintah git pushupyang selalu mendorong cabang saat ini ke asal. Saya selalu bisa menggunakan git pushupalih-alih git push👍
thespacecamel
18

Jika di bawah ini tidak berfungsi:

git config --global push.default current

Anda juga harus memperbarui konfigurasi lokal proyek Anda, karena kemungkinan proyek Anda memiliki konfigurasi git lokal:

git config --local push.default current
youngrrrr
sumber
2
Lebih banyak penjelasan akan lebih bagus. Apa yang dilakukan baris pertama?
papillon
3
Jawaban ini adalah yang terasa sah. Semua yang mengusulkan alias adalah solusi bodoh. Dan yang lain membenarkan menghafal urutan perintah yang panjang sangat mengagumkan.
MarkHu
10

Anda juga dapat secara eksplisit memberi tahu git pull cabang jarak jauh mana yang akan ditarik (seperti yang disebutkan dalam pesan kesalahan):

git pull <remote-name> <remote-branch>

Namun hati-hati dengan ini: jika Anda berada di cabang yang berbeda dan melakukan tarikan eksplisit, refspec yang Anda tarik akan digabungkan ke dalam cabang yang Anda tuju!

mtbkrdave
sumber
10

Untuk apa nilainya, jika Anda mencoba melacak cabang yang sudah ada pada remote (mis. Asal / somebranch) tetapi belum memeriksanya secara lokal, Anda dapat melakukannya:

$ git checkout --track origin/somebranch

Catatan: '-t' adalah versi singkat dari opsi '--track'.

Ini mengatur asosiasi yang sama langsung dari kelelawar.

tidak biasa
sumber
5
Anda sebenarnya bisa checkout ke cabang. Jadi git checkout somebranchsetara.
Zamith
2
@Zamith Bukankah itu hanya bekerja setelah menelepon git fetchlangsung sebelumnya?
Walter Roman
1
Tidak segera, tapi ya, Anda perlu memiliki referensi ke cabang itu di repo lokal Anda, yang terjadi setiap kali Anda menelepon git fetchatau git pull. Saya tidak pernah menemukan itu menjadi masalah.
Zamith
10
git branch --set-upstream-to=origin/master<branch_name>

sumber
9

Saya menggunakan alias Git ini alih-alih menyalin / menempelkan saran dari Git setiap kali: https://gist.github.com/ekilah/88a880c84a50b73bd306

Sumber disalin di bawah (tambahkan ini ke ~/.gitconfigfile Anda ):

[alias]
  pushup = "!gitbranchname() { git symbolic-ref --short HEAD; }; gitpushupstream() { git push --set-upstream origin `gitbranchname`; }; gitpushupstream"
manroe
sumber
7

Anda dapat mengatur alias yang benar-benar bagus yang dapat menangani ini tanpa sintaks yang terlalu bertele-tele.

Saya memiliki alias berikut di ~/.gitconfig:

po = "!git push -u origin \"$(git rev-parse --abbrev-ref HEAD)\""

Setelah membuat komit pada cabang baru, Anda bisa mendorong cabang baru Anda dengan hanya mengetik perintah:

git po
123
sumber
mengapa po? push origin? apa yang terjadi jika ini dijalankan beberapa kali?
Arnold Roa
Ya, seperti dalam push push. Tidak ada yang terjadi jika dijalankan berulang kali. Saya juga memiliki git push -falias yang disetel ke git pf, jadi saya menggunakannya setelah asal sudah didorong.
123
lihat komentar djanowski , Anda dapat langsung menggunakanHEAD
arhak
3

Bagi mereka yang mencari alias yang berfungsi git pull, inilah yang saya gunakan:

alias up="git branch | awk '/^\\* / { print \$2 }' | xargs -I {} git branch --set-upstream-to=origin/{} {}"

Sekarang setiap kali Anda mendapatkan:

$ git pull
There is no tracking information for the current branch.
...

Lari saja:

$ up
Branch my_branch set up to track remote branch my_branch from origin.
$ git pull

Dan Anda baik untuk pergi

jchavannes
sumber
2

Karena git memiliki kemampuan keren untuk mendorong / menarik cabang yang berbeda ke repositori "hulu" yang berbeda. Anda bahkan dapat menggunakan repositori terpisah untuk mendorong dan menarik - pada cabang yang sama. Ini dapat membuat aliran multi-level terdistribusi, saya dapat melihat ini berguna pada proyek seperti kernel Linux. Git awalnya dibangun untuk digunakan pada proyek itu.

Sebagai akibatnya, itu tidak membuat asumsi tentang repo cabang Anda yang harus dilacak.

Di sisi lain, sebagian besar orang tidak menggunakan git dengan cara ini, jadi ini mungkin cocok untuk opsi default.

Git umumnya levelnya cukup rendah dan bisa membuat frustasi. Namun ada GUI dan seharusnya mudah untuk menulis skrip pembantu jika Anda masih ingin menggunakannya dari shell.

Rolf
sumber
2

Anda juga bisa melakukannya git push -u origin $(current_branch)

ourmaninamsterdam
sumber
0

Saya semacam ditemukan kembali legitkarena masalah ini (hanya OS X). Sekarang yang saya gunakan saat bercabang adalah dua perintah ini:

legit publish [<branch>] Menerbitkan cabang yang ditentukan ke remote. (alias:pub )

legit unpublish <branch> Menghapus cabang tertentu dari jarak jauh. (alias: unp)

SublimeGit hadir dengan legitdukungan secara default, yang membuat seluruh rutinitas percabangan semudah menekan Ctrl-b.

Benny K
sumber
0

Kami menggunakan phabricator dan tidak mendorong menggunakan git. Saya harus membuat alias bash yang berfungsi di Linux / mac

vim ~/.bash_aliases

new_branch() {
    git checkout -b "$1"
    git branch --set-upstream-to=origin/master "$1"
}

menyimpan

source ~/.bash_aliases
new_branch test #instead of git checkout -b test
git pull
om471987
sumber
0

Berikut adalah alias bash untuk git push yang aman dijalankan untuk setiap push dan secara otomatis akan beralih antara pengaturan upstream untuk push pertama dan kemudian melakukan push normal setelahnya.

alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && git push -u origin $(git symbolic-ref --short HEAD) || git push'

Pos Asli

Loren
sumber