ローカル変更を維持するgit pull


132

アップストリームの変更がある場合でも、特定のファイルを変更せずにgitプロジェクトを安全に更新(プル)するにはどうすればよいですか?

myrepo / config / config.php

このファイルがリモートで変更されていたとしても、git pullすると他のすべてが更新されますが、このファイルは変更されていません(マージされていません)。

PS。私はgitベースのデプロイスクリプトを作成しているだけなので、私が求めていることを行う必要があります。設定ファイルをテンプレートに変更できません。

そのため、ローカルで変更された内容を失わない更新スクリプトを作成する方法が必要です。私は次のような単純なものを望んでいました:

git assume-remote-unchanged file1
git assume-remote-unchanged file2

その後 git pull


変更はconfig.phpコミットされますか?
Mark Longair、2012年


コミットされていません。私はむしろする必要はありません
ジョニーエバーソン

@JhonnyEverson:全体的に同じ問題クラスです(構成ファイルがあり、特定の設定をコミットしたくないが、構成ファイルの構造を追跡する必要がある。)
Daenyth

回答:


248

Git stashに基づく簡単な解決策があります。変更したものをすべて隠し、新しいものをすべて引き出し、隠し場所を適用します。

git stash
git pull
git stash pop

スタッシュポップでは競合が発生する可能性があります。あなたが説明する場合、実際にはとの衝突がありconfig.phpます。ただし、隠し場所に入れたものが必要なものであることがわかっているため、競合の解決は簡単です。これを行います:

git checkout --theirs -- config.php

5
そのgit checkout --theirsコマンドは非常に混乱します。それは私がかつて望んでいたことをし、別の時に本当に悪いことをしました。良いドキュメントはありますか?
ミリメトリック2013

3
はい、時には「彼ら」と「私たち」は混乱することがあります。でgit merge「私たち」作業ディレクトリ内に現在あるものです。しかしgit rebase(またはgit rebase -onto)の場合、意味が入れ替わることがあります。
GoZoner 2013

1
git stash , git pull , git stash apply 次の方法でgit stash drop
スタッシュ

11
gitの重要な点は、gitが何をするのかを理解する必要があるということです。gitのもう1つのことは、賢い人であっても、gitが何をするのかを理解するのが非常に難しいことです。
Brad Thomas

1
実際に隠しておくべきものがあるかどうかを確認する必要があります。それ以外の場合は、以前の隠された変更をポップしますgit stash
ジョーンReimerdes

15

ほとんどのプラーによってカスタマイズされることになっているファイルがリポジトリにある場合は、ファイルの名前をのように変更してにconfig.php.template追加config.phpします.gitignore


5
この回答も確認し.gitattributesてください。マージ中に常に変更を保持するために使用できます。
KurzedMetal

それは私が必要としていたものに似ています。テンプレートのことはエレガントなソリューションですが、デプロイスクリプトを作成しているだけなので、これは使用できません。
ジョニーエバーソン

6

更新:これは文字通り質問に答えますが、KurzedMetalの答えはあなたが本当に望んでいるものだと思います。

仮定して:

  1. あなたはブランチにいます master
  2. 上流分岐があるmasterorigin
  3. コミットされていない変更はありません

....できること:

# Do a pull as usual, but don't commit the result:
git pull --no-commit

# Overwrite config/config.php with the version that was there before the merge
# and also stage that version:
git checkout HEAD config/config.php

# Create the commit:
git commit -F .git/MERGE_MSG

頻繁に行う必要がある場合は、そのエイリアスを作成できます。へのコミットされていない変更がある場合config/config.php、これはそれらを破棄します。



1

質問に答えるには:チェックアウトの特定のファイルを除外する場合は、スパースチェックアウトを使用できます

1)で.git/info/sparse-checkout、保持するものを定義します。ここでは、すべての(*)が必要です(感嘆符に注意してください)config.php:

 /*
 !/config.php

2)スパースチェックアウトを考慮に入れたいことをgitに伝えます

 git config core.sparseCheckout true

3)このファイルをローカルで既に取得している場合は、gitがスパースチェックアウトで実行することを実行します(「skip-worktree」フラグを設定して、このファイルを除外する必要があることを伝えます)

git update-index --skip-worktree config.php

4)config.phpファイルが自分のものであるリポジトリをお楽しみください-リポジトリの変更は何でも。


構成値がソース管理に含まれていないことに注意してください:

  • これは潜在的なセキュリティ違反です
  • デプロイメントの場合、このような問題が発生します

つまり、それらを除外し(最初のコミットの前に.gitignoreに置く)、アプリをチェックアウトする各インスタンスに適切なファイルを作成する必要があります(「テンプレート」ファイルをコピーして変更することにより)

いったんgitがファイルを担当すると、.gitignoreは何の効果もないことに注意してください。

その場合、ファイルがソース管理下に置かれると、2つの選択肢()しかありません。-すべての履歴をリベースしてファイルを削除します(を使用git filter-branch)-ファイルを削除するコミットを作成します。それは敗戦の戦いのようなものですが、まあ、それと一緒に生きなければならないこともあります。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.