Bagaimana cara 'git pull' ke cabang yang bukan yang sekarang?


126

Ketika Anda berjalan git pulldi mastercabang, itu biasanya menarik dari origin/master. Saya berada di cabang berbeda yang dipanggil newbranch, tetapi saya perlu menjalankan perintah yang melakukan git pulldari origin/masterke mastertetapi saya tidak dapat menjalankan git checkoutuntuk mengubah cabang yang dipilih sampai setelah penarikan selesai. Apakah ada cara untuk melakukan ini?

Sebagai latar belakang, repositori menyimpan sebuah situs web. Saya telah membuat beberapa perubahan newbranchdan menerapkannya dengan mengalihkan situs web ke newbranch. Sekarang perubahan tersebut telah digabungkan ke dalam mastercabang, saya mencoba untuk mengalihkan situs web kembali ke mastercabang juga. Pada titik ini, newbranchdan origin/masteridentik, tetapi mastertertinggal origin/masterdan perlu diperbarui. Masalahnya, jika saya melakukannya dengan cara tradisional:

$ git checkout master
   # Uh oh, production website has now reverted back to old version in master
$ git pull
   # Website is now up to date again

Saya perlu mencapai hal yang sama seperti di atas ( git checkout master && git pull), tetapi tanpa mengubah direktori kerja ke revisi sebelumnya selama proses tersebut.


@phi: Saya tidak berpikir itu akan berhasil, karena saya masuk newbranchdan tidak ada apa-apa di sana untuk disimpan!
Malvineous

Saya akan mengkloning ke direktori baru, menggabungkan cabang baru menjadi master, menggabungkan master kembali ke cabang baru, lalu git pull dari tempat Anda berada. Master dan cabang baru akan sama.
aet

@aet Dia bisa melakukannya sekarang di direktori saat ini dengan melakukan git fetch; git merge origin/masterdari dalam newbranch. Tidak ada manfaatnya menggandakan seluruh salinan kedua dari repositori.
meagar


Jawaban:


5

Anda memiliki pohon kerja yang tidak ingin Anda sentuh, jadi gunakan yang lain. Clone itu murah, dibuat untuk ini.

git fetch origin master       # nice linear tree
git clone . ../wip -b master  # wip's `origin/master` is my `master`
cd ../wip                     # .
git pull origin origin/master # merge origin's origin/master
git push origin master        # job's done, turn it in.
cd ../main
rm -rf ../wip                 # wip was pushed here, wip's done

git checkout master           # payload

Masalah dengan semua jawaban lain di sini adalah, mereka tidak benar-benar melakukan tarikan. Jika Anda membutuhkan merge atau rebase yang telah Anda siapkan pull, Anda memerlukan worktree lain dan prosedur di atas. Kalau tidak, hanya git fetch; git checkout -B master origin/masterakan dilakukan.


2
Ketika Anda menjalankan, git checkout masterAnda akan memeriksa mastercabang lama karena Anda belum melakukan git pulldi mainfolder untuk menyinkronkannya dengan origin / master. Inilah yang saya coba hindari.
Malvineous

Pembayaran yang dilakukan oleh klon adalah dari master lama, tetapi checkout itu masuk ke direktori yang tidak dilihat oleh server web. Kasir master di bagian akhir adalah master yang digabungkan sepenuhnya yang didorong kembali dari penghapusan.
sampai

Pada baris 6 Anda mendorong gabungan (diperbarui) masterkembali ke origin, tetapi saya tidak percaya pembayaran akhir Anda adalah dari pembaruan ini master. Tidak ada git pullpembaruan mastercabang di maindirektori, jadi kecuali saya kehilangan sesuatu, perintah Anda tidak berbeda dengan hanya berjalan git checkout mastersendiri dan mendapatkan masterpohon lama . Jika Anda melihat lebih dekat, Anda tidak menjalankan perintah apa pun di maindirektori yang berkomunikasi ke upstream (selain baris 1, yang dijalankan sebelum Anda membuat perubahan apa pun ke repo upstream.)
Malvineous

baik, Anda bisa mencobanya di repo percobaan, atau memeriksa dokumen push.
sampai

1
@jwg dibandingkan dengan apa, please? Pastikan untuk memenuhi semua kebutuhan OP yang dinyatakan.
sampai

163

Langsung: Memperbarui dari cabang jarak jauh menjadi master cabang yang saat ini tidak diperiksa :

git fetch origin master:master

di mana asal adalah remote Anda dan Anda saat ini diperiksa di beberapa cabang misalnya dev .

Jika Anda ingin memperbarui cabang Anda saat ini selain cabang yang ditentukan sekaligus:

git pull origin master:master

4
Hm, sepertinya itu tidak selalu berhasil; Saya baru saja diminta untuk menggabungkan dengan cabang WIP saya.
underscore_d

@underscored sama untuk saya.
Greg

1
Berhasil untuk saya ... jika diminta untuk menggabungkan maka saya membayangkan ada perubahan di cabang Anda yang Anda perbarui yang tidak berkomitmen ke asalnya
skim

2
Bagaimana cara kerjanya? Itu tidak berhasil untuk saya, itu hanya mencoba untuk menggabungkan origin / master ke dalam cabang saya yang saat ini check-out.
mhogerheijde

3
Ini menarik master ke cabang saat ini. Ini jelas BUKAN apa yang diminta. Jika Anda mengubah tarik untuk mengambil, maka inilah yang diminta.
Jeff Wolski

90

