web-dev-qa-db-ja.com

リモートのGitリポジトリから特定のコミットを取得する

自分のPCでクローンを作成せずに、リモートGitリポジトリから特定のコミットを1つだけ取得する方法はありますか?リモートリポジトリの構造は私のものと全く同じです、そしてそれ故にいかなる衝突もありませんが、私はこれを行う方法がわからないので、私はその巨大なリポジトリをクローンしたくありません。

私はgitに慣れていません、何か方法はありますか?

175
Varun Chitre

Gitバージョン2.5以降(2015年第2四半期)から、(完全なレポのクローンを作成せずに)単一のコミットを取得することは実際には可能です。

2015年5月21日の Fredrik Medley(moroten による commit 68ee628 を参照してください。
commit a9d3493Junio C Hamano - gitster - にマージされました、2015年6月1日)

これで新しい設定ができました(サーバー側)

uploadpack.allowReachableSHA1InWant

upload-packが任意のref tipから到達可能なオブジェクトを要求するフェッチ要求を受け入れることを許可します。ただし、オブジェクトの到達可能性の計算には計算コストがかかります。
デフォルトはfalseです。

そのサーバーサイドの設定を浅いクローン( git fetch --depth=1 )と組み合わせると、単一のコミットを要求できます( t/t5516-fetch-Push.sh を参照)。

git fetch --depth=1 ../testrepo/.git $SHA1

git cat-fileコマンドを使用して、コミットが取得されたことを確認できます。

git cat-file commit $SHA1

"git upload-pack"を提供する "git fetch"は、uploadpack.allowReachableSHA1InWant設定変数を使用して、それらがrefから到達可能である限り、どのrefの先端にもないコミットを提供するように指示することができます。


完全な資料は以下のとおりです。

upload-pack:オプションで到達可能なsha1の取得を許可

uploadpack.allowReachableSHA1InWant設定オプションがサーバー側で設定されていると、 "git fetch"は、アドバタイズされていない(帯域外またはサブモジュールポインタから取得された可能性が高い)オブジェクトを示す "want"行で要求を出すことができます。
分岐の先端から到達可能なオブジェクト、つまり、宣伝されている分岐とtransfer.hideRefsで隠されている分岐の和集合のみが処理されます。
到達可能性をチェックするために履歴を遡る必要があることには関連するコストがあります。

この機能は、sha1がわかっている特定のコミットの内容を取得するときに使用できます。特に、浅いフェッチを使用する場合は、リポジトリ全体を複製する必要はありません

便利な例は.

  • 歴史上大きなファイルを含むリポジトリ
  • サブモジュールのチェックアウトに必要なデータだけを取得する
  • 変更番号ではなくコミットの観点から考えると、それがどの正確なブランチに属しているのかを知らずにsha1を共有しているとき、そしてGerrit内で。
    (Gerritのすべての変更には参照があるため、Gerritのケースは既にallowTipSHA1InWantによって解決されています。)

Git 2.6(2015年第3四半期)はそのモデルを改善するでしょう。
commit 2bc31d1commit cc118a6 (2015年7月28日)by Jeff King(peff を参照してください。
commit 824a0be 内の Junio C Hamano - gitster - にマージされました、2015年8月19日)

refs:support negativetransfer.hideRefs

transfer.hideRefs設定を使用して参照の階層を非表示にした場合、後でその設定を上書きして「表示」する方法はありません。
このパッチは、たとえ他のマッチが隠していても、マッチが即座に隠されていないとしてマークされるようにする「否定的な」隠しを実装しています。
通常の "最後の1つが勝つ"という設定の優先順位(および.git/configのエントリなど)が有効になるため、一致の設定は、一致の設定を機械から受け取る方法とは逆の順序で適用します。 /etc/gitconfigをオーバーライドします。

それで、あなたは今することができます:

git config --system transfer.hideRefs refs/secret
git config transfer.hideRefs '!refs/secret/not-so-secret'

1つの特定のリポジトリの1つのパブリックビットを除いて、すべてのリポジトリでrefs/secretを非表示にする。


Git 2.7(2015年11月/ 12月)はまた改善するでしょう。

