Bagaimana Saya 'git fetch' dan 'git merge' dari Remote Tracking Branch (seperti 'git pull')

111

Saya telah menyiapkan beberapa cabang pelacakan jarak jauh di git, tetapi sepertinya saya tidak pernah dapat menggabungkannya ke cabang lokal setelah saya memperbaruinya dengan 'git fetch'.

Misalnya, saya memiliki cabang jarak jauh yang disebut 'an-other-branch'. Saya mengaturnya secara lokal sebagai cabang pelacakan menggunakan

git branch --track an-other-branch origin/an-other-branch

Sejauh ini baik. Tetapi jika cabang itu diperbarui (biasanya oleh saya memindahkan mesin dan melakukan dari mesin itu), dan saya ingin memperbaruinya di mesin asli, saya mengalami masalah dengan fetch / merge:

git fetch origin an-other-branch
git merge origin/an-other-branch

Setiap kali saya melakukan ini, saya mendapatkan pesan 'Sudah up-to-date' dan tidak ada yang bergabung.

Namun, a

git pull origin an-other-branch

selalu perbarui seperti yang Anda harapkan.

Juga, menjalankan git diff

git diff origin/an-other-branch

menunjukkan bahwa ada perbedaan, jadi menurut saya sintaks saya salah.

Apa yang saya lakukan salah?

EDIT [2010-04-09]: Saya telah memeriksa beberapa kali, dan saya jelas tidak berada di cabang yang berbeda. Haruskah 'git fetch' saya yang diikuti dengan 'git merge' (seperti yang ditunjukkan di atas) harus melakukan hal yang sama persis dengan git pull? Saya akan mendapatkan beberapa alur kerja yang menunjukkan hasil dari status git dll.

kaybenleroll
sumber

Jawaban:

170

Anda tidak mengambil cabang, Anda mengambil seluruh jarak jauh:

git fetch origin
git merge origin/an-other-branch
Gareth
sumber
8
Lebih detail: git fetch origin an-other-branchmenyimpan tip yang diambil FETCH_HEAD, tetapi tidak origin/an-other-branch(yaitu 'cabang pelacakan jarak jauh' biasa). Jadi, seseorang dapat melakukannya git fetch origin an-other-branch && git merge FETCH_HEAD, tetapi melakukannya seperti yang dikatakan @Gareth lebih baik (atau cukup gunakan git pull ).
Chris Johnsen
jadi jika origin memiliki 1000 cabang, Anda akan menjadi cabang remote untuk semuanya?
Gauthier
4
Tentu. Jika saya telah menambahkan repositori jarak jauh dengan 1000 cabang ke milik saya, dan saya bertanya cabang apa yang dimiliki remote, lebih baik berikan saya semua 1000
Gareth
akan git merge origin/an-other-branchbergabung origin/an-other-branchke semua cabang lokal yang diatur untuk melacaknya? bagaimana cara menggabungkan menjadi hanya satu cabang lokal?
amfibi
1
Jadi apa yang git pull(tanpa argumen) lakukan - cabang mana yang digabungkan? Apakah itu menggabungkan cabang pelacakan jarak jauh yang sesuai dengan cabang saat ini ?
The Red Pea
69

Memilih hanya satu cabang: fetch/ merge vs. pull

Orang sering menyarankan Anda untuk memisahkan "pengambilan" dari "penggabungan". Mereka malah mengatakan:

    git pull remoteR branchB

melakukan hal ini:

    git fetch remoteR
    git merge remoteR branchB

Apa yang tidak mereka sebutkan adalah bahwa perintah fetch seperti itu sebenarnya akan mengambil semua cabang dari repo jarak jauh, yang bukan merupakan fungsi dari perintah pull itu. Jika Anda memiliki ribuan cabang di repo jarak jauh, tetapi Anda tidak ingin melihat semuanya, Anda dapat menjalankan perintah yang tidak jelas ini:

    git fetch remoteR refs/heads/branchB:refs/remotes/remoteR/branchB
    git branch -a  # to verify
    git branch -t branchB remoteR/branchB

