Saya membuat cabang lokal untuk menguji Solaris dan Sun Studio. Saya kemudian mendorong cabang ke hulu. Setelah melakukan perubahan dan mencoba mendorong perubahan:
$ git commit blake2.cpp -m "Add workaround for missing _mm_set_epi64x"
[solaris 7ad22ff] Add workaround for missing _mm_set_epi64x
1 file changed, 5 insertions(+)
$ git push
fatal: The current branch solaris has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin solaris
Mengapa saya harus melakukan sesuatu yang istimewa untuk ini?
Apakah ada kasus penggunaan yang masuk akal di mana seseorang akan membuat <branch>
, mendorong <branch>
remote, dan kemudian mengklaim komit <branch>
tidak seharusnya untuk <branch>
?
Saya mengikuti pertanyaan dan jawaban ini di Stack Overflow: Dorong cabang lokal baru ke repositori Git jarak jauh dan lacak juga . Saya menduga ini adalah contoh lain dari jawaban yang diterima tidak lengkap atau salah. Atau, ini contoh lain dari Git yang mengambil tugas sederhana dan membuatnya sulit.
Inilah tampilan pada mesin yang berbeda. Cabangnya jelas ada, jadi itu dibuat dan didorong:
$ git branch -a
alignas
* master
remotes/origin/HEAD -> origin/master
remotes/origin/alignas
remotes/origin/arm-neon
remotes/origin/det-sig
remotes/origin/master
remotes/origin/solaris
git config --add push.default current
, maka git push akan secara otomatis membuat cabang dalam repo jarak jauh jika perlu.Jawaban:
TL; DR:
git branch --set-upstream-to origin/solaris
Jawaban atas pertanyaan yang Anda ajukan — yang akan saya ulangi sedikit lagi sebagai "apakah saya harus menetapkan upstream" —adalah: tidak, Anda tidak perlu mengatur upstream sama sekali.
Jika Anda tidak memiliki upstream untuk cabang saat ini, Git mengubah perilakunya aktif
git push
, dan pada perintah lain juga.Kisah lengkap di sini panjang dan membosankan dan kembali ke sejarah sebelum Git versi 1.5. Untuk mempersingkat banyak,
git push
diterapkan dengan buruk. 1 Pada Git versi 2.0, Git sekarang memiliki tombol konfigurasi yang diejapush.default
sekarang menjadi defaultsimple
. Untuk beberapa versi Git sebelum dan sesudah 2.0, setiap kali Anda berlarigit push
, Git akan memuntahkan banyak suara yang mencoba meyakinkan Anda untuk mengaturpush.default
hanya agar bisagit push
tutup mulut.Anda tidak menyebutkan versi Git yang Anda jalankan, atau apakah Anda telah mengonfigurasi
push.default
, jadi kami harus menebak. Dugaan saya adalah bahwa Anda menggunakan Git versi 2-point-something, dan Anda telah mengaturpush.default
untuksimple
membuatnya tutup mulut. Tepatnya versi Git yang Anda miliki, dan bagaimana jika apa pun yang Andapush.default
tetapkan, memang penting, karena sejarah yang panjang dan membosankan itu, tetapi pada akhirnya, fakta bahwa Anda mendapatkan keluhan lain dari Git menunjukkan bahwa Git Anda adalah dikonfigurasi untuk menghindari salah satu kesalahan dari masa lalu.Apa itu hulu?
Sebuah hulu hanya nama cabang lain, biasanya cabang terpencil-pelacakan, terkait dengan (biasa, lokal) cabang.
Setiap cabang memiliki opsi untuk memiliki satu (1) set upstream. Artinya, setiap cabang memiliki hulu, atau tidak memiliki hulu. Tidak ada cabang yang dapat memiliki lebih dari satu hulu.
Hulu harus , tetapi tidak harus, cabang yang valid (apakah seperti pelacakan jarak jauh atau seperti lokal ). Artinya, jika cabang B saat ini memiliki U hulu , harus bekerja. Jika tidak berfungsi — jika mengeluh bahwa U tidak ada — maka sebagian besar Git bertindak seolah-olah hulu tidak disetel sama sekali. Beberapa perintah, seperti , akan menampilkan pengaturan hulu tetapi menandainya sebagai "hilang".
origin/B
master
git rev-parse U
git branch -vv
Apa bagusnya sebuah hulu?
Jika Anda
push.default
diatur kesimple
atauupstream
, pengaturan hulu akan membuatgit push
, digunakan tanpa argumen tambahan, hanya berfungsi.Itu saja — hanya itu gunanya
git push
. Tapi itu cukup signifikan, karenagit push
merupakan salah satu tempat di mana kesalahan ketik yang sederhana menyebabkan sakit kepala utama.Jika Anda
push.default
diatur kenothing
,,matching
ataucurrent
, mengatur upstream tidak melakukan apa pun untukgit push
.(Semua ini mengasumsikan versi Git Anda setidaknya 2.0.)
Hulu mempengaruhi
git fetch
Jika Anda menjalankan
git fetch
tanpa argumen tambahan, Git mencari tahu dari jarak jauh mana dengan berkonsultasi dengan hulu cabang saat ini. Jika upstream adalah cabang pelacakan jarak jauh, Git mengambil dari jarak jauh itu. (Jika upstream tidak disetel atau cabang lokal, Git mencoba mengambilorigin
.)Hulu mempengaruhi
git merge
dangit rebase
jugaJika Anda menjalankan
git merge
ataugit rebase
tanpa argumen tambahan, Git menggunakan hulu cabang saat ini. Jadi itu memperpendek penggunaan dua perintah ini.Hulu mempengaruhi
git pull
Anda seharusnya tidak pernah menggunakan 2
git pull
, tetapi jika Anda melakukannya,git pull
gunakan pengaturan hulu untuk mencari tahu dari mana remote untuk mengambil, dan kemudian cabang mana untuk bergabung atau rebase dengan. Yaitu,git pull
melakukan hal yang sama dengangit fetch
— karena itu benar-benar berjalangit fetch
— dan kemudian melakukan hal yang sama dengangit merge
ataugit rebase
, karena itu benar-benar berjalangit merge
ataugit rebase
.(Anda biasanya hanya perlu melakukan dua langkah ini secara manual, setidaknya sampai Anda cukup mengenal Git sehingga ketika salah satu langkah gagal, yang nantinya akan, Anda mengenali apa yang salah dan tahu apa yang harus dilakukan tentang hal itu.)
Hulu mempengaruhi
git status
Ini mungkin sebenarnya yang paling penting. Setelah Anda memiliki set upstream,
git status
dapat melaporkan perbedaan antara cabang Anda saat ini dan upstreamnya, dalam hal komitmen.Jika, seperti halnya kasus normal, Anda berada di cabang
B
dengan hulu yang diatur ke , dan Anda menjalankan , Anda akan segera melihat apakah Anda memiliki komit yang dapat Anda dorong, dan / atau komit yang dapat Anda gabungkan atau rebond ke.origin/B
git status
Ini karena
git status
menjalankan:git rev-list --count @{u}..HEAD
: berapa banyak komitmen yang Anda milikiB
yang tidak aktif ?origin/B
git rev-list --count HEAD..@{u}
: berapa banyak komitmen yang Anda miliki yang tidak aktif ?origin/B
B
Mengatur upstream memberi Anda semua hal ini.
Kenapa
master
sudah memiliki set upstream?Saat Anda pertama kali mengkloning dari jarak jauh, menggunakan:
atau serupa, langkah terakhir yang dilakukan Git adalah, pada dasarnya
git checkout master
,. Ini memeriksa cabang lokalmaster
Anda — hanya saja Anda tidak memiliki cabang lokalmaster
.Di sisi lain, Anda tidak memiliki cabang terpencil-pelacakan bernama
origin/master
, karena Anda hanya kloning itu.Git menebak bahwa Anda harus berarti: "membuat saya lokal baru
master
yang menunjuk ke yang sama komit sebagai remote trackingorigin/master
, dan, sementara Anda berada di itu, mengatur hulu untukmaster
keorigin/master
."Ini terjadi untuk setiap cabang Anda
git checkout
yang belum Anda miliki. Git menciptakan cabang dan membuatnya "melacak" (miliki sebagai upstream) cabang pelacakan jarak jauh yang sesuai.Tetapi ini tidak berfungsi untuk cabang baru , yaitu cabang yang belum memiliki cabang pelacak jarak jauh .
Jika Anda membuat cabang baru :
masih ada, belum
origin/solaris
. Lokal Andasolaris
tidak dapat melacak cabang pelacakan jarak jauhorigin/solaris
karena tidak ada.Saat Anda pertama kali mendorong cabang baru:
yang menciptakan
solaris
padaorigin
, dan karenanya juga menciptakanorigin/solaris
dalam repositori Git Anda sendiri. Tapi sudah terlambat: Anda sudah memiliki lokalsolaris
yang tidak memiliki hulu . 3Bukankah seharusnya Git hanya menetapkan itu, sekarang, sebagai upstream secara otomatis?
Mungkin. Lihat "diimplementasikan dengan buruk" dan catatan kaki 1. Sulit untuk berubah sekarang : Ada jutaan 4 skrip yang menggunakan Git dan beberapa mungkin tergantung pada perilaku saat ini. Mengubah perilaku memerlukan rilis besar baru, nag-ware untuk memaksa Anda untuk mengatur beberapa bidang konfigurasi, dan sebagainya. Singkatnya, Git adalah korban dari kesuksesannya sendiri: kesalahan apa pun yang ada di dalamnya, hari ini, hanya dapat diperbaiki jika perubahan itu sebagian besar tidak terlihat, jelas jauh lebih baik, atau dilakukan secara perlahan seiring waktu.
Faktanya adalah, tidak hari ini, kecuali Anda menggunakan
--set-upstream
atau-u
selamagit push
. Itulah yang disampaikan pesan itu kepada Anda.Anda tidak harus melakukannya seperti itu. Yah, seperti yang kami sebutkan di atas, Anda tidak harus melakukannya sama sekali, tetapi katakanlah Anda menginginkan hulu. Anda telah membuat cabang
solaris
padaorigin
, melalui dorongan sebelumnya, dan seperti yanggit branch
ditunjukkan output Anda, Anda sudah memilikiorigin/solaris
dalam repositori lokal Anda.Anda hanya tidak mengaturnya sebagai hulu untuk
solaris
.Untuk mengaturnya sekarang, daripada selama dorongan pertama, gunakan
git branch --set-upstream-to
. The--set-upstream-to
sub-perintah mengambil nama dari setiap cabang yang ada, sepertiorigin/solaris
, dan menetapkan hulu cabang saat ini untuk cabang lainnya.Itu saja — itu saja yang dilakukannya — tetapi semua implikasi itu disebutkan di atas. Ini berarti Anda hanya bisa berlari
git fetch
, melihat sekeliling, lalu berlarigit merge
ataugit rebase
jika perlu, kemudian membuat komitmen baru dan berlarigit push
, tanpa banyak kerumitan-sekitar tambahan.1 Agar adil, tidak jelas saat itu bahwa implementasi awal rawan kesalahan. Itu hanya menjadi jelas ketika setiap pengguna baru melakukan kesalahan yang sama setiap saat. Sekarang "kurang miskin", yang tidak berarti "hebat".
2 "Tidak pernah" sedikit kuat, tetapi saya menemukan bahwa pemula Git memahami banyak hal dengan lebih baik ketika saya memisahkan langkah-langkahnya, terutama ketika saya bisa menunjukkan kepada mereka apa yang
git fetch
sebenarnya dilakukan, dan mereka kemudian dapat melihat apa yang akangit merge
ataugit rebase
akan dilakukan selanjutnya.3 Jika Anda menjalankan yang pertama
git push
sebagaigit push -u origin solaris
—yaitu, jika Anda menambahkan-u
bendera — Git akan ditetapkanorigin/solaris
sebagai hulu untuk cabang Anda saat ini jika (dan hanya jika) dorongan berhasil. Jadi, Anda harus memasok-u
pada dorongan pertama . Bahkan, Anda dapat memasoknya pada sembarang dorongan kemudian, dan itu akan mengatur atau mengubah hulu pada saat itu. Tapi saya pikirgit branch --set-upstream-to
lebih mudah, jika Anda lupa.4 Diukur dengan metode Austin Powers / Dr Evil dengan hanya mengatakan "satu MILLLL-YUN".
sumber
--set-upstream /dev/null
? Mengapa beban didorong ke kasus umum? Saya benar-benar tidak mengerti beberapa keputusan teknis dan kegunaan ini.git push -u
, tapi itu benar-benar tampak sepertigit push -u
harus menjadi default, atau setidaknya default jika tidak ada hulu belum , dan harus adagit push --no-set-upstream
ketika tidak ada saat ini merupakan hulu dan Anda ingin menyimpan seperti itu (untuk alasan apa pun yang tidak bisa dipahami :-)).git config --add push.default current
, maka git push akan secara otomatis membuat cabang dalam repo jarak jauh jika perlu.Perbedaan antara
git push origin <branch>
dan
git push --set-upstream origin <branch>
keduanya mendorong dengan baik ke repositori jarak jauh, tetapi saat Anda menariknya Anda melihat perbedaannya.
Jika Anda melakukannya:
git push origin <branch>
saat menarik, Anda harus melakukan:
git pull origin <branch>
Tetapi jika Anda melakukannya:
git push --set-upstream origin <branch>
maka, saat menarik, Anda hanya perlu melakukan:
git pull
Jadi menambahkan di
--set-upstream
memungkinkan untuk tidak harus menentukan cabang mana yang ingin Anda tarik dari setiap waktu yang Anda lakukangit pull
.sumber
Perintah pada dasarnya penuh adalah seperti
git push <remote> <local_ref>:<remote_ref>
. Jika Anda menjalankannya sajagit push
, git tidak tahu apa yang harus dilakukan kecuali Anda telah membuat konfigurasi yang membantu git untuk membuat keputusan. Dalam repo git, kita dapat mengatur beberapa remote. Kami juga dapat mendorong ref lokal ke ref jarak jauh. Perintah penuh adalah cara paling mudah untuk melakukan push. Jika Anda ingin mengetik lebih sedikit kata, Anda harus mengkonfigurasi terlebih dahulu, seperti --set-upstream.sumber