Pada contoh spesifik dari file konfigurasi, saya setuju dengan jawaban Ron :
konfigurasi harus "pribadi" ke ruang kerja Anda (karenanya "diabaikan", seperti dalam "dideklarasikan dalam .gitignore
file").
Anda mungkin memiliki template file konfigurasi dengan nilai tokenized di dalamnya, dan skrip yang mengubah config.template
file itu menjadi file konfigurasi pribadi (dan diabaikan).
Namun, pernyataan khusus itu tidak menjawab pertanyaan yang lebih luas yang lebih umum, yaitu pertanyaan Anda (!):
Bagaimana cara memberi tahu git untuk selalu memilih versi lokal saya untuk penggabungan yang berkonflik pada file tertentu? (untuk file atau grup file apa pun)
Penggabungan jenis ini adalah "penggabungan salinan", di mana Anda akan selalu menyalin versi 'milik kami' atau 'milik mereka' setiap kali ada konflik.
(seperti yang dicatat Brian Vandenberg di komentar , ' ours
' dan ' theirs
' di sini digunakan untuk penggabungan .
Mereka dibalik untuk rebase : lihat " Why is the meaning of “ours” and “theirs” reversed with git-svn
", yang menggunakan rebase, " git rebase
, melacak 'lokal' dan 'jarak jauh' " )
Untuk "file" (file secara umum, tidak berbicara tentang file "config", karena ini adalah contoh yang buruk), Anda akan melakukannya dengan skrip kustom yang dipanggil melalui penggabungan.
Git akan memanggil skrip tersebut karena Anda telah menentukan nilai gitattributes , yang mendefinisikan driver gabungan khusus .
Dalam hal ini, "custom merge driver" adalah skrip yang sangat sederhana yang pada dasarnya tidak akan mengubah versi saat ini, sehingga memungkinkan Anda untuk selalu memilih versi lokal Anda.
YAITU., Seperti dicatat oleh Ciro Santilli :
echo 'path/to/file merge=ours' >> .gitattributes
git config --global merge.ours.driver true
Mari kita uji dalam skenario sederhana, dengan msysgit 1.6.3 di Windows, hanya dalam sesi DOS:
cd f:\prog\git\test
mkdir copyMerge\dirWithConflicts
mkdir copyMerge\dirWithCopyMerge
cd copyMerge
git init
Initialized empty Git repository in F:/prog/git/test/copyMerge/.git/
Sekarang, mari buat dua file, yang keduanya akan memiliki konflik, tetapi akan digabungkan secara berbeda.
echo a > dirWithConflicts\a.txt
echo b > dirWithCopyMerge\b.txt
git add -A
git commit -m "first commit with 2 directories and 2 files"
[master (root-commit) 0adaf8e] first commit with 2 directories and 2 files
Kami akan memperkenalkan "konflik" pada konten kedua file tersebut di dua cabang git yang berbeda:
git checkout -b myBranch
Switched to a new branch 'myBranch'
echo myLineForA >> dirWithConflicts\a.txt
echo myLineForB >> dirWithCopyMerge\b.txt
git add -A
git commit -m "add modification in myBranch"
[myBranch 97eac61] add modification in myBranch
git checkout master
Switched to branch 'master'
git checkout -b hisBranch
Switched to a new branch 'hisBranch'
echo hisLineForA >> dirWithConflicts\a.txt
echo hisLineForB >> dirWithCopyMerge\b.txt
git add -A
git commit -m "add modification in hisBranch"
[hisBranch 658c31c] add modification in hisBranch
Sekarang, mari kita coba menggabungkan "hisBranch" ke "myBranch", dengan:
- resolusi manual untuk penggabungan yang bertentangan
- kecuali untuk
dirWithCopyMerge\b.txt
di mana aku selalu ingin menjaga saya versi b.txt
.
Karena penggabungan terjadi di ' MyBranch
', kami akan beralih kembali ke sana, dan menambahkan gitattributes
arahan ' ' yang akan menyesuaikan perilaku penggabungan.
git checkout myBranch
Switched to branch 'myBranch'
echo b.txt merge=keepMine > dirWithCopyMerge\.gitattributes
git config merge.keepMine.name "always keep mine during merge"
git config merge.keepMine.driver "keepMine.sh %O %A %B"
git add -A
git commit -m "prepare myBranch with .gitattributes merge strategy"
[myBranch ec202aa] prepare myBranch with .gitattributes merge strategy
Kami memiliki .gitattributes
file yang ditentukan di dirWithCopyMerge
direktori (hanya ditentukan di cabang tempat penggabungan akan terjadi :) myBranch
, dan kami memiliki .git\config
file yang sekarang berisi driver gabungan.
[merge "keepMine"]
name = always keep mine during merge
driver = keepMine.sh %O %A %B
Jika Anda belum mendefinisikan keepMine.sh, dan tetap meluncurkan penggabungan, inilah yang Anda dapatkan.
git merge hisBranch
sh: keepMine.sh: command not found
fatal: Failed to execute internal merge
git st
# On branch myBranch
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: dirWithConflicts/a.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
type dirWithConflicts\a.txt
a
<<<<<<< HEAD:dirWithConflicts/a.txt
myLineForA
=======
hisLineForA
>>>>>>> hisBranch:dirWithConflicts/a.txt
Ini baik saja:
a.txt
siap untuk digabungkan dan memiliki konflik di dalamnya
b.txt
masih belum tersentuh, karena driver gabungan seharusnya menanganinya (karena arahan dalam .gitattributes
file di direktorinya).
Tentukan keepMine.sh
di mana saja di Anda %PATH%
(atau $PATH
untuk teman Unix kami. Saya melakukan keduanya tentu saja: Saya memiliki sesi Ubuntu dalam sesi VirtualBox)
Seperti yang dikomentari oleh lrkwz , dan dijelaskan di bagian " Merge Strategies " dari Menyesuaikan Atribut Git - Git , Anda dapat mengganti skrip shell dengan perintah shell true
.
git config merge.keepMine.driver true
Namun dalam kasus umum, Anda dapat menentukan file skrip:
keepMine.sh
# I want to keep MY version when there is a conflict
# Nothing to do: %A (the second parameter) already contains my version
# Just indicate the merge has been successfully "resolved" with the exit status
exit 0
(yang satu driver penggabungan sederhana;) (Bahkan sederhana dalam kasus, penggunaan true
)
(Jika Anda ingin menjaga versi lainnya, cukup tambahkan sebelum exit 0
baris:
cp -f $3 $2
.
Itu saja Anda menggabungkan pengemudi akan aways menjaga versi datang dari yang lain. cabang, menimpa perubahan lokal apa pun)
Sekarang, mari coba lagi penggabungan dari awal:
git reset --hard
HEAD is now at ec202aa prepare myBranch with .gitattributes merge strategy
git merge hisBranch
Auto-merging dirWithConflicts/a.txt
CONFLICT (content): Merge conflict in dirWithConflicts/a.txt
Auto-merging dirWithCopyMerge/b.txt
Automatic merge failed; fix conflicts and then commit the result.
Penggabungan gagal ... hanya untuk a.txt .
Edit a.txt dan tinggalkan baris dari 'hisBranch', lalu:
git add -A
git commit -m "resolve a.txt by accepting hisBranch version"
[myBranch 77bc81f] resolve a.txt by accepting hisBranch version
Mari kita periksa bahwa b.txt telah dipertahankan selama penggabungan ini
type dirWithCopyMerge\b.txt
b
myLineForB
Komit terakhir memang mewakili gabungan penuh :
git show -v 77bc81f5e
commit 77bc81f5ed585f90fc1ca5e2e1ddef24a6913a1d
Merge: ec202aa 658c31c
git merge hisBranch
Already up-to-date.
(Garis yang dimulai dengan Gabung membuktikan itu)
Pertimbangkan bahwa Anda dapat menentukan, menggabungkan dan / atau menimpa driver gabungan, karena Git akan:
- memeriksa
<dir>/.gitattributes
(yang ada di direktori yang sama dengan jalur yang dimaksud): akan berlaku atas yang lain .gitattributes
di direktori
- Kemudian memeriksa
.gitattributes
(yang ada di direktori induk), hanya akan mengatur direktif jika belum diatur
- Akhirnya ia memeriksa
$GIT_DIR/info/attributes
. File ini digunakan untuk mengganti pengaturan dalam pohon. Ini akan menimpa <dir>/.gitattributes
arahan.
Dengan "menggabungkan", yang saya maksud adalah "menggabungkan" beberapa driver gabungan.
Nick Green mencoba, di komentar , untuk benar-benar menggabungkan driver gabungan: lihat " Menggabungkan pom melalui driver git python ".
Namun, seperti yang disebutkan dalam pertanyaannya yang lain , ini hanya berfungsi jika terjadi konflik (modifikasi bersamaan di kedua cabang).