Що стосується конкретного примірника файлу config, я погодився би з відповіддю Рона :
конфігурація повинна бути "приватною" для вашої робочої області (отже, "ігнорується", як у "оголошеному у .gitignore
файлі").
У вас може бути шаблон конфігураційного файлу з токенізованими значеннями та сценарій, який перетворює цей config.template
файл у приватний (і ігнорований) конфігураційний файл.
Однак це конкретне зауваження не відповідає, що є більш широким загальним питанням, тобто вашим питанням (!):
Як я можу сказати git завжди вибирати локальну версію для суперечливих злиттів у певному файлі? (для будь-якого файлу чи групи файлів)
Цей вид злиття - це "злиття копії", в якому ви завжди будете копіювати "нашу" або "їхню" версію файлу, коли виникає конфлікт.
(Як Брайан Ванденберг примітка в коментарях , « ours
» і « theirs
» тут використовується для об'єднання .
Вони зворотні для перебазування : см « Why is the meaning of “ours” and “theirs” reversed with git-svn
», який використовує перебазуватися git rebase
«стежити за " місцеві "і" віддаленим " » )
Для "файла" (файл взагалі, не кажучи про файл "config", оскільки це поганий приклад), ви могли б цього досягти за допомогою спеціального сценарію, викликаного через злиття.
Git називатиме цей скрипт, оскільки у вас буде визначене значення gitattributes , яке визначає користувацький драйвер злиття .
"Користувацький драйвер злиття" - в цьому випадку дуже простий скрипт, який в основному залишатиметься незмінним поточної версії, отже, дозволяє вам завжди обирати локальну версію.
. IE, Як зазначено на Ciro Сантіллі :
echo 'path/to/file merge=ours' >> .gitattributes
git config --global merge.ours.driver true
Давайте перевіримо це у простому сценарії, з msysgit 1.6.3 для Windows, протягом простого сеансу 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/
Тепер давайте зробимо два файли, в яких будуть обидва конфлікти, але які будуть об'єднані по-різному.
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
Ми введемо "конфлікт" у вміст обох цих файлів у двох різних гілках git:
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
Тепер спробуємо об'єднати "hisBranch" з "myBranch" із:
- ручне рішення для конфліктуючих злиттів
- за винятком того, на
dirWithCopyMerge\b.txt
якому я завжди хочу , щоб зберегти свою версію b.txt
.
Оскільки злиття відбувається в ' MyBranch
', ми переключимось на нього назад і додамо gitattributes
директиви ' ', які налаштовують поведінку злиття.
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
файлі визначений файл dirWithCopyMerge
(визначений лише у гілці, де відбудеться злиття:) myBranch
, і у нас є .git\config
файл, який тепер містить драйвер злиття.
[merge "keepMine"]
name = always keep mine during merge
driver = keepMine.sh %O %A %B
Якщо ви ще не визначили KeepMine.sh і все одно запустите злиття, ось що ви отримаєте.
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
Це добре:
a.txt
готовий до злиття і має в цьому конфлікт
b.txt
залишається недоторканим, оскільки драйвер злиття повинен піклуватися про нього (через директиву, що міститься у .gitattributes
файлі в його каталозі).
Визначте keepMine.sh
будь-де у своєму %PATH%
(або $PATH
для нашого друга Unix. Я, звичайно, і те, і інше: у мене сесія Ubuntu у сесії VirtualBox)
Як зазначив по lrkwz , і описано в розділі « Об'єднати Strategies розділі" з призначеної для користувача настройки Git - Атрибути Git , ви можете замінити скрипт з командою оболонки true
.
git config merge.keepMine.driver true
Але в загальному випадку ви можете визначити файл сценарію:
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
(Це був один простий драйвер злиття;) (навіть простіше в цьому випадку, використання true
)
(Якщо ви хочете зберегти іншу версію, просто додайте перед exit 0
рядком:
cp -f $3 $2
.
Ось і ви зливатися водій буде Візитки тримати версію приходячи від іншого. відділення, що скасовує будь-які місцеві зміни)
Тепер давайте спробуємо об'єднати спочатку:
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.
Злиття не вдається ... лише для a.txt .
Відредагуйте a.txt і залиште рядок із "hisBranch", а потім:
git add -A
git commit -m "resolve a.txt by accepting hisBranch version"
[myBranch 77bc81f] resolve a.txt by accepting hisBranch version
Перевіримо, чи зберігався b.txt під час цього злиття
type dirWithCopyMerge\b.txt
b
myLineForB
Остання комісія дійсно являє собою повне злиття:
git show -v 77bc81f5e
commit 77bc81f5ed585f90fc1ca5e2e1ddef24a6913a1d
Merge: ec202aa 658c31c
git merge hisBranch
Already up-to-date.
(Рядок, що починається з об’єднання, це доводить)
Ми можемо визначити, об'єднати та / або перезаписати драйвер злиття, як Git:
- вивчити
<dir>/.gitattributes
(який знаходиться в тому ж каталозі, що і розглянутий шлях): буде мати перевагу над іншими .gitattributes
в каталогах
- Тоді він вивчає
.gitattributes
(що знаходиться в батьківському каталозі), буде встановлювати директиви лише, якщо вони вже не встановлені
- Нарешті він вивчає
$GIT_DIR/info/attributes
. Цей файл використовується для зміни параметрів дерева. Це замінить <dir>/.gitattributes
директиви.
Під "комбінуванням" я маю на увазі "сукупність" драйверів з декількома об'єднаннями.
Нік Грін намагається, в коментарях , насправді комбайнери злиття: дивіться « Merge POM за допомогою пітона мерзотник драйвер ».
Однак, як згадувалося в його іншому питанні , він працює лише у випадку конфліктів (одночасні зміни в обох галузях).