Mengapa memanggil cabang git --unset-upstream untuk memperbaiki?

161

Saya lebih pemula dalam hal operasi lanjutan di git. Saya memelihara blog saya menggunakan kerangka blogging Octopress . Meskipun Octopress tidak dalam pengembangan sejak 2011, itu melayani tujuan saya dengan baik dan jadi saya belum berpikir untuk mengubah apa pun sejauh ini.

FYI, blog saya di-host di Halaman Github.

Hari ini, sambil mengerjakan posting baru, git statusmenunjukkan pesan berikut:

On branch source
Your branch is based on 'origin/master', but the upstream is gone.
  (use "git branch --unset-upstream" to fixup)

Pesan yang sama diulang untuk semua perintah selanjutnya seperti git add ., git commit -m 'message'dan git push origin source.

  • Apa pesannya?
  • Apakah ada yang rusak?
  • Jika ya, apa?
  • Apakah saya perlu memperbaikinya?

Jika memungkinkan, tolong tunjukkan saya ke artikel pdf / web di mana saya bisa membaca ini dan memahaminya untuk masa depan.

Keterangan lebih lanjut:

bash-3.2$ git branch -a
* source
  remotes/octopress/2.1
  remotes/octopress/HEAD -> octopress/master
  remotes/octopress/gh-pages
  remotes/octopress/linklog
  remotes/octopress/master
  remotes/octopress/refactor_with_tests
  remotes/octopress/rubygemcli
  remotes/octopress/site
  remotes/origin/source

Tolong beri tahu saya jika ada informasi lebih lanjut. Terima kasih.

Jatin Ganhotra
sumber

Jawaban:

197

TL; Versi DR: cabang pelacak jarak jauh origin/masterdulu ada, tetapi tidak sekarang, jadi cabang lokal sourcemelacak sesuatu yang tidak ada, yang paling mencurigakan — artinya fitur Git yang berbeda tidak dapat melakukan apa pun untuk Anda — dan Git memperingatkan Anda tentang hal itu. Anda baik-baik saja tanpa memiliki fitur "pelacakan hulu" berfungsi sebagaimana dimaksud, jadi terserah Anda apakah akan mengubah apa pun.

Untuk pengambilan pengaturan upstream lainnya, lihat Mengapa saya harus "git push --set-upstream origin <branch>"?


Peringatan ini adalah hal baru di Git, muncul pertama kali di Git 1.8.5. Catatan rilis berisi hanya satu butir-butir singkat tentang hal itu:

  • "git branch -v -v" (dan "git status") tidak membedakan antara cabang yang tidak berdasarkan cabang lain, cabang yang disinkronkan dengan cabang hulu, dan cabang yang dikonfigurasi dengan hulu cabang yang sudah tidak ada.

Untuk menggambarkan apa artinya, pertama-tama Anda perlu tahu tentang "remote", "cabang pelacak jarak jauh", dan bagaimana Git menangani "melacak upstream". ( Cabang pelacak jarak jauh adalah istilah yang sangat cacat — saya sudah mulai menggunakan nama pelacak jarak jauh , yang menurut saya sedikit perbaikan. Namun, di bawah ini, saya akan menggunakan "cabang pelacak jarak jauh" untuk konsistensi dengan dokumentasi Git. )

Setiap "remote" hanyalah sebuah nama, seperti originatau octopressdalam hal ini. Tujuannya adalah untuk merekam hal-hal seperti URL lengkap tempat tempat Anda git fetchatau git pullpembaruan. Ketika Anda menggunakan 1 Git pergi ke remote itu (menggunakan URL yang disimpan) dan membawa set pembaruan yang sesuai. Itu juga mencatat pembaruan, menggunakan "cabang pelacakan jarak jauh".git fetch remote,

"Cabang pelacak jarak jauh" (atau nama pelacak jarak jauh) hanyalah rekaman nama cabang yang terakhir dilihat pada "jarak jauh". Setiap remote itu sendiri adalah repositori Git, sehingga ia memiliki cabang. Cabang-cabang di "asal" jauh direkam di repositori lokal Anda di bawah remotes/origin/. Teks yang Anda menunjukkan mengatakan bahwa ada cabang bernama sourcepada origin, dan cabang bernama 2.1, linklogdan sebagainya pada octopress.

