Mengapa git status show branch mutakhir saat perubahan ada di hulu?

226

Perubahan ada di hulu di cabang yang dilacak, tetapi saat saya mengetik git status menunjukkan bahwa cabang lokal saya mutakhir. Apakah ini perilaku baru, apakah saya mengubah pengaturan konfigurasi, atau ada sesuatu yang salah?

Terima kasih untuk bantuannya.

ubuntu@host:/my/repo# git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean


ubuntu@host:/my/repo# git pull
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 11 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (11/11), done.
From bitbucket.org:my/repo
   1234567..abcdefg  master     -> origin/master
Updating 1234567..abcdefg
Fast-forward
 file1        |  1 -
 file2        | 43 +++++++++++++++++++++++++++++++++++++++++++
 file3        | 21 ++++++++++++---------
 file4        | 21 ++++++++++++---------
 4 files changed, 67 insertions(+), 19 deletions(-)
 create mode 100644 file5
GregB
sumber

Jawaban:

274

Apa statusnya memberitahu Anda adalah bahwa Anda berada di belakang wasit yang disebut origin/master sebagai ref lokal di repo lokal Anda . Dalam hal ini ref yang terjadi untuk melacak cabang di beberapa remote, dipanggil origin, tetapi statusnya tidak memberi tahu Anda apa pun tentang cabang di remote. Ini memberi tahu Anda tentang ref, yang hanya merupakan ID komit yang disimpan di sistem file lokal Anda (dalam hal ini, biasanya dalam file bernama.git/refs/remotes/origin/master di repo lokal Anda).

git pullmelakukan dua operasi; pertama-tama ia melakukan git fetchpembaruan dengan komit di repo jarak jauh (yang memperbarui origin/masterref di repo lokal Anda), lalu git mergekomit untuk menggabungkan komit-komit tersebut ke cabang saat ini.

Sampai Anda melakukan fetchlangkah (baik sendiri atau via git pull) repo lokal Anda tidak memiliki cara untuk mengetahui bahwa ada komit tambahan di hulu, dan git statushanya melihat origin/masterreferensi lokal Anda .

Ketika git statusmengatakan up-to-date, itu berarti "up-to-date dengan cabang yang dilacak oleh cabang saat ini", yang dalam hal ini berarti "up-to-date dengan referensi lokal yang disebut origin/master". Itu sama dengan "up-to-date dengan status upstream yang diambil terakhir kali kami melakukan fetch" yang tidak sama dengan "up-to-date dengan status live terbaru dari upstream".

Mengapa bisa seperti ini? Yah fetchlangkahnya adalah operasi jaringan yang berpotensi lambat dan mahal. Desain Git (dan sistem kontrol versi terdistribusi lainnya ) adalah untuk menghindari operasi jaringan jika tidak diperlukan, dan merupakan model yang sangat berbeda dengan sistem client-server tipikal yang digunakan banyak orang (walaupun seperti ditunjukkan dalam komentar di bawah, konsep Git dari "cabang pelacakan jarak jauh" yang menyebabkan kebingungan di sini tidak dibagikan oleh semua DVCS). Sangat mungkin untuk menggunakan Git offline, tanpa koneksi ke server terpusat, dan output git statusmencerminkan hal ini.

Membuat dan mengalihkan cabang (dan memeriksa statusnya) di Git seharusnya ringan, bukan sesuatu yang melakukan operasi jaringan lambat ke sistem terpusat. Asumsi ketika mendesain Git, dan git statushasilnya, adalah bahwa pengguna memahami ini (terlalu banyak fitur Git hanya masuk akal jika Anda sudah tahu cara kerja Git). Dengan adopsi Git oleh banyak dan banyak pengguna yang tidak terbiasa dengan DVCS asumsi ini tidak selalu valid.

Jonathan Wakely
sumber
79
Komentar yang terlambat tetapi saya mengalami situasi yang sama. Saya mengerti mengapa git tidak memiliki cara untuk mengetahui tentang perubahan sebelum mengambil. Tetapi kemudian seharusnya tidak mengatakan "up to date" yang memang tidak benar. Lebih baik mengatakan "tidak tahu apa yang mungkin terjadi dari jarak jauh".
Droidum
31
Mungkin ini sepenuhnya logis, tetapi sama sekali tidak masuk akal manusia. Mengapa Anda tidak merancang untuk melakukan pengambilan dan MAKA menyatakan apakah itu terbaru? Atau ubah pesan untuk memberi tahu apa yang sebenarnya dilakukannya, mis. "Cabang Anda mutakhir dengan 'asal / master' saat terakhir diperiksa di {timestamp}"? Atau bahkan hanya mengatakan, "Lakukan pengambilan untuk mengetahui apakah cabang Anda sudah mutakhir"?
Colin
25
mengapa repot-repot menampilkan pesan "Cabang Anda sudah terbaru" sama sekali? Saya tidak melihat titik dalam mengetahui status asal / master, dan jika itu seharusnya mewakili cabang master sebenarnya pada remote asal, maka jelas tidak tahu sama sekali.
whiterook6
2
@ pastullo, jadi buat alias.
Jonathan Wakely
23
Ini adalah contoh sempurna dari kegunaan Git yang mengerikan. Saya suka kekuatan dan fleksibilitasnya, tetapi hanya mengubah pesan menjadi sesuatu seperti "Cabang Anda mutakhir dengan versi lokal 'asal / master'." akan menjadi peningkatan besar. Kebingungan di sini adalah bahwa asal cabang / master (pola cocok dengan remote / cabang apa pun yang Anda gunakan) yang melacak cabang jauh.
matthewcummings516
35

