In Bezug auf die spezifische Instanz einer Konfigurationsdatei würde ich Rons Antwort zustimmen :
Eine Konfiguration sollte für Ihren Arbeitsbereich "privat" sein (daher "ignoriert", wie in "in einer .gitignore
Datei deklariert ").
Sie können eine Konfigurationsdatei haben Schablone mit Zeichen übersetzten Werte in ihm, und ein Skript , das die Umwandlung config.template
Datei in eine private (und ignoriert) Config - Datei.
Diese spezifische Bemerkung beantwortet jedoch nicht eine allgemeinere Frage, dh Ihre Frage (!):
Wie kann ich git anweisen, immer meine lokale Version für Zusammenführungen von Konflikten in einer bestimmten Datei auszuwählen? (für jede Datei oder Dateigruppe)
Diese Art der Zusammenführung ist eine "Zusammenführung von Kopien", bei der Sie bei Konflikten immer "unsere" oder "ihre" Version einer Datei kopieren.
(Wie Brian Vandenberg in den Kommentaren feststellt , werden ' ours
' und ' theirs
' hier für eine Zusammenführung verwendet .
Sie werden für eine Rebase umgekehrt : siehe " ", das eine Rebase verwendet, " und verfolgt 'local' und 'remote' ". )Why is the meaning of “ours” and “theirs” reversed with git-svn
git rebase
Für "eine Datei" (eine Datei im Allgemeinen, die nicht von einer "Konfigurations" -Datei spricht, da dies ein schlechtes Beispiel ist) würden Sie dies mit einem benutzerdefinierten Skript erreichen, das durch Zusammenführungen aufgerufen wird.
Git ruft dieses Skript auf, da Sie einen gitattributes- Wert definiert haben , der einen benutzerdefinierten Zusammenführungstreiber definiert .
Der "benutzerdefinierte Zusammenführungstreiber" ist in diesem Fall ein sehr einfaches Skript, das die aktuelle Version grundsätzlich unverändert lässt, sodass Sie immer Ihre lokale Version auswählen können.
IE., Wie von Ciro Santilli bemerkt :
echo 'path/to/file merge=ours' >> .gitattributes
git config --global merge.ours.driver true
Lassen Sie uns dies in einem einfachen Szenario mit einem msysgit 1.6.3 unter Windows in einer bloßen DOS-Sitzung testen:
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/
Lassen Sie uns nun zwei Dateien erstellen, die beide Konflikte aufweisen, aber unterschiedlich zusammengeführt werden.
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
Wir werden einen "Konflikt" im Inhalt dieser beiden Dateien in zwei verschiedenen Git-Zweigen einführen:
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
Versuchen wir nun, "hisBranch" mit "myBranch" zusammenzuführen, mit:
- manuelle Lösung für widersprüchliche Zusammenführungen
- ausnehmen für ,
dirWithCopyMerge\b.txt
wo ich will immer halten meine Version b.txt
.
Da die Zusammenführung in ' MyBranch
' erfolgt, wechseln wir zurück und fügen die ' gitattributes
' Anweisungen hinzu, mit denen das Zusammenführungsverhalten angepasst wird.
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
Wir haben eine .gitattributes
Datei im dirWithCopyMerge
Verzeichnis definiert (definiert nur in dem Zweig, in dem die Zusammenführung stattfinden wird :) myBranch
, und wir haben eine .git\config
Datei, die jetzt einen Zusammenführungstreiber enthält.
[merge "keepMine"]
name = always keep mine during merge
driver = keepMine.sh %O %A %B
Wenn Sie keepMine.sh noch nicht definieren und die Zusammenführung trotzdem starten, erhalten Sie Folgendes.
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
Das ist gut:
a.txt
ist bereit zum Zusammenführen und hat Konflikte
b.txt
ist immer noch unberührt, da der Zusammenführungstreiber sich darum kümmern soll (aufgrund der Anweisung in der .gitattributes
Datei in seinem Verzeichnis).
Definieren Sie eine keepMine.sh
beliebige Stelle in Ihrem %PATH%
(oder $PATH
für unseren Unix-Freund. Ich mache natürlich beides: Ich habe eine Ubuntu-Sitzung in einer VirtualBox-Sitzung)
Wie von lrkwz kommentiert und im Abschnitt " Strategien zusammenführen " unter Anpassen von Git - Git-Attributen beschrieben , können Sie das Shell-Skript durch den Shell-Befehl ersetzen .true
git config merge.keepMine.driver true
Im allgemeinen Fall können Sie jedoch eine Skriptdatei definieren:
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
(das war ein einfacher Zusammenführungstreiber;) (In diesem Fall noch einfacher verwenden true
)
(Wenn Sie die andere Version
behalten möchten , fügen Sie einfach vor der exit 0
Zeile hinzu :
cp -f $3 $2
.
Das war's. Ihr Zusammenführungstreiber würde immer die Version von der anderen erhalten Zweigstelle, die alle lokalen Änderungen außer Kraft setzt)
Lassen Sie uns nun die Zusammenführung von Anfang an wiederholen:
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.
Die Zusammenführung schlägt fehl ... nur für a.txt .
Bearbeiten Sie a.txt und verlassen Sie die Zeile von 'hisBranch'. Dann:
git add -A
git commit -m "resolve a.txt by accepting hisBranch version"
[myBranch 77bc81f] resolve a.txt by accepting hisBranch version
Lassen Sie uns überprüfen, ob b.txt während dieser Zusammenführung beibehalten wurde
type dirWithCopyMerge\b.txt
b
myLineForB
Das letzte Commit stellt die vollständige Zusammenführung dar:
git show -v 77bc81f5e
commit 77bc81f5ed585f90fc1ca5e2e1ddef24a6913a1d
Merge: ec202aa 658c31c
git merge hisBranch
Already up-to-date.
(Die mit Merge beginnende Zeile beweist das)
Überlegen Sie, ob Sie den Zusammenführungstreiber wie bei Git definieren, kombinieren und / oder überschreiben können:
- Prüfen
<dir>/.gitattributes
(das sich im selben Verzeichnis befindet wie der betreffende Pfad): Wird sich .gitattributes
in Verzeichnissen gegen das andere durchsetzen
- Dann prüft es
.gitattributes
(das sich im übergeordneten Verzeichnis befindet), setzt nur Direktiven, wenn es nicht bereits gesetzt ist
- Schließlich untersucht es
$GIT_DIR/info/attributes
. Diese Datei wird verwendet, um die In-Tree-Einstellungen zu überschreiben. <dir>/.gitattributes
Direktiven werden überschrieben .
Mit "Kombinieren" meine ich den "aggregierten" Mehrfachzusammenführungstreiber.
Nick Green versucht in den Kommentaren , Zusammenführungstreiber tatsächlich zu kombinieren: siehe " Zusammenführen von Poms über Python-Git-Treiber ".
Wie in seiner anderen Frage erwähnt , funktioniert dies jedoch nur bei Konflikten (gleichzeitige Änderung in beiden Zweigen).