(Cabang "normal" atau "lokal", tentu saja, hanya nama cabang yang telah Anda buat di repositori Anda sendiri.)

Terakhir, Anda dapat mengatur cabang (lokal) untuk "melacak" cabang "pelacakan jarak jauh". Setelah cabang lokal Ldiatur untuk melacak cabang pelacakan jarak jauh R, Git akan memanggil R"upstream" dan memberi tahu Anda apakah Anda "maju" dan / atau "belakang" upstream (dalam hal komitmen). Itu normal (bahkan direkomendasikan-mampu) untuk cabang lokal dan cabang pelacakan jarak jauh untuk menggunakan nama yang sama (kecuali untuk bagian awalan jarak jauh), suka sourcedan origin/source, tapi itu sebenarnya tidak perlu.

Dan dalam hal ini, itu tidak terjadi. Anda memiliki cabang lokal yang sourcemelacak cabang pelacakan jarak jauh origin/master.

Anda seharusnya tidak perlu mengetahui mekanisme yang tepat tentang bagaimana Git mengatur cabang lokal untuk melacak yang jauh, tetapi mereka relevan di bawah ini, jadi saya akan menunjukkan cara kerjanya. Kami mulai dengan nama cabang lokal Anda source,. Ada dua entri konfigurasi menggunakan nama ini, dieja branch.source.remotedan branch.source.merge. Dari output yang Anda tunjukkan, jelas bahwa keduanya diatur, sehingga Anda akan melihat yang berikut jika Anda menjalankan perintah yang diberikan:

$ git config --get branch.source.remote
origin
$ git config --get branch.source.merge
refs/heads/master

Jika disatukan, 2 ini memberi tahu Git bahwa cabang sourceAnda melacak "cabang pelacak jarak jauh" Anda origin/master,.

Tapi sekarang lihat output git branch -a, yang menampilkan semua nama cabang lokal dan pelacakan jarak jauh di repositori Anda. Nama pelacak jarak jauh tercantum di bawah remotes/... dan tidak adaremotes/origin/master . Mungkin ada, pada suatu waktu, tetapi sekarang sudah hilang.

Git memberi tahu Anda bahwa Anda dapat menghapus informasi pelacakan --unset-upstream. Ini akan menghapus keduanya branch.source.origindan branch.source.merge, dan menghentikan peringatan.

Tampaknya cukup mungkin bahwa apa yang Anda inginkan adalah beralih dari pelacakan origin/master, ke pelacakan sesuatu yang lain: mungkin origin/source, tetapi mungkin salah satu octopress/nama.

Anda dapat melakukan ini dengan git branch --set-upstream-to, 3 misalnya:

$ git branch --set-upstream-to=origin/source

(dengan asumsi Anda masih di "sumber" cabang, dan itu origin/sourceadalah hulu yang Anda inginkan — tidak ada cara bagi saya untuk mengatakan yang mana, jika ada, Anda benar-benar menginginkannya).

(Lihat juga Bagaimana Anda membuat cabang Git yang ada melacak cabang jarak jauh? )

Saya pikir cara Anda sampai di sini adalah ketika Anda pertama kali melakukan git clone, hal yang Anda kloning-dari memiliki cabang master. Anda juga memiliki cabang master, yang disetel untuk dilacak origin/master(ini adalah pengaturan standar normal untuk git). Ini berarti Anda memiliki branch.master.remotedan branch.master.mergemengatur, ke origindan refs/heads/master. Tetapi kemudian originremote Anda mengubah namanya dari mastermenjadi source. Untuk mencocokkan, saya yakin Anda juga mengubah nama lokal Anda dari mastermenjadi source. Ini mengubah nama pengaturan Anda, dari branch.master.remoteke branch.source.remotedan dari branch.master.mergeke branch.source.merge... tetapi meninggalkan yang lama nilai-nilai , sehingga branch.source.mergesekarang salah.

Pada titik inilah tautan "hulu" rusak, tetapi dalam versi Git yang lebih tua dari 1.8.5, Git tidak pernah memperhatikan pengaturan yang rusak. Sekarang Anda memiliki 1.8.5, ini menunjukkan ini.


