[解決済み] 特定のファイルで競合が発生した場合、常に自分のローカルバージョンを選択するようにgitに指示するにはどうすればよいですか?
質問
git リポジトリを介して誰かと共同作業をしていて、外部からの変更を決して受け入れたくない特定のファイルがあるとします。
git pull するたびに競合するマージの文句を言わないように、自分のローカルリポジトリをセットアップする方法はありますか?このファイルをマージするときに、常に私のローカル バージョンを選択したいのです。
どのように解決するのですか?
設定ファイルの具体的な例については、私も同意見です。
Ron の回答
:
はワークスペースに対してプライベートであるべきです(したがって、quot;無視されます)。
.gitignore
ファイルで宣言されているように)。
あなたは、コンフィグファイル
テンプレート
で
トークン化された値
であり、それを変換するスクリプトが
config.template
ファイルをプライベートな (そして無視される) 設定ファイルに変換するスクリプトです。
しかし、その特定の発言は、より広範で一般的な質問、すなわちあなたの質問(!)には答えていません。
特定のファイルで競合が発生した場合に、常に自分のローカルバージョンを選択するように git に指示するにはどうすればよいですか? (任意のファイルやファイルのグループに対して)
この種のマージは "コピーマージ" で、競合がある場合は常に「我々」または「彼ら」のバージョンのファイルをコピーすることになります。
(例えば ブライアン・ヴァンデンバーグ ノート コメント欄 , '
ours
' と 'theirs
はここではマージに使用されています .
これらは 逆 の場合は リベース : "を参照してください。Why is the meaning of “ours” and “theirs” reversed with git-svn
"は、リベースを使用する、"git rebase
は、'ローカル' と 'リモート' を追跡しています。 ")
ファイル (一般的なファイル。悪い例なので、設定ファイルについては言及しません) については、マージによって呼び出されるカスタム スクリプトで実現します。
を定義しているので、Git はそのスクリプトを呼び出します。
gitattributes
値
を定義しています。
カスタムマージドライバ
.
カスタム マージ ドライバは、この場合、基本的に現在のバージョンを変更しないようにする非常に単純なスクリプトであり、したがって、常にローカル バージョンを選択できるようにします。
echo 'path/to/file merge=ours' >> .gitattributes
git config --global merge.ours.driver true
単なる DOS セッションで、Windows 上の msysgit 1.6.3 を使って、簡単なシナリオでテストしてみましょう。
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/
さて、2つのファイルを作ってみましょう。どちらもコンフリクトを起こしますが、マージされるファイルは異なります。
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
2つの異なるgitブランチにあるこれら両方のファイルの内容に"conflict"を導入することにします。
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の友人です。もちろん、私は両方やっています。私はVirtualBoxセッションの中にUbuntuセッションを持っています)
として
コメント
によって
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
)
(別のバージョンを維持したい場合は、(1)の前に
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.
(Mergeで始まる行はその証明になります)
Gitのように、マージドライバを定義、結合、上書きすることができると考えてください。
-
調べる
<dir>/.gitattributes
(これは問題のパスと同じディレクトリにあります): は、他の.gitattributes
ディレクトリ内の -
次に
.gitattributes
(これは親ディレクトリにあります) を調べ、ディレクティブがまだ設定されていなければ -
最後に
$GIT_DIR/info/attributes
. このファイルは、ツリー内の設定を上書きするために使用されます。これは<dir>/.gitattributes
ディレクティブを上書きします。
結合というのは、複数のマージドライバを集約するという意味です。
ニック グリーン
のトライを行います。
コメントで
で、実際にマージドライバを結合しています。
python git ドライバで pom をマージする
を参照してください。
しかし
の質問にもあるように
にあるように、それはコンフリクトの場合にのみ動作します(両方のブランチで同時に修正)。
関連
-
[解決済み] Git で直近のローカルコミットを取り消すには?
-
[解決済み] 現在のGit作業ツリーからローカル(未追跡)ファイルを削除する方法
-
[解決済み] Git が追跡したファイルを .gitignore に登録したまま「忘れる」ようにするにはどうしたらいいですか?
-
[解決済み] ファイルをリセットしたり、特定のリビジョンに戻したりするにはどうすればよいですか?
-
[解決済み] リモート Git リポジトリの URI (URL) を変更するには?
-
[解決済み] 新しいローカルブランチをリモートの Git リポジトリにプッシュし、それを追跡するにはどうすればよいのでしょうか?
-
[解決済み] ローカルの Git リポジトリが元々クローンされた URL を特定するにはどうすればよいですか。
-
[解決済み】"git pull" でローカルファイルを強制的に上書きするには?
-
[解決済み】ローカルのGitブランチの名前を変更するには?
-
[解決済み] なぜGitでコミットする前にステージが必要なのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[git push] 解決策: ! [リモート拒否] master -> master (受信前のフックは拒否されました)
-
解決策 このリポジトリでは、別の git プロセスが実行されているようです。たとえば、「git commit」によって開かれたエディタなどです。
-
Git エラー: ヒント: リモートにあなたが持っていない作業が含まれているため、更新が拒否されました ヒント: あなたが持っていない作業です。
-
[解決済み] git merge -s ours "の "theirs "バージョンはありますか?
-
git-fatal: 設定されたプッシュターゲットがありません / 警告: store/README.md の LF は CRLF に置き換えられています。
-
[解決済み】Gitでのブランチ記述
-
[解決済み] git rebase、'local' と 'remote' を追跡する
-
[解決済み] 1つのレポの中で、ディレクトリごとに追加の.gitignoreを持つことはできますか?
-
[解決済み] IntelliJのShelveとGit stashの違いは何ですか?
-
[解決済み] Git: リモートブランチの情報を更新する