Bir yapılandırma dosyasının belirli bir örneğinde, Ron'un cevabına katılıyorum :
bir yapılandırma, çalışma alanınıza "özel" olmalıdır (bu nedenle "bir .gitignore
dosyada bildirildiği gibi" "yok sayılır ").
Bir yapılandırma dosyası olabilir şablonu ile dizgecikli değerler içinde ve bu dönüşüm bir komut dosyası config.template
özel (ve göz ardı) yapılandırma dosyası içine dosyayı.
Bununla birlikte, bu özel açıklama, daha geniş ve daha genel bir sorunun ne olduğunu, yani sorunuzun (!) Yanıtını vermez:
Git'e belirli bir dosyada çakışan birleştirmeler için her zaman yerel sürümümü seçmesini nasıl söylerim? (herhangi bir dosya veya dosya grubu için)
Bu tür bir birleştirme, bir çatışma olduğunda bir dosyanın "bizim" veya "onların" sürümünü her zaman kopyalayacağınız bir "kopya birleştirme" dir.
(aynı Brian Vandenberg notları yorumlarda , ' ours
' ve ' theirs
' burada bir birleştirme işlemi için kullanılmaktadır .
Onlar edilir tersine bir için rebase : bakınız " Why is the meaning of “ours” and “theirs” reversed with git-svn
", bir rebase kullanan, git rebase
"takip 'uzak' 'Yerel' ve " )
"Bir dosya" için (genel olarak bir dosya, kötü bir örnek olduğu için bir "yapılandırma" dosyasından bahsetmeyen bir dosya), bunu birleştirme adı verilen özel bir komut dosyasıyla elde edersiniz.
Eğer bir tanımlayacaktır çünkü Git o senaryoyu arayacak gitattributes değer bir tanımlar, özel birleştirme sürücü .
"Özel birleştirme sürücüsü", bu durumda, temelde mevcut sürümü değiştirmeden koruyan ve böylece her zaman yerel sürümünüzü seçmenize izin veren çok basit bir komut dosyasıdır.
. IE, şöyle kaydetti tarafından Ciro Santilli :
echo 'path/to/file merge=ours' >> .gitattributes
git config --global merge.ours.driver true
Bunu basit bir senaryoda, Windows üzerinde bir msysgit 1.6.3 ile sadece bir DOS oturumunda test edelim:
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/
Şimdi, ikisinin de çakışması olacak, ancak farklı şekilde birleştirilecek iki dosya yapalım.
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
İki farklı git dalındaki her iki dosyanın içeriğinde bir "çakışma" oluşturacağız:
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
Şimdi, "hisBranch" ı "myBranch" ile birleştirmeyi deneyelim:
- çakışan birleştirmeler için manuel çözünürlük
- hariç için
dirWithCopyMerge\b.txt
hep saklamak istediğiniz benim sürümünü b.txt
.
Birleştirme ' MyBranch
' içinde gerçekleştiğinden, ona geri döneceğiz gitattributes
ve birleştirme davranışını özelleştirecek ' ' direktiflerini ekleyeceğiz .
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
.gitattributes
Dizinde tanımlanmış bir dosyamız var dirWithCopyMerge
(yalnızca birleştirmenin gerçekleşeceği dalda tanımlanmıştır myBranch
) ve .git\config
şimdi bir birleştirme sürücüsü içeren bir dosyamız var .
[merge "keepMine"]
name = always keep mine during merge
driver = keepMine.sh %O %A %B
Henüz keepMine.sh tanımlamadıysanız ve birleştirme işlemini yine de başlattıysanız, işte size ne elde edersiniz.
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
Bu iyi:
a.txt
birleştirilmeye hazır ve içinde çatışma var
b.txt
birleştirme sürücüsünün bununla ilgilenmesi gerektiğinden ( .gitattributes
dizinindeki dosyadaki yönerge nedeniyle) hala dokunulmamıştır .
İçinde keepMine.sh
herhangi bir yeri tanımlayın %PATH%
(veya $PATH
Unix arkadaşımız için. Her ikisini de yapıyorum: VirtualBox oturumunda bir Ubuntu oturumum var)
Şöyle yorumladı tarafından lrkwz ve "açıklanan Birleştirme Stratejileri ait" bölümünde Özelleştirme Git - Git Nitelikler , bu kabuk komutuyla shell script değiştirebilirsiniz true
.
git config merge.keepMine.driver true
Ancak genel durumda, bir komut dosyası tanımlayabilirsiniz:
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
(Bu basit bir birleştirme sürücü vardı;) (bu durumda, kullanımda bile daha basit true
)
(eğer hemen önce ekleyin diğer sürümünü kullanmaya devam etmek istiyorsa exit 0
hattı:
cp -f $3 $2
.
İşte bu Şoför uzağa diğer gelen versiyonunu tutacak birleşir. şube, herhangi bir yerel değişikliği geçersiz kılar)
Şimdi, birleştirmeyi baştan tekrar deneyelim:
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.
Birleştirme başarısız olur ... sadece a.txt için .
A.txt dosyasını düzenleyin ve 'hisBranch' satırını bırakın, ardından:
git add -A
git commit -m "resolve a.txt by accepting hisBranch version"
[myBranch 77bc81f] resolve a.txt by accepting hisBranch version
Bu birleştirme sırasında b.txt'nin korunup korunmadığını kontrol edelim
type dirWithCopyMerge\b.txt
b
myLineForB
Son kaydetme, tam birleştirmeyi temsil eder :
git show -v 77bc81f5e
commit 77bc81f5ed585f90fc1ca5e2e1ddef24a6913a1d
Merge: ec202aa 658c31c
git merge hisBranch
Already up-to-date.
(Merge ile başlayan satır bunu kanıtlıyor)
Git'in yapacağı gibi, birleştirme sürücüsünü tanımlayabileceğinizi, birleştirebileceğinizi ve / veya üzerine yazabileceğinizi düşünün:
- incelemek
<dir>/.gitattributes
(söz konusu yolla aynı dizindedir): .gitattributes
dizinlerde diğerine üstün gelecektir
- Daha sonra
.gitattributes
(üst dizinde bulunan) inceler , yalnızca önceden ayarlanmadıysa yönergeleri ayarlayacaktır.
- Sonunda inceliyor
$GIT_DIR/info/attributes
. Bu dosya, ağaç içi ayarları geçersiz kılmak için kullanılır. <dir>/.gitattributes
Direktiflerin üzerine yazacak.
"Birleştirme" ile, "birleştirme" çoklu birleştirme sürücüsünü kastediyorum.
Nick Green , yorumlarda , birleştirme sürücülerini gerçekten birleştirmeye çalışır : bkz. " Pomları python git sürücüsü aracılığıyla birleştirme ".
Ancak, diğer sorusunda da belirtildiği gibi , yalnızca çatışma durumunda işe yarar (her iki dalda eşzamanlı değişiklik).