Itu mencakup sebagian besar pertanyaan, tetapi bukan yang "harus saya perbaiki". Kemungkinan Anda telah bekerja di sekitar kehancuran selama bertahun-tahun sekarang, dengan melakukan (misalnya, ). Jika Anda terus melakukan itu, itu akan terus mengatasi masalah — jadi, tidak, Anda tidak perlu memperbaikinya. Jika Anda suka, Anda dapat menggunakan untuk menghapus hulu dan menghentikan keluhan, dan tidak memiliki cabang lokal ditandai sebagai memiliki setiap hulu sama sekali.git pull remote branchgit pull origin source--unset-upstreamsource

Maksud dari memiliki upstream adalah untuk membuat berbagai operasi lebih nyaman. Misalnya, git fetchdiikuti oleh git mergeumumnya akan "melakukan hal yang benar" jika upstream diatur dengan benar, dan git statussetelah git fetchakan memberi tahu Anda apakah repo Anda cocok dengan yang upstream, untuk cabang itu.

Jika Anda menginginkan kenyamanan, atur ulang hulu.


1git pull menggunakan git fetch, dan pada Git 1.8.4, ini (akhirnya!) Juga memperbarui informasi "cabang pelacakan jarak jauh". Dalam versi Git yang lebih lama, pembaruan tidak direkam di cabang pelacakan jarak jauh git pull, hanya dengan git fetch. Karena Git Anda harus setidaknya versi 1.8.5 ini bukan masalah bagi Anda.

2 Nah, ini ditambah garis konfigurasi saya sengaja mengabaikan yang ditemukan di bawah remote.origin.fetch. Git harus memetakan nama "gabungan" untuk mengetahui bahwa nama lokal lengkap untuk cabang jarak jauh adalah refs/remotes/origin/master. Pemetaan hampir selalu berfungsi seperti ini, jadi bisa diprediksi mastermasuk ke situ origin/master.

3 Atau, dengan git config. Jika Anda hanya ingin mengatur upstream ke origin/sourcesatu-satunya bagian yang harus diubah adalah branch.source.merge, dan git config branch.source.merge refs/heads/source akan melakukannya. Tetapi --set-upstream-tokatakan apa yang ingin Anda lakukan, daripada membuat Anda melakukannya sendiri secara manual, jadi itu "cara yang lebih baik".

torek
sumber
3
+1 untuk "Jika Anda suka, Anda dapat menggunakan --unset-upstream untuk membuat cabang lokal ditandai sebagai tidak memiliki upstream sama sekali."
BeatriceThalo
157

jawaban torek mungkin sempurna, tetapi saya hanya ingin agar catatan menyebutkan kasus lain yang berbeda dari yang dijelaskan dalam pertanyaan asli tetapi kesalahan yang sama mungkin muncul (karena dapat membantu orang lain dengan masalah yang sama):

Saya telah membuat repo kosong (baru) yang digunakan git init --barepada salah satu server saya. Kemudian saya git clonemembawanya ke ruang kerja lokal di PC saya.

Setelah melakukan satu versi pada repo lokal saya mendapatkan kesalahan itu setelah menelepon git status.

Mengikuti jawaban torek, saya mengerti bahwa yang terjadi adalah komit pertama pada repo direktori kerja lokal yang dibuat cabang "master". Tetapi pada repo jarak jauh (pada server) tidak pernah ada apa-apa, jadi bahkan tidak ada cabang "master" (remote / origin / master).

Setelah berlari git push origin masterdari repo lokal repo jarak jauh akhirnya memiliki cabang master. Ini menghentikan kesalahan muncul.

Jadi untuk menyimpulkan - orang mungkin mendapatkan kesalahan seperti itu untuk repo jarak jauh baru yang baru dengan nol komit karena tidak memiliki cabang, termasuk "master".

ElazarR
sumber
6
Ini saat ini adalah hasil pertama untuk pesan kesalahan ini On branch source Your branch is based on 'origin/master', but the upstream is gone. (use "git branch --unset-upstream" to fixup)dan, meskipun subjektif, lebih mungkin disebabkan oleh kloning repositori kosong yang sangat bagus untuk mendapatkan jawaban alternatif di sini.
Bella
2
Saya pikir itu sebabnya itu selalu ide yang baik untuk menginisialisasi repositori baru Anda dengan file README.md, bahkan jika itu adalah file kosong
Ahmed Hussein
8

