Bagaimana cara menggabungkan perubahan ke satu file, dan tidak menggabungkan komit?


383

Saya memiliki dua cabang (A dan B) dan saya ingin menggabungkan satu file dari cabang A dengan file tunggal yang sesuai dari Cabang B.



27
Sebagian besar respons terhadap posting lain tersebut adalah tentang cara menggabungkan komit , bukan file . Ini membuat jawaban yang dipilih salah. Pertanyaannya tetap tidak terjawab.


Jawaban ini adalah cara untuk pergi, IMO. git diff branch_name > patch git apply patch. stackoverflow.com/a/9473543/1091853
blamb

Jawaban:


631

Saya menemukan masalah yang sama. Lebih tepatnya, saya memiliki dua cabang Adan Bdengan file yang sama tetapi antarmuka pemrograman yang berbeda dalam beberapa file. Sekarang metode file f, yang independen dari perbedaan antarmuka di dua cabang, diubah dalam cabang B, tetapi perubahan ini penting untuk kedua cabang. Jadi, saya perlu menggabungkan hanya file fcabang Bke file fcabang A.

Perintah sederhana sudah memecahkan masalah bagi saya jika saya berasumsi bahwa semua perubahan dilakukan di kedua cabang Adan B:

git checkout A

git checkout --patch B f

Perintah pertama beralih ke cabang A, ke tempat saya ingin menggabungkan Bversi file f. Perintah kedua patch file fdengan fdari HEADdari B. Anda bahkan dapat menerima / membuang satu bagian patch. Alih-alih BAnda dapat menentukan komit apa pun di sini, itu tidak harus HEAD.

Suntingan komunitas : Jika file faktif Bbelum ada A, maka abaikan --patchopsi. Jika tidak, Anda akan mendapatkan "Tidak Ada Perubahan." pesan.


10
Ini hanya berfungsi jika Anda ingin memperbarui file. Bagaimana jika saya ingin menambahkan file baru dari cabang B ke cabang A?
Umair A.

25
@UmairAshraf Anda harus dapat menambahkan file baru dari B ke A dengan menghapus opsi --patch.
bbak

9
Hmmm ... ketika saya coba ini saya mendapat pesan "tidak ada perubahan", tetapi jelas ada perubahan. OK, saya harus berada di folder tempat file yang relevan berada. Sunting: Ini sangat mungkin menjadi solusi favorit saya untuk masalah yang pernah saya lihat di stackoverflow :-D
bot_bot

2
Saya harus menggunakan git checkout --patch B -- funtuk mendapatkan ini berfungsi.
user545424

8
Hanya perlu menambahkan bahwa jika Anda memiliki beberapa perubahan (bakhil) dalam file dan Anda ingin mementaskan semuanya , Anda dapat menekan aselama fase interaktif, alih-alih menekan ysetiap waktu. Atau gunakan git checkout B -- fperintah sebagai gantinya.
Dmitry Gonchar

17

Inilah yang saya lakukan dalam situasi ini. Itu adalah kludge tetapi itu bekerja dengan baik untuk saya.

  1. Buat cabang lain berdasarkan dari cabang kerja Anda.
  2. git pull / git menggabungkan revisi (SHA1) yang berisi file yang ingin Anda salin. Jadi ini akan menggabungkan semua perubahan Anda, tetapi kami hanya menggunakan cabang ini untuk mengambil satu file.
  3. Perbaiki segala Konflik dll. Selidiki file Anda.
  4. checkout cabang kantor Anda
  5. Periksa file yang dilakukan dari gabungan Anda.
  6. Lakukan itu.

Saya mencoba menambal dan situasi saya terlalu buruk untuk itu. Jadi singkatnya akan terlihat seperti ini:

Cabang Kerja: Cabang Eksperimental: B (berisi file.txt yang memiliki perubahan yang ingin saya lipat.)

git checkout A

Buat cabang baru berdasarkan A:

git checkout -b tempAB

Gabungkan B ke dalam tempAB

git merge B

Salin hash sha1 dari penggabungan:

git log

commit 8dad944210dfb901695975886737dc35614fa94e
Merge: ea3aec1 0f76e61
Author: matthewe <matthewe@matthewe.com>
Date:   Wed Oct 3 15:13:24 2012 -0700

Merge branch 'B' into tempAB

Periksa cabang kerja Anda:

git checkout A

Periksa file perbaikan Anda:

git checkout 7e65b5a52e5f8b1979d75dffbbe4f7ee7dad5017 file.txt

Dan di sana Anda harus memilikinya. Komit hasil Anda.


3
Jadi kita harus melakukan semua ini hanya untuk menggabungkan satu file? Bukankah lebih mudah untuk menyalin dan menempelkan file ke cabang lain
Robin

1
@Robin mungkin tidak, karena penggabungan membuat perubahan pada file, yang berbeda antara cabang A dan B. menyalin file akan menimpa perbedaan tambahan antara cabang kerja A Anda, dan apa yang ingin Anda bawa dari B, yang mungkin tidak mengandung entri / suntingan tersebut. misalnya tersangka Atelah beralih dari Bawal, dengan cara lain. Menyalin akan mengatasi perbedaan-perbedaan itu.
mengacaukan

14

