自分のPCでクローンを作成せずに、リモートGitリポジトリから特定のコミットを1つだけ取得する方法はありますか?リモートリポジトリの構造は私のものと全く同じです、そしてそれ故にいかなる衝突もありませんが、私はこれを行う方法がわからないので、私はその巨大なリポジトリをクローンしたくありません。
私はgitに慣れていません、何か方法はありますか?
Gitバージョン2.5以降(2015年第2四半期)から、(完全なレポのクローンを作成せずに)単一のコミットを取得することは実際には可能です。
2015年5月21日の Fredrik Medley(moroten
) による commit 68ee628 を参照してください。
( commit a9d3493 の Junio 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 2bc31d1 、 commit 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 948bfa2 、 commit 00b293e (2015年11月5日)、 commit 78a766a 、 commit 92cab49 、 commit 92cab49 、 コミット92cab49 (2015年11月3日)、 コミット00b293e 、 コミット00b293e (2015年11月5日)、および コミット92cab49 、 commit 92cab49 、 commit 92cab49 、 commit 92cab49 (2015年11月3日)〜 Lukas Fleischer(lfos
) 。
手助け: Eric Sunshine(sunshineco
) 。
(2015年11月20日、 commit dbba85e に Jeff King - peff
- がマージされました。)
config.txt
:hideRefs
のセマンティクスを名前空間と共に文書化する今のところ、名前空間が設定されたときに
transfer.hideRefs
がどのように振る舞うべきかの明確な定義はありません。
その場合、hideRefs
プレフィックスは削除された名前と一致することを説明します。これがhideRefs
パターンが現在receive-packでどのように扱われるかです。hideRefs:全参照のマッチングのサポートを追加しました
削除された参照の照合に加えて、完全な(削除されていない)参照が照合される
hideRefs
パターンを追加できるようになりました。
削除されたものと完全に一致したものを区別するために、これらの新しいパターンの前に曲折アクセント記号(^
)を付ける必要があります。
それゆえ 新しいドキュメント :
transfer.hideRefs:
ネームスペースが使用されている場合、ネームスペース接頭辞は
transfer.hiderefs
パターンと照合される前に各参照から取り除かれます。
例えば、refs/heads/master
がtransfer.hideRefs
で指定され、現在のネームスペースがfoo
である場合、refs/namespaces/foo/refs/heads/master
は広告から除外されますが、refs/heads/master
とrefs/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要求が最終的にこれらの異なるサーバーに送信されます。
クローン作成は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
として保存されます。
私はGitリポジトリを引っ張った。
git pull --rebase <repo> <branch>
Gitがブランチのためのすべてのコードを引き込むことを許可して、それから私は私が興味を持ったコミットへのリセットをやり直しました。
git reset --hard <commit-hash>
お役に立てれば。
あなたは単にリモートリポジトリの単一のコミットを取得することができます
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
これはあなたを "分離ヘッド"状態にするでしょう。
次のコマンドでリモートレポジトリを取得することができます。
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
最後に、 git cherry-pick を使用して特定のコミットを複製する方法を見つけました。ローカルにリポジトリがなく、リモートから特定のコミットを行っているとします。
1)ローカルに空のリポジトリを作成し、 git init
2) git remoteでOriginを追加 "url-of-repository"
3) git fetch Origin [マージしない限り、ファイルはローカルのワークスペースに移動されません]
4) git cherry-pick "必要なハッシュ値を入力してください"
この方法では、あなたはあなたのローカルでその特定のコミットからのファイルだけを持つことになります。
- > git log --pretty = oneline を使ってこれを取得できます。
私は 'git ls-remote'( http://git-scm.com/docs/git-ls-remote )があなたが望むことをするべきだと思います。無理矢理引っ張ったり引っ張ったりしないで。
これは最もうまくいきます:
git fetch Origin specific_commit
git checkout -b temp FETCH_HEAD
name "temp"あなたが望むものは何でも...このブランチは孤児かもしれません
要求されたコミットがリモートリポジトリのプルリクエストにある場合、その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