Ini bisa menyelesaikan masalah Anda.

setelah melakukan perubahan, Anda dapat mengkomitnya lalu

git remote add origin https://(address of your repo) it can be https or ssh
then
git push -u origin master

Semoga ini berhasil untuk Anda.

Terima kasih

Ajay Kotnala
sumber
1
Ini memang akan membantu - alasannya dirinci dalam jawaban saya (Singkatnya - ini menciptakan cabang master yang hilang di repo jarak jauh).
ElazarR
7

Bagi saya, .git/refs/origin/mastersudah korup.

Saya melakukan yang berikut, yang memperbaiki masalah bagi saya.

rm .git/refs/remotes/origin/master
git fetch
git branch --set-upstream-to=origin/master
smremde
sumber
0

Sebenarnya torek sudah memberi tahu Anda cara menggunakan alat-alat ini jauh lebih baik daripada yang bisa saya lakukan. Namun, dalam hal ini saya pikir penting untuk menunjukkan sesuatu yang aneh jika Anda mengikuti pedoman di http://octopress.org/docs/deploying/github/ . Yaitu, Anda akan memiliki beberapa repositori github dalam pengaturan Anda. Pertama-tama satu dengan semua kode sumber untuk situs web Anda di katakan direktori $WEBSITE, dan kemudian satu dengan hanya file yang dihasilkan statis berada di $WEBSITE/_deploy. Yang lucu dari pengaturan adalah bahwa ada .gitignorefile di $WEBSITEdirektori sehingga pengaturan ini benar-benar berfungsi.

Pengantar yang cukup. Dalam hal ini kesalahan mungkin juga berasal dari repositori di _deploy.

cd _deploy

git branch -a
* master
remotes/origin/master
remotes/origin/source

Di dalam .git/configAnda biasanya perlu menemukan sesuatu seperti ini:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = [email protected]:yourname/yourname.github.io.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master

Tetapi dalam kasus Anda master cabang tidak memiliki remote.

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[remote "origin"]
    url = [email protected]:yourname/yourname.github.io.git
    fetch = +refs/heads/*:refs/remotes/origin/*

Yang dapat Anda atasi dengan:

cd _deploy
git branch --set-upstream-to=origin/master

Jadi, semuanya seperti yang dikatakan torek kepada Anda, tetapi mungkin penting untuk menunjukkan bahwa ini mungkin lebih berkaitan dengan _deploydirektori daripada akar situs web Anda.

PS: Mungkin layak menggunakan shell seperti zshdengan gitplugin untuk tidak digigit oleh hal ini di masa depan. Ini akan segera menunjukkan yang _deployberkaitan dengan repositori yang berbeda.

Anne van Rossum
sumber
0

Saya memiliki pertanyaan ini dua kali, dan itu selalu disebabkan oleh korupsi file cache git di cabang lokal saya. Saya memperbaikinya dengan menulis hash komit yang hilang ke file itu. Saya mendapat hash komit yang tepat dari server dan menjalankan perintah berikut secara lokal:

cat .git/refs/remotes/origin/feature/mybranch \
echo 1edf9668426de67ab764af138a98342787dc87fe \
>> .git/refs/remotes/origin/feature/mybranch
pengguna1106400
sumber
0

Masalah: Cabang Anda didasarkan pada 'asal / master', tetapi hulu hilang.

Solusi: cabang git --unset-hulu

reecha soni
sumber
3
Selamat datang di stackoverflow. Pertanyaannya bukan tentang bagaimana kesalahan bisa diperbaiki, dia ingin tahu mengapa kesalahan ini muncul dan jika dia harus melakukan sesuatu tentang hal itu. Harap jawab ini dalam jawaban Anda.
cronoik
0

hapus cabang lokal Anda dengan mengikuti perintah

git branch -d branch_name

Anda juga bisa melakukannya

git branch -D branch_name 

yang pada dasarnya memaksa penghapusan (bahkan jika lokal tidak digabungkan ke sumber)

Pravin
sumber