Saya mengerjakan proyek yang memiliki 2 cabang, A dan B. Saya biasanya bekerja di cabang A, dan menggabungkan hal-hal dari cabang B. Untuk penggabungan, saya biasanya akan melakukan:
git merge origin/branchB
Namun, saya juga ingin menyimpan salinan cabang B lokal, karena saya kadang-kadang memeriksa cabang tanpa terlebih dahulu bergabung dengan cabang saya A. Untuk ini, saya akan melakukan:
git checkout branchB
git pull
git checkout branchA
Apakah ada cara untuk melakukan hal di atas dalam satu perintah, dan tanpa harus berganti cabang bolak-balik? Haruskah saya gunakan git update-ref
untuk itu? Bagaimana?
git
git-merge
git-pull
git-checkout
charles
sumber
sumber
--no-ff
opsi, yang menyebabkan komitmen gabungan dicatat pula. Jika Anda tertarik pada hal itu, jawaban saya di sana menunjukkan bagaimana Anda bisa melakukan itu - tidak sekuat jawaban saya di sini, tetapi kekuatan keduanya pasti bisa digabungkan.Jawaban:
Jawaban Singkat
Selama Anda melakukan penggabungan maju-cepat , maka Anda bisa menggunakannya
Contoh:
Sementara jawaban Amber juga akan berfungsi dalam kasus fast-forward, menggunakan
git fetch
dengan cara ini sebagai gantinya sedikit lebih aman daripada hanya memindahkan-paksa referensi cabang, karenagit fetch
secara otomatis akan mencegah non-fast-forward tanpa disengaja asalkan Anda tidak menggunakannya+
dalam refspec.Jawaban Panjang
Anda tidak dapat menggabungkan cabang B menjadi cabang A tanpa memeriksa A terlebih dahulu jika itu akan menghasilkan penggabungan non-maju cepat. Ini karena copy pekerjaan diperlukan untuk menyelesaikan potensi konflik.
Namun, dalam kasus penggabungan maju-cepat, ini dimungkinkan , karena penggabungan tersebut tidak pernah dapat mengakibatkan konflik, menurut definisi. Untuk melakukan ini tanpa memeriksa cabang terlebih dahulu, Anda dapat menggunakan
git fetch
dengan refspec.Berikut adalah contoh pemutakhiran
master
(melarang perubahan tidak-maju-cepat) jika Anda memiliki cabang lain yangfeature
diperiksa:Casing penggunaan ini sangat umum, sehingga Anda mungkin ingin membuat alias untuknya di file konfigurasi git Anda, seperti ini:
Apa yang dilakukan alias ini adalah sebagai berikut:
git checkout HEAD
: ini membuat copy pekerjaan Anda menjadi kondisi kepala terpisah. Ini berguna jika Anda ingin memperbaruimaster
sementara Anda telah check-out. Saya pikir itu perlu dilakukan karena kalau tidak referensi cabang untukmaster
tidak akan bergerak, tapi saya tidak ingat apakah itu benar-benar tepat di luar kepala saya.git fetch upstream master:master
: ini memajukan lokal Andamaster
ke tempat yang sama denganupstream/master
.git checkout -
periksa cabang yang sebelumnya Anda check-out (itulah yang-
dilakukan dalam hal ini).Sintaksis
git fetch
untuk (tidak) penggabungan maju cepatJika Anda ingin
fetch
perintah gagal jika pembaruan tidak maju, maka Anda cukup menggunakan refspec dari formulirJika Anda ingin memperbolehkan pembaruan yang tidak maju, maka Anda menambahkan a di
+
bagian depan refspec:Perhatikan bahwa Anda dapat meneruskan repo lokal Anda sebagai parameter "jarak jauh" menggunakan
.
:Dokumentasi
Dari
git fetch
dokumentasi yang menjelaskan sintaks ini (penekanan pada saya):Lihat juga
Dapatkan checkout dan bergabung tanpa menyentuh pohon yang berfungsi
Penggabungan tanpa mengubah direktori kerja
sumber
git checkout --quiet HEAD
adalahgit checkout --quiet --detach
pada Git 1.7.5.git fetch . origin/foo:foo
untuk memperbarui foo lokal saya ke asal / foo lokal sayagit checkout -
triknya! Semudahcd -
.Tidak, tidak ada. Checkout cabang target diperlukan untuk memungkinkan Anda menyelesaikan konflik, antara lain (jika Git tidak dapat menggabungkannya secara otomatis).
Namun, jika penggabungan adalah salah satu yang akan maju cepat, Anda tidak perlu memeriksa cabang target, karena Anda sebenarnya tidak perlu menggabungkan apa pun - yang harus Anda lakukan hanyalah memperbarui cabang untuk menunjuk ke ref kepala baru. Anda dapat melakukan ini dengan
git branch -f
:Akan memperbarui
branch-b
ke titik ke kepalabranch-a
.The
-f
pilihan singkatan--force
, yang berarti Anda harus berhati-hati saat menggunakannya.sumber
git reset
hanya berfungsi pada cabang yang saat ini ditutup.git fetch upstream branch-b:branch-b
(diambil dari jawaban ini ).git fetch <remote> B:A
, di mana B dan A adalah cabang yang benar-benar berbeda, tetapi B dapat maju cepat digabungkan menjadi A. Anda juga dapat meneruskan repositori lokal Anda sebagai "remote" menggunakan.
sebagai alias jarak jauh:git fetch . B:A
.branch -f
bisa berbahaya, seperti yang Anda tunjukkan. Jadi jangan gunakan itu! Gunakanfetch origin branchB:branchB
, yang akan gagal dengan aman jika penggabungan tidak maju cepat.Seperti kata Amber, penggabungan maju cepat adalah satu-satunya kasus di mana Anda bisa melakukan ini. Penggabungan lain yang mungkin perlu melalui seluruh penggabungan tiga arah, menerapkan tambalan, menyelesaikan konflik - dan itu berarti perlu ada file di sekitar.
Saya kebetulan memiliki skrip di sekitar yang saya gunakan untuk persis ini: melakukan penggabungan maju cepat tanpa menyentuh pohon kerja (kecuali jika Anda menggabungkan ke HEAD). Agak panjang, karena setidaknya sedikit kuat - memeriksa untuk memastikan bahwa penggabungan akan menjadi maju cepat, kemudian melakukan itu tanpa memeriksa cabang, tetapi menghasilkan hasil yang sama seperti jika Anda punya - Anda melihat
diff --stat
ringkasan perubahan, dan entri di reflog persis seperti penggabungan maju cepat, alih-alih "reset" yang Anda dapatkan jika Anda gunakanbranch -f
. Jika Anda nama itugit-merge-ff
dan menjatuhkannya dalam direktori bin Anda, Anda dapat menyebutnya sebagai perintah git:git merge-ff
.PS Jika ada yang melihat masalah dengan skrip itu, silakan komentar! Itu adalah pekerjaan menulis dan melupakan, tetapi saya akan senang untuk memperbaikinya.
sumber
# or git branch -f localbranch remote/remotebranch
untuk mengingatkan saya pada sumber dan opsinya. Berikan komentar Anda pada tautan lain, +1."$branch@{u}"
sebagai komite untuk bergabung untuk mendapatkan cabang upstream (dari kernel.org/pub/software/scm/git/docs/gitrevisions.html )Anda hanya bisa melakukan ini jika penggabungan adalah maju cepat. Jika tidak, maka git perlu memeriksa file-nya agar dapat digabungkan!
Untuk melakukannya hanya untuk maju cepat :
di mana
<commit>
komit diambil, yang ingin Anda maju cepat. Ini pada dasarnya seperti menggunakangit branch -f
untuk memindahkan cabang, kecuali itu juga mencatatnya di reflog seolah-olah Anda benar-benar melakukan penggabungan.Tolong, tolong, tolong jangan lakukan ini untuk sesuatu yang bukan fast-forward, atau Anda hanya akan mengatur ulang cabang Anda ke komit lainnya. (Untuk memeriksa, lihat apakah
git merge-base <branch> <commit>
memberikan SHA1 cabang.)sumber
git merge-base --is-ancestor <A> <B>
. "B" menjadi hal yang perlu digabung menjadi "A". Contohnya adalah A = master dan B = mengembangkan, memastikan pengembangan cepat-maju ke master. Catatan: Ada dengan 0 jika tidak ff-mampu, ada dengan 1 jika itu.Dalam kasus Anda, Anda dapat menggunakan
yang melakukan apa yang Anda inginkan (dengan asumsi penggabungan adalah maju cepat). Jika cabang tidak dapat diperbarui karena memerlukan penggabungan non-maju cepat, maka ini gagal dengan pesan.
Bentuk pengambilan ini juga memiliki beberapa opsi yang lebih berguna:
Catatan yang
<remote>
bisa menjadi repositori lokal , dan<sourceBranch>
bisa menjadi cabang pelacakan. Jadi Anda dapat memperbarui cabang lokal, meskipun tidak dicentang, tanpa mengakses jaringan .Saat ini, akses server hulu saya adalah melalui VPN yang lambat, jadi saya terhubung secara berkala,
git fetch
untuk memperbarui semua remote, dan kemudian memutuskan sambungan. Kemudian jika, katakanlah, master jarak jauh telah berubah, saya bisa melakukannyauntuk memperbarui master lokal saya dengan aman, meskipun saya saat ini memiliki beberapa cabang lain yang sudah diperiksa. Tidak diperlukan akses jaringan.
sumber
Cara lain, yang diakui cukup kasar adalah dengan hanya menciptakan kembali cabang:
Ini membuang cabang yang sudah ketinggalan zaman lokal dan membuat ulang cabang dengan nama yang sama, jadi gunakan dengan hati-hati ...
sumber
Anda dapat mengkloning repo dan melakukan penggabungan dalam repo baru. Pada sistem file yang sama, ini akan menggunakan hardlink daripada menyalin sebagian besar data. Selesai dengan menarik hasilnya ke dalam repo asli.
sumber
Masukkan git-forward-merge :
https://github.com/schuyler1d/git-forward-merge
Hanya berfungsi untuk penggabungan otomatis, jika ada konflik Anda perlu menggunakan penggabungan biasa.
sumber
Untuk banyak kasus (seperti penggabungan), Anda bisa menggunakan cabang jarak jauh tanpa harus memperbarui cabang pelacakan lokal. Menambahkan pesan di reflog terdengar seperti berlebihan dan akan menghentikannya lebih cepat. Untuk membuatnya lebih mudah untuk dipulihkan, tambahkan berikut ini ke konfigurasi git Anda
Kemudian ketik
untuk melihat riwayat terbaru untuk cabang Anda
sumber
[core]
tidak boleh[user]
? (dan ini secara default aktif, untuk repo dengan ruang kerja (yaitu non-telanjang)Saya menulis fungsi shell untuk use case serupa yang saya temui setiap hari pada proyek. Ini pada dasarnya adalah jalan pintas untuk memperbarui cabang lokal dengan cabang umum seperti pengembangan sebelum membuka PR, dll.
glmh
("git pull dan gabung di sini") akan secara otomatischeckout branchB
,pull
yang terbaru, ulangcheckout branchA
, danmerge branchB
.Tidak membahas kebutuhan untuk menyimpan salinan branchA lokal, tetapi dapat dengan mudah dimodifikasi untuk melakukannya dengan menambahkan langkah sebelum memeriksa branchB. Sesuatu seperti...
Untuk penggabungan maju cepat sederhana, ini melompati ke prompt pesan komit.
Untuk penggabungan non-maju, ini menempatkan cabang Anda dalam keadaan resolusi konflik (Anda mungkin perlu melakukan intervensi).
Untuk mengatur, menambah
.bashrc
atau.zshrc
, dll:Pemakaian:
sumber
Cara lain untuk melakukan ini secara efektif adalah:
Karena ini adalah huruf kecil
-d
, itu hanya akan menghapusnya jika data masih ada di suatu tempat. Ini mirip dengan jawaban @ kkoehne kecuali itu tidak memaksa. Karena-t
itu akan mengatur remote lagi.Saya memiliki kebutuhan yang sedikit berbeda dari OP, yaitu membuat cabang fitur baru mati
develop
(ataumaster
), setelah menggabungkan permintaan tarik. Itu bisa dicapai dalam satu-liner tanpa kekuatan, tetapi itu tidak memperbaruidevelop
cabang lokal . Ini hanya masalah memeriksa cabang baru dan membuatnya didasarkanorigin/develop
:sumber
hanya untuk menarik master tanpa memeriksa master yang saya gunakan
git fetch origin master:master
sumber
Sangat mungkin untuk melakukan penggabungan, bahkan penggabungan maju non-cepat, tanpa penggabungan
git checkout
. Theworktree
jawaban dengan @grego adalah petunjuk yang baik. Untuk memperluas itu:Anda sekarang telah menggabungkan cabang kerja lokal ke
master
cabang lokal tanpa mengalihkan checkout Anda.sumber
Jika Anda ingin menyimpan pohon yang sama dengan salah satu cabang yang ingin Anda gabungkan (mis. Bukan "gabungan" yang sebenarnya), Anda dapat melakukannya seperti ini.
sumber
Anda dapat mencoba
git worktree
membuka dua cabang secara berdampingan, sepertinya ini yang Anda inginkan tetapi sangat berbeda dari beberapa jawaban lain yang pernah saya lihat di sini.Dengan cara ini Anda dapat memiliki dua cabang terpisah yang melacak di repo git yang sama sehingga Anda hanya perlu mengambil satu kali untuk mendapatkan pembaruan di kedua pohon kerja (daripada harus git klon dua kali dan git tarik pada masing-masing)
Worktree akan membuat direktori kerja baru untuk kode Anda di mana Anda dapat memiliki cabang yang berbeda diperiksa secara bersamaan alih-alih bertukar cabang di tempat.
Saat Anda ingin menghapusnya, Anda dapat membersihkannya
sumber