Как я могу сказать git всегда выбирать мою локальную версию для конфликтных слияний в определенном файле?



скажем, я сотрудничаю с кем-то через репозиторий git, и есть конкретный файл, который я никогда не хочу принимать никаких внешних изменений.



есть ли способ для меня настроить мое локальное репо, чтобы не жаловаться на конфликтное слияние каждый раз, когда я git pull? Я хотел бы всегда выбирать свою локальную версию при объединении этого файла.

611   2  

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

    Ничего не найдено.