Sobre a instância específica de um arquivo de configuração, eu concordaria com a resposta de Ron :
uma configuração deve ser "privada" para sua área de trabalho (portanto, "ignorada", como em "declarada em um .gitignore
arquivo").
Você pode ter um modelo de arquivo de configuração com valores tokenizados e um script que transforma esse config.template
arquivo em um arquivo de configuração privado (e ignorado).
No entanto, essa observação específica não responde a uma questão mais ampla e geral, ou seja, sua pergunta (!):
Como faço para dizer ao git para sempre selecionar minha versão local para mesclagens conflitantes em um arquivo específico? (para qualquer arquivo ou grupo de arquivos)
Esse tipo de mesclagem é uma "mesclagem de cópia", na qual você sempre copiará a versão 'nossa' ou 'deles' de um arquivo sempre que houver um conflito.
(como Brian Vandenberg observa nos comentários , ' ours
' e ' theirs
' são usados aqui para uma mesclagem .
Eles são revertidos para um rebase : consulte " Why is the meaning of “ours” and “theirs” reversed with git-svn
", que usa um rebase, " git rebase
, mantendo o controle de 'local' e 'remoto' " )
Para "um arquivo" (um arquivo em geral, sem falar em um arquivo "config", já que é um mau exemplo), você conseguiria isso com um script personalizado chamado por meio de mesclagens.
O Git chamará esse script porque você terá de definir um valor gitattributes , que define um driver de mesclagem personalizado .
O "driver de mesclagem personalizado" é, neste caso, um script muito simples que basicamente manterá inalterada a versão atual, permitindo que você sempre selecione sua versão local.
IE., Conforme observado por Ciro Santilli :
echo 'path/to/file merge=ours' >> .gitattributes
git config --global merge.ours.driver true
Vamos testar isso em um cenário simples, com um msysgit 1.6.3 no Windows, em uma mera sessão do 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/
Agora, vamos fazer dois arquivos, que terão conflitos, mas que serão mesclados de forma diferente.
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
Vamos introduzir um "conflito" no conteúdo de ambos os arquivos em dois branches diferentes do 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
Agora, vamos tentar mesclar "hisBranch" em "myBranch", com:
- resolução manual para mesclagens conflitantes
- exceto para
dirWithCopyMerge\b.txt
onde eu sempre quero manter a minha versão do b.txt
.
Uma vez que a fusão ocorre em ' MyBranch
', voltaremos a ela e adicionaremos as gitattributes
diretivas ' ' que irão personalizar o comportamento da fusão.
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
Temos um .gitattributes
arquivo definido no dirWithCopyMerge
diretório (definido apenas no branch onde ocorrerá a fusão:) myBranch
, e temos um .git\config
arquivo que agora contém um driver de fusão.
[merge "keepMine"]
name = always keep mine during merge
driver = keepMine.sh %O %A %B
Se você ainda não definiu keepMine.sh e lançou a mesclagem mesmo assim, aqui está o que você obtém.
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
Está bem:
a.txt
está pronto para ser mesclado e tem conflito
b.txt
ainda não foi alterado, pois o driver de mesclagem deve cuidar disso (devido à diretiva no .gitattributes
arquivo em seu diretório).
Defina um keepMine.sh
em qualquer lugar no seu %PATH%
(ou $PATH
para nosso amigo Unix. Eu faço ambos, é claro: tenho uma sessão do Ubuntu em uma sessão do VirtualBox)
Conforme comentado por lrkwz e descrito na seção " Merge Strategies " de Customizing Git - Git Attributes , você pode substituir o script de shell pelo comando shell true
.
git config merge.keepMine.driver true
Mas, no caso geral, você pode definir um arquivo de script:
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
(que era um simples motorista de fusão;) (Ainda mais simples, nesse caso, o uso true
)
(Se você queria manter a outra versão, basta adicionar antes da exit 0
linha:
cp -f $3 $2
.
É isso Mesclar motorista brindes manter a versão vinda do outro. filial, substituindo qualquer mudança local)
Agora, vamos tentar novamente a mesclagem desde o início:
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 mesclagem falha ... apenas para a.txt .
Edite a.txt e deixe a linha de 'hisBranch', então:
git add -A
git commit -m "resolve a.txt by accepting hisBranch version"
[myBranch 77bc81f] resolve a.txt by accepting hisBranch version
Vamos verificar se b.txt foi preservado durante esta fusão
type dirWithCopyMerge\b.txt
b
myLineForB
O último commit representa a mesclagem completa :
git show -v 77bc81f5e
commit 77bc81f5ed585f90fc1ca5e2e1ddef24a6913a1d
Merge: ec202aa 658c31c
git merge hisBranch
Already up-to-date.
(A linha que começa com Merge prova isso)
Considere que você pode definir, combinar e / ou substituir o driver de mesclagem, como o Git fará:
- examine
<dir>/.gitattributes
(que está no mesmo diretório do caminho em questão): prevalecerá sobre o outro .gitattributes
nos diretórios
- Em seguida, examina
.gitattributes
(que está no diretório pai), só definirá as diretivas se ainda não estiver definido
- Finalmente, ele examina
$GIT_DIR/info/attributes
. Este arquivo é usado para substituir as configurações da árvore. Ele substituirá as <dir>/.gitattributes
diretivas.
Por "combinação", quero dizer "agregar" vários drivers de mesclagem.
Nick Green tenta, nos comentários , realmente combinar os drivers de mesclagem: consulte " Mesclar pom's via driver git python ".
No entanto, como mencionado em sua outra pergunta , ele só funciona em caso de conflitos (modificação simultânea em ambos os ramos).