Ini karena repo lokal Anda belum masuk dengan remote upstream. Agar pekerjaan ini sesuai dengan yang Anda harapkan, gunakan git fetchkemudian jalankan git statuskembali.

Ryan
sumber
7

Meskipun ini semua jawaban yang layak, saya memutuskan untuk memberikan cara saya memeriksa apakah repo lokal sesuai dengan remote, tanpa mengambil atau menarik. Untuk melihat di mana cabang saya, saya hanya menggunakan:

git remote show origin

Apa yang dilakukannya adalah mengembalikan semua cabang yang dilacak saat ini dan yang paling penting - info apakah mereka mutakhir, di depan atau di belakang yang berasal dari jauh. Setelah perintah di atas, ini adalah contoh dari apa yang dikembalikan:

  * remote origin
  Fetch URL: https://github.com/xxxx/xxxx.git
  Push  URL: https://github.com/xxxx/xxxx.git
  HEAD branch: master
  Remote branches:
    master      tracked
    no-payments tracked
  Local branches configured for 'git pull':
    master      merges with remote master
    no-payments merges with remote no-payments
  Local refs configured for 'git push':
    master      pushes to master      (local out of date)
    no-payments pushes to no-payments (local out of date)

Semoga ini bisa membantu seseorang.

Skycube
sumber
0

"asal / master" mengacu pada referensi yang mengacu pada komit HEAD cabang "asal / master". Referensi adalah nama alias yang ramah manusia untuk objek Git, biasanya objek komit. Referensi "asal / master" hanya akan diperbarui ketika Anda git pushke remote Anda ( http://git-scm.com/book/en/v2/Git-Internals-Git-References#Remotes ).

Dari dalam root proyek Anda, jalankan:

cat .git/refs/remotes/origin/master

Bandingkan ID komit yang ditampilkan dengan:

cat .git/refs/heads/master

Mereka harus sama, dan itulah sebabnya Git mengatakan mastersudah ketinggalan zamanorigin/master .

Ketika kamu berlari

git fetch origin master

Itu mengambil objek Git baru secara lokal di bawah folder .git / objek. Dan Git memperbarui .git / FETCH_HEAD sehingga sekarang, ini menunjuk ke komit terbaru dari cabang yang diambil.

Jadi untuk melihat perbedaan antara cabang lokal Anda saat ini, dan cabang yang diambil dari hulu, Anda dapat menjalankan

git diff HEAD FETCH_HEAD
Marek Stanley
sumber
1
Anda seharusnya tidak memasukkan item dalam direktori .git, itu tidak akan berfungsi dengan referensi yang penuh. Juga perilaku ambil yang Anda gambarkan adalah untuk versi git yang lebih lama.
Andrew C
bukankah origin/masterref juga diperbarui dengan mengambil, serta dorongan?
Jonathan Wakely
Benar. Saya menggunakan Git 1.8.3 sejauh ini. Saya dapat melihat memang dengan versi 2.2.1, FETCH_HEAD juga diperbarui selama pengambilan. Juga ketika datang ke pesan "Cabang Anda mutakhir dengan ..." atau "Cabang Anda di belakang ... dengan X melakukan", itu muncul hanya jika cabang lokal Anda melacak cabang terpencil yang diberikan. Untuk master untuk melacak asal / master, seseorang harus menjalankan git branch -u origin / master dari master cabang. Jika tidak ada pelacakan, Anda masih perlu menjalankan git diff.
Marek Stanley
Kalau begitu saya sarankan Anda memperbaiki pernyataan bahwa referensi '"asal / master" hanya akan diperbarui ketika Anda git push to remote Anda'
Jonathan Wakely
0

Mari lihat ke dalam git repo sampel untuk memverifikasi apakah your branch (master)adalah up to datedenganorigin/master .

Verifikasi bahwa master lokal melacak asal / master:

$ git branch -vv
* master a357df1eb [origin/master] This is a commit message

Info lebih lanjut tentang cabang master lokal:

$ git show --summary
commit a357df1eb941beb5cac3601153f063dae7faf5a8 (HEAD -> master, tag: 2.8.0, origin/master, origin/HEAD)
Author: ...
Date:   Tue Dec 11 14:25:52 2018 +0100

    Another commit message

Verifikasi apakah asal / master memiliki komit yang sama:

$ cat .git/packed-refs | grep origin/master
a357df1eb941beb5cac3601153f063dae7faf5a8 refs/remotes/origin/master

Kita dapat melihat hash yang sama di sekitar, dan aman untuk mengatakan cabang itu konsisten dengan yang jauh, setidaknya dalam repo git saat ini.

tengah lapangan
sumber
0

coba dengan git add .sebelumnyagit commit

Dejan Baric llevo3
sumber
0

Jawaban sepele belum akurat dalam beberapa kasus, seperti yang membawa saya ke sini. Saya sedang mengerjakan repo yang baru bagi saya dan saya menambahkan file yang tidak terlihat baru oleh statusnya.

Itu berakhir bahwa file cocok dengan pola dalam file .gitignore.

krustyengineer
sumber
0

dalam hal ini gunakan git add dan integrasikan semua file yang tertunda dan kemudian gunakan git commit dan kemudian git push

git add - mengintegrasikan semua file pedent

git commit - simpan komit

git push - save to repository

Airton Silveira
sumber