Ini menggunakan difftool internal git. Mungkin sedikit pekerjaan yang harus dilakukan tetapi terus terang.

#First checkout the branch you want to merge into
git checkout <branch_to_merge_into>

#Then checkout the file from the branch you want to merge from
git checkout <branch_to_merge_from> -- <file> 

#Then you have to unstage that file to be able to use difftool
git reset HEAD <file> 

#Now use difftool to chose which lines to keep. Click on the mergebutton in difftool
git difftool

#Save the file in difftool and you should be done.

1
Untuk memperjelas penggunaan --(label argumen kosong), git checkout docs: ARGUMENT DISAMBIGUATION mengatakan: "gunakan git checkout -- <pathspec>jika Anda ingin checkout jalur ini dari indeks." Ini karena Anda bisa memiliki cabang dan file / jalur dengan nama yang sama. Dalam kasus seperti itu, daripada meminta Anda untuk tidak menentukan apakah cabang atau path harus diperiksa ketika keduanya ada, git akan memilih untuk checkout cabang secara default. Namun jika --precit git akan checkout file / path sebagai gantinya.
SherylHohman

8

Saya menemukan pendekatan ini sederhana dan bermanfaat: Cara "menggabungkan" file tertentu dari cabang lain

Ternyata, kami berusaha terlalu keras. Git checkout teman baik kami adalah alat yang tepat untuk pekerjaan itu.

git checkout source_branch <paths>...

Kita cukup memberi git checkout nama cabang fitur A dan path ke file tertentu yang ingin kita tambahkan ke cabang master kita.

Silakan baca seluruh artikel untuk pemahaman lebih lanjut


2
Ini menimpa file, itu tidak menggabungkan mereka
Alex G

Bagi Anda itu mungkin, itu tergantung apa yang Anda lakukan dan apa yang ingin Anda capai. Idenya di sini adalah cabang B adalah garpu A, Anda memodifikasi 4 file dalam B, tetapi ingin menggabungkan hanya 2 dari B ke A. Gabungan biasa akan menggabungkan semua 4, di sini Anda dapat memilih. Ini mungkin terlihat seperti ditimpa karena B pada dasarnya berisi file yang lebih baru. Anda perlu mendukung pengalaman Anda dengan beberapa bukti.
Pawel Cioch

Saya setuju bahwa itu menimpa. Saya pikir Anda bermaksud menggunakan -popsi dalam perintah itu. Yang kemudian, menimpa setiap bagian pada file worktree Anda yang sebelumnya dialihkan dari cabang tempat Anda keluar, sebelum perubahan patch, sayangnya.
mengacaukan

Yah idenya adalah dari tahun 2009, kemungkinan versi baru git berperilaku berbeda dan perlu -p atau apa pun tetapi kembali ketika saya mempostingnya itu berfungsi untuk saya, tapi sekali lagi mungkin saya tidak peduli tentang file yang ditimpa, karena versi terbaru adalah yang saya butuhkan
Pawel Cioch


3

Perintah berikut akan (1) membandingkan file dari cabang yang benar, untuk menguasai (2) secara interaktif bertanya kepada Anda modifikasi mana yang berlaku.

git checkout - master pengirim


0

Hasil edit saya ditolak, jadi saya melampirkan cara menangani perubahan gabungan dari cabang jarak jauh di sini.

Jika Anda harus melakukan ini setelah penggabungan yang salah, Anda dapat melakukan sesuatu seperti ini:

# If you did a git pull and it broke something, do this first
# Find the one before the merge, copy the SHA1
git reflog
git reset --hard <sha1>

# Get remote updates but DONT auto merge it
git fetch github 

# Checkout to your mainline so your branch is correct.
git checkout develop 

# Make a new branch where you'll be applying matches
git checkout -b manual-merge-github-develop

# Apply your patches
git checkout --patch github/develop path/to/file
...

# Merge changes back in
git checkout develop
git merge manual-merge-github-develop # optionally add --no-ff

# You'll probably have to
git push -f # make sure you know what you're doing.

0

Dengan asumsi B adalah cabang saat ini:

$ git diff A <file-path> > patch.tmp
$ git apply patch.tmp -R

Perhatikan bahwa ini hanya berlaku untuk perubahan file lokal. Anda harus berkomitmen setelahnya.


Bagi saya ini menghasilkanerror: <file-path>: already exists in working directory
kontur

Anda harus menentukan jalur file atau file tertentu di direktori saat ini. Saya menggunakangit diff Branch_A <file-path, filename> -- hash_commit > file_name.temp
R.Chatsiri

0

Anda bisa checkout versi lama file untuk digabung, menyimpannya di bawah nama yang berbeda, kemudian jalankan alat penggabungan apa pun Anda pada dua file.

misalnya.

git show B:src/common/store.ts > /tmp/store.ts (di mana B adalah nama cabang / komit / tag)

meld src/common/store.ts /tmp/store.ts


0

Saya akan melakukannya sebagai

git format-patch branch_old..branch_new file

ini akan menghasilkan tambalan untuk file.

Terapkan tambalan di target branch_old

git am blahblah.patch


Bisakah Anda dengan mudah melihat ke dalam tambalan untuk keamanan ekstra?
XavierStuvw
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.