Как я могу сказать git всегда выбирать мою локальную версию для конфликтных слияний в определенном файле?
скажем, я сотрудничаю с кем-то через репозиторий git, и есть конкретный файл, который я никогда не хочу принимать никаких внешних изменений.
есть ли способ для меня настроить мое локальное репо, чтобы не жаловаться на конфликтное слияние каждый раз, когда я git pull? Я хотел бы всегда выбирать свою локальную версию при объединении этого файла.
2 ответов:
на конкретном экземпляре конфигурационного файла я бы согласился с Рона!--43-->:
конфигурация должна быть " частной "для вашего рабочего пространства (следовательно," игнорируется", как в " объявлено в ").
У вас может быть конфигурационный файл шаблон С размечается значения в нем и скрипт, преобразующий этоconfig.templateфайл в частный (и проигнорированный) конфигурационный файл.
однако это конкретное замечание не отвечает на то, что более широкий общий вопрос, т. е. вопрос(!):
как я могу сказать git всегда выбирать мою локальную версию для конфликтных слияний в определенном файле ? (для любого файла или группы файлов)
этот вид слияния является "слиянием копий", в котором вы всегда будете копировать "нашу" или " их " версию файла всякий раз, когда возникает конфликт.
(как Брайан Ванденберг Примечания в комментарии,'
ours' и 'theirs' здесь используются для слияния.
Они отменено на rebase: см."Why is the meaning of “ours” and “theirs” reversed with git-svn", который использует перебазировать, "git rebase, отслеживание "локального" и "удаленного"")для "файла" (файл вообще, не говоря о файле "config", так как это плохой пример), вы бы достигли этого с помощью пользовательского скрипта, вызванного через поглощает.
Git вызовет этот скрипт, потому что у вас будет define a gitattributes стоимостью, который определяет a пользовательский драйвер слияния."пользовательский драйвер слияния" в этом случае является очень простым скриптом, который в основном будет сохранять неизменной текущую версию, что позволяет вам всегда выбирать локальную версию.
давайте проверим это в простом сценарии, с 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)как прокомментировал by lrkwz, и описан в "Слияние Стратегий" из Настройка Атрибутов 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.
Вот и все. Вы объединяете драйвер всегда сохраняете версию, поступающую из другой ветви, переопределяя любое локальное изменение)теперь давайте повторим слияние с самого начала:
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директивы.под " объединением "я подразумеваю" совокупный " драйвер множественного слияния.
Ник Зеленый нах в комментариях, чтобы на самом деле объединить объединить драйверы: см. "слияние pom через драйвер python git".
Однако, как уже упоминалось в его другой вопрос, он работает только в случае конфликтов (одновременных изменений в обеих ветвях).
У нас есть несколько конфигурационных файлов, которые мы никогда не хотим перезаписывать. Однако.gitignore и .gitattributes не работал в нашей ситуации. Наше решение состояло в том, чтобы хранить конфигурационные файлы в ветке configs. Затем разрешите изменять файлы во время слияния git, но сразу после слияния используйте "git checkout branch -- ."чтобы скопировать наши конфигурационные файлы из ветки configs после каждого слияния. подробный ответ stackoverflow здесь
Comments