Git:リモートの起点マスターから単一のファイルを更新/チェックアウトする方法は?


362

シナリオ:

  1. 私はローカルに1つのファイルにいくつかの変更を行い、実行git addgit commitおよびgit push
  2. ファイルはリモートオリジンマスターリポジトリにプッシュされます
  3. Capistranoを介してデプロイされた別のローカルリポジトリがあり、そのリモートリポジトリから "remote_cache"メソッドを使用しています
  4. アプリケーション全体をデプロイするのではなく、その単一のファイルを更新/チェックアウトします。

これはどういうわけかgitで可能ですか?うまくいくものを見つけることができず、それを理解することもできませんでした。SVNを使って、やっただけsvn up fileです。


19
承認された回答を、実際に質問に回答する回答に変更することを検討してください。;)
手順

6
以上の6年後、私たちは安全、これは@stepsが起こるのではないだろうと仮定することができます信じている...
フェリックス・ガニオン-グルニエ

Git 2.23(2019年8月)では、ですgit restore -s origin/master -- path/to/file以下の私の答えを参照しください。
VonC

回答:


914

(デプロイされたリポジトリで)行うことが可能です

git fetch
git checkout origin/master -- path/to/file

フェッチは最近の変更をすべてダウンロードしますが、現在のチェックアウトされたコード(作業領域)には入れません。

チェックアウトは、ダウンロードされた変更からの特定のファイルで作業ツリーを更新します(origin/master)。

少なくともこれは、ファイル内の1つの単語を変更するだけのためにブランチなどを作成するのは変だと感じる、小さな小さなタイプミスの修正に対して機能します。


1
これはとても便利です。本番サイトの残りのサイトを更新する前に、composer.jsonファイルを取得して更新を実行する必要がありました。composer.json / lockファイルを手動で配置した場合、プルを実行すると、ファイルがすでに存在すると言って競合します。このようにすることで、gitは問題なくファイルを認識しました。
David

6
これが私が探していた答えです。
javadba 14

20
@Mymozaaa二重ダッシュは、後に続くものがファイル名であることを示します。残念なことに、同じ名前のファイルが2つある場合に、gitがファイル名をブランチとして解釈しないようにするためです。
ジョエルメロン

問題は、まだフェッチしているということです。それが大きなレポである場合、それはコストのかかる操作になります。gitwebをリモートにインストールし、それにアクセスしてファイルなどを取得するのが唯一の代替策だと私は恐れています。
クリスチャンゲッツェ2017年

小さな質問、それを行った後、私は別のマシンに行き、次に上記のアクションを実行しますが、git statusそれらをChanges to be committed:-意味として、もう一度コミットする必要があると思いますか?(私は単一の変更されていないファイルを更新したかったが、リポジトリ自体が別のマシンで変更されたことに注意してください)
Ricky Levi


19
git archive --format=zip --remote=ssh://<user>@<host>/repos/<repo name> <tag or HEAD> <filename> > <output file name>.zip

1
これはssh経由で複製されたリポジトリの良い解決策ですが、httpsではサポートされていないよう git archive --remote=https://github.com/git/git.git master:git/contrib/completion git-completion.bash | tar -x です:エラーメッセージが表示されます:fatal: Operation not supported by protocol.
Alderath

1
素敵と組み合わせたtar:S --to-stdoutgit archive --remote="gitolite3@<host>:<repo>" <tag> <file> | tar xf - --to-stdout
Puggan Seの

19

Git 2.23(2019年8月)と、git restoreステージング領域からではなく、作業ディレクトリからすべてのファイルをリセットする方法は?」に示されている新しい(まだ実験的な)コマンドを使用すると、次のようになります。

git fetch
git restore -s origin/master -- path/to/file

アイデアはgit restore、ファイルのみを扱い、ファイルブランチは扱いgit checkoutません。
混乱git checkout」を参照してください:そこにgit switch来る場所です)


codersamコメントに追加します

私の場合、上流からデータ取得したかった(そこから分岐した)。
したがって、次のように変更しました:

git restore -s upstream/master -- path/to/file

2
このコマンドがついに存在したことの何の救済... git-cluefullの人々は以前に何をしていましたか?私はすべてを復元し、必要な個々のファイルをコピーしていましたが、苦痛でした。
マイクワイズ

これは私にとってはうまくいきましたが、私の場合、上流からデータを取得したいと思いました(そこから分岐しました)。したがって、次のように変更されましたgit restore -s upstream/master -- path/to/file
coderSam

@coderSamこのフィードバックをありがとうございます。見やすくするために、回答にコメントを含めました。
VonC

8

あなたができることは:

  1. ローカルのgitリポジトリを更新します。

    git fetch

  2. ローカルブランチを作成してチェックアウトします。

    git branch pouet && git checkout pouet

  3. このブランチに必要なコミットを適用します。

    git cherry-pick abcdefabcdef

    (abcdefabcdefは、適用するコミットのsha1です)


4
余談ですが、2番目のステップは1つのコマンドでとして実行することもできますgit checkout -b pouet
グレッグヒューギル

4
「pouet」は、この例に最適なブランチ名です。
Hussard、2016

2

または、現在のブランチでgit stash(変更がある場合)、マスターのチェックアウト、最新の変更の取得、デスクトップ(またはアプリ全体)へのそのファイルの取得。あなたがいたブランチをチェックアウトします。Git stashは現在の状態に戻り、手動で変更を修正するか、ドラッグしてファイルを置き換えます。

この方法はすごくかっこいいわけではありませんが、他に何も理解できない場合はうまくいきます。


-10

私は簡単なハックを見つけたと思います。

ローカルリポジトリにあるファイル(リモートサーバーの最新のコミットから更新するファイル)を削除します。

そして次に git pull

ファイルが削除されるため、競合は発生しません


これにより、そのファイルにローカルで加えられた最終的な変更がすべて削除され、他のすべてのファイルもプルされます。これは、特にOPが実行したくないことです。
legrojan

リモートブランチを更新する代わりに、ローカルを削除することは非常に悪い考えです。
c0der512
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.