commit 948bfa2commit 00b293e (2015年11月5日)、 commit 78a766acommit 92cab49commit 92cab49コミット92cab49 (2015年11月3日)、 コミット00b293eコミット00b293e (2015年11月5日)、および コミット92cab49commit 92cab49commit 92cab49commit 92cab49 (2015年11月3日)〜 Lukas Fleischer(lfos
手助け: Eric Sunshine(sunshineco
(2015年11月20日、 commit dbba85eJeff King - peff - がマージされました。)

config.txthideRefsのセマンティクスを名前空間と共に文書化する

今のところ、名前空間が設定されたときにtransfer.hideRefsがどのように振る舞うべきかの明確な定義はありません。
その場合、hideRefsプレフィックスは削除された名前と一致することを説明します。これがhideRefsパターンが現在receive-packでどのように扱われるかです。

hideRefs:全参照のマッチングのサポートを追加しました

削除された参照の照合に加えて、完全な(削除されていない)参照が照合されるhideRefsパターンを追加できるようになりました。
削除されたものと完全に一致したものを区別するために、これらの新しいパターンの前に曲折アクセント記号(^)を付ける必要があります。

それゆえ 新しいドキュメント

transfer.hideRefs:

ネームスペースが使用されている場合、ネームスペース接頭辞はtransfer.hiderefsパターンと照合される前に各参照から取り除かれます。
例えば、refs/heads/mastertransfer.hideRefsで指定され、現在のネームスペースがfooである場合、refs/namespaces/foo/refs/heads/masterは広告から除外されますが、refs/heads/masterrefs/namespaces/bar/refs/heads/masterはいわゆる "have"行として広告されます。
削除する前に参照を一致させるには、参照名の前に^を追加します。 !^を組み合わせる場合は、最初に!を指定する必要があります。


R ..コメント内 _ config uploadpack.allowAnySHA1InWant に言及しています。これにより、upload-packは任意のオブジェクトを要求するfetchリクエストを受け入れることができます。 (デフォルトはfalse).

David "novalis" Turner(novalis _による commit f8edeaa (2016年11月、Git v2.11.1)を参照してください。

upload-pack:オプションで任意のsha1の取得を許可

ユーザーがリポジトリ内のすべてのものにアクセスすることを信頼している場合に、到達可能性チェックを行うのは少し愚かなようです。

また、分散システムでは怠け者です。おそらく1つのサーバーが参照をアドバタイズしますが、別のサーバーがその参照を強制プッシュしたため、2つのHTTP要求が最終的にこれらの異なるサーバーに送信されます。

96
VonC

クローン作成は1回だけなので、リモートリポジトリのクローンをすでに持っている場合は、そこから引っ張ってもすべてが再度ダウンロードされることはありません。どのブランチを引っ張りたいかを指定するか、変更を取得してコミットをチェックアウトしてください。

新しいリポジトリから取得することは、あなたが持っていない変更をダウンロードするだけなので、 とても 安い帯域幅です。 Gitが最小の負荷で正しいことをするという観点から考えてください。

Gitはすべてを.gitフォルダーに格納します。コミットをフェッチして単独で保存することはできません。すべての先祖が必要です。それらは 相互関係 です。


ただし、ダウンロードサイズを減らすために、gitに特定のブランチやコミットに関連するオブジェクトだけを取得するように依頼することができます。

git fetch Origin refs/heads/branch:refs/remotes/Origin/branch

これはリモートブランチbranch に含まれるコミット(そしてあなたが見逃しているもののみ) をダウンロードし、それをOrigin/branchに保存します。その後、マージまたはチェックアウトできます。

SHA1コミットだけを指定することもできます。

git fetch Origin 96de5297df870:refs/remotes/Origin/foo-commit

これにより、指定されたSHA-1 96de5297df870(およびその見逃し先祖)のコミットのみがダウンロードされ、(存在しない)リモートブランチOrigin/foo-commitとして保存されます。

93
CharlesB

私はGitリポジトリを引っ張った。

git pull --rebase <repo> <branch>

Gitがブランチのためのすべてのコードを引き込むことを許可して、それから私は私が興味を持ったコミットへのリセットをやり直しました。

git reset --hard <commit-hash>

お役に立てれば。

59
Piu Sharma

あなたは単にリモートリポジトリの単一のコミットを取得することができます

git fetch <repo> <commit>

どこで、

  • <repo>は、リモートリポジトリ名(例:Origin)またはリモートリポジトリURL(例:https://git.foo.com/myrepo.git)でもかまいません。
  • <commit>はSHA1コミットにすることができます

例えば

git fetch https://git.foo.com/myrepo.git 0a071603d87e0b89738599c160583a19a6d95545

コミット(そして行方不明の先祖)を取得した後は、次のようにしてチェックアウトできます。

git checkout FETCH_HEAD

これはあなたを "分離ヘッド"状態にするでしょう。

46
Flow

次のコマンドでリモートレポジトリを取得することができます。

git fetch <repo>

どこで、

  • <repo>は、リモートリポジトリ名(例:Origin)またはリモートリポジトリURL(例:https://git.foo.com/myrepo.git)でもかまいません。

例えば:

git fetch https://git.foo.com/myrepo.git 

リポジトリを取得した後、必要なコミットをマージすることができます(質問は1つのコミットを取得することですが、マージの代わりにcherry-pickを使用して1つのコミットを選択することもできます)。

git merge <commit>
  • <commit>はSHA1コミットにすることができます

例えば:

git cherry-pick 0a071603d87e0b89738599c160583a19a6d95545

または

git merge 0a071603d87e0b89738599c160583a19a6d95545

もしあなたがマージしたい最新のコミットであれば、FETCH_HEAD変数を使うこともできます。

git cherry-pick (or merge) FETCH_HEAD
16
Sérgio

最後に、 git cherry-pick を使用して特定のコミットを複製する方法を見つけました。ローカルにリポジトリがなく、リモートから特定のコミットを行っているとします。

1)ローカルに空のリポジトリを作成し、 git init

2) git remoteでOriginを追加 "url-of-repository"

3) git fetch Origin [マージしない限り、ファイルはローカルのワークスペースに移動されません]

4) git cherry-pick "必要なハッシュ値を入力してください"

この方法では、あなたはあなたのローカルでその特定のコミットからのファイルだけを持つことになります。

Enter-long-commit-hash:

- > git log --pretty = oneline を使ってこれを取得できます。

1
surya deepak

私は 'git ls-remote'( http://git-scm.com/docs/git-ls-remote )があなたが望むことをするべきだと思います。無理矢理引っ張ったり引っ張ったりしないで。

0
Hubbitus

これは最もうまくいきます:

git fetch Origin specific_commit
git checkout -b temp FETCH_HEAD

name "temp"あなたが望むものは何でも...このブランチは孤児かもしれません

0
Alexander Mills

要求されたコミットがリモートリポジトリのプルリクエストにある場合、そのIDで取得できます。

# Add the remote repo path, let's call it 'upstream':
git remote add upstream https://github.com/repo/project.git

# checkout the pull ID, for example ID '60':
git fetch upstream pull/60/head && git checkout FETCH_HEAD
0
Noam Manos