Tentu saja, itu sangat sulit untuk diingat, jadi jika Anda benar-benar ingin menghindari pengambilan semua cabang, lebih baik mengubah Anda .git/configseperti yang dijelaskan di ProGit.

Hah?

Penjelasan terbaik dari semua ini ada di Bab 9-5 dari ProGit, Git Internals - The Refspec ( atau via github ). Itu sangat sulit ditemukan melalui Google.

Pertama, kita perlu memperjelas beberapa terminologi. Untuk pelacakan cabang jarak jauh, biasanya ada 3 cabang berbeda yang harus diperhatikan:

  1. Cabang di repo jarak jauh: refs/heads/branchBdi dalam repo lainnya
  2. Cabang pelacakan jarak jauh Anda : refs/remotes/remoteR/branchBdi repo Anda
  3. Cabang Anda sendiri: refs/heads/branchBdi dalam repo Anda

Cabang pelacakan jarak jauh (dalam refs/remotes) bersifat hanya baca. Anda tidak mengubahnya secara langsung. Anda mengubah cabang Anda sendiri, dan kemudian Anda mendorong ke cabang yang sesuai di repo jarak jauh. Hasilnya tidak tercermin dalam Anda refs/remotessampai setelah penarikan atau pengambilan yang sesuai. Perbedaan itu sulit bagi saya untuk memahami dari halaman manual git, terutama karena cabang lokal ( refs/heads/branchB) dikatakan "melacak" cabang pelacakan jarak jauh saat .git/configmendefinisikan branch.branchB.remote = remoteR.

Pikirkan 'refs' sebagai petunjuk C ++. Secara fisik, mereka adalah file yang berisi SHA-digest, tetapi pada dasarnya mereka hanyalah penunjuk ke dalam pohon komit. git fetchakan menambahkan banyak node ke commit-tree Anda, tetapi bagaimana git memutuskan pointer apa yang akan dipindahkan agak rumit.

Seperti yang disebutkan dalam jawaban lain , keduanya juga tidak

    git pull remoteR branchB

maupun

    git fetch remoteR branchB

akan bergerak refs/remotes/branches/branchB, dan yang terakhir pasti tidak bisa bergerak refs/heads/branchB. Namun, keduanya bergerak FETCH_HEAD. (Anda dapat catsalah satu dari file-file ini di dalam .git/untuk melihat kapan mereka berubah.) Dan git mergeakan merujuk ke FETCH_HEAD, saat mengatur MERGE_ORIG, dll.

cdunn2001
sumber
1
Tahukah Anda bahwa tautan Anda ke Git Internals adalah tautan ke pertanyaan yang sama?
Shahbaz
9

Apakah Anda yakin Anda berada di lokal an-other-branchsaat Anda menggabungkan?

git fetch origin an-other-branch
git checkout an-other-branch
git merge origin/an-other-branch

The penjelasan lain :

semua perubahan dari cabang yang Anda coba gabungkan telah digabungkan ke cabang tempat Anda berada.
Lebih khusus lagi ini berarti bahwa cabang yang Anda coba gabungkan adalah induk dari cabang Anda saat ini

jika Anda mendahului repo jarak jauh dengan satu komit, itu adalah repo jarak jauh yang kedaluwarsa, bukan Anda.

Tetapi dalam kasus Anda, jika git pullberhasil, itu berarti Anda tidak berada di cabang yang benar.

VonC
sumber
3

Git pull sebenarnya adalah alat kombo: ia menjalankan git fetch (mendapatkan perubahan) dan git merge (menggabungkannya dengan salinan Anda saat ini)

Apakah Anda yakin Anda berada di cabang yang benar?

RDL
sumber
Saya pikir OP di diff. cabang, kebetulan saya.
Chaklader Asfak Arefe
1

ini adalah perintahnya:

git fetch origin
git merge origin/somebranch somebranch

jika Anda melakukan ini di baris kedua:

git merge origin somebranch

itu akan mencoba untuk menggabungkan master lokal ke dalam cabang Anda saat ini.

Pertanyaannya, seperti yang saya pahami, apakah Anda sudah diambil secara lokal dan sekarang ingin menggabungkan cabang Anda ke yang terbaru dari cabang yang sama .

pengguna1524957
sumber