Ini dijawab di sini: Gabungkan, perbarui, dan tarik cabang Git tanpa menggunakan pembayaran

# Merge local branch foo into local branch master,
# without having to checkout master first.
# Here `.` means to use the local repository as the "remote":
git fetch . foo:master

# Merge remote branch origin/foo into local branch foo,
# without having to checkout foo first:
git fetch origin foo:foo

2
Ini yang terbaik, karena berfungsi dengan perubahan lokal tanpa komitmen.
Tomasz Gandor

2
Jika Anda hanya ingin mengetahui perubahan terbaru yang akan Anda lakukan git fetch origin master:master. git fetchdengan sendirinya akan menganggap Anda bermaksud memperbarui cabang saat ini dan bukan cabang lain.
John Leidegren

2
Ini adalah jawaban yang paling sederhana dan paling langsung. Ini harus menjadi jawaban yang diterima IMO.
Keego

@JohnLeidegren - kecuali itu tidak selalu berfungsi sebagaimana mestinya. Lihat komentar untuk stackoverflow.com/a/42902058/274579 jawaban.
ysap

22

Ternyata, jawabannya sederhana saja:

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

Hal ini memungkinkan Anda untuk memperbarui mastercabang tanpa beralih untuk itu sampai setelah itu telah diperbarui.


11
Ini tidak melakukan apa yang Anda minta.
sampai

Seperti yang dikatakan oleh komentar di atas, pertanyaan yang akhirnya Anda tanyakan sebenarnya bukanlah pertanyaan yang akhirnya Anda jawab. Anda harus memperbarui pertanyaan Anda sehingga tidak terlalu spesifik tentang penggabungan ke dalam cabang tanpa memeriksanya, dan lebih banyak tentang berpindah langsung ke versi terbaru dari cabang yang tersedia di remote tanpa memeriksa versi lama terlebih dahulu.
meagar

1
Ini benar-benar jawaban yang saya cari ke sini :)
Sophistifunk

1
Bukan yang diinginkan OP, tapi bantu saya, sejujurnya.
Marcel Bro

1
@anoniim, bukan yang diinginkan OP? Maksudmu OP yang baru saja menjawab pertanyaan ini?
smac89

12

Anda khawatir tentang sesuatu yang tidak dapat diperbaiki, karena operasi Git tidak bersifat atomik. Anda akan selalu memiliki lubang di mana direktori kerja Anda berada di tengah jalan antar cabang, bahkan jika Anda memperbarui master tanpa terlebih dahulu beralih ke sana. Inilah mengapa Git bukanlah alat penerapan .

Karena Anda tidak benar-benar memasukkan kode di lingkungan produksi Anda (saya harap), Anda tidak perlu memeriksa cabang. Anda cukup melakukan a git fetchuntuk memperbarui referensi jarak jauh Anda, dan kemudian git checkout origin/mastermemindahkan direktori kerja langsung ke komit yang saat ini ditunjukkan oleh origin/master. Ini akan menempatkan Anda dalam status kepala terpisah, tetapi sekali lagi, karena Anda tidak melakukan kode, ini tidak masalah.

Ini adalah lubang terkecil yang akan Anda dapatkan, tetapi seperti yang saya katakan, lubang masih ada; checkouttidak atom.


Saya memahami batasan penggunaan git untuk penyebaran, masalahnya adalah bahwa lubang dalam kasus ini akan menjadi menit, bukan kurang dari satu detik. Ide bagus tentang check out origin/master, itu mungkin hanya melakukan trik.
Malvineous

Apa yang membuat lubang itu menjadi "menit"? Menarik data di seluruh jaringan? Lakukan saja git fetchsebelum Anda melakukan hal lain dan singkirkan transfer data yang sebenarnya.
meagar

Ini berdurasi beberapa menit karena file (sekarang) yang tidak terlacak akan ditimpa oleh komit sebelumnya. Jadi saya harus menyalin file, melakukan hal-hal git, lalu mengembalikannya. 'Menit' berasal dari kecepatan mengetik saya. (Ya, saya bisa membuat skrip tetapi itu hanya untuk menunjukkan bahwa membuat git melakukan semuanya sendiri lebih cepat.)
Malvineous

3

Anda dapat menggunakan update-ref untuk ini:

git fetch
git update-ref refs/heads/master origin/master
git checkout master

Perhatikan bahwa ini akan membuang semua komit lokal di cabang master. Dalam kasus Anda tidak akan ada jadi ini tidak apa-apa. Bagi orang lain yang mencoba melakukan ini di mana ada komit lokal, menurut saya tidak mungkin, karena penggabungan hanya dapat dijalankan di cabang saat ini.


Apakah ini setara dengan git branch --force master origin/master? Ini memaksa kepala lokal masteruntuk menunjuk ke kepala originsmaster
Keego

2

Solusi Malvineous berhasil untuk saya

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

Hanya di beri kesalahan


warning: not deleting branch 'master' that is not yet merged to
         'refs/remotes/origin/master', even though it is merged to HEAD.
error: The branch 'master' is not fully merged.
If you are sure you want to delete it, run 'git branch -D master'.

Jadi saya menjalankan dengan opsi -D

Terima kasih


0

git fetch origin master:master

  • "Menarik" (sebenarnya mengambil) master.
  • Jika Anda memiliki perubahan pada Anda masteryang belum didorong, origin/masterdigabungkan ke master Anda.
  • Jika ada konflik gabungan, Anda harus menyelesaikannya terlebih dahulu.
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.