PCにクローンを作成せずに、リモートGitリポジトリから特定のコミットを1つだけ取得する方法はありますか?リモートリポジトリの構造は私のものとまったく同じであるため、競合は発生しませんが、これを行う方法がわからないため、その巨大なリポジトリのクローンを作成したくありません。
私はgitを初めて使用しますが、方法はありますか?
Gitバージョン2.5以降(2015年第2四半期)以降、(完全なリポジトリのクローンを作成せずに)単一のコミットをフェッチすることが実際に可能です。
2015年5月21日、FredrikMedleyによるcommit68ee628を参照してください。moroten
gitster
これで、(サーバー側に)新しい構成ができました。
uploadpack.allowReachableSHA1InWant
upload-pack
任意の参照チップから到達可能なオブジェクトを要求するフェッチ要求を受け入れることを許可します。ただし、オブジェクトの到達可能性の計算には計算コストがかかることに注意してください。
デフォルトはfalse
。
そのサーバー側の構成を浅いクローン(git fetch --depth=1
)と組み合わせると、単一のコミットを要求できます(参照t/t5516-fetch-push.sh
:
git fetch --depth=1 ../testrepo/.git <full-length SHA1>
このコマンドを使用しgit cat-file
て、コミットがフェッチされたことを確認できます。
git cat-file commit <full-length SHA1>
「
git upload-pack
」は、 構成変数を使用git fetch
して、参照から到達可能である限り、参照の先端にないコミットを処理するように指示できます。uploadpack.allowReachableSHA1InWant
SHAは完全に省略されていないSHAである必要があることに注意してください。そうでない場合、Gitはコミットを見つけることができなかったと主張します
完全なドキュメントは次のとおりです。
upload-pack
:オプションで到達可能なsha1のフェッチを許可する
uploadpack.allowReachableSHA1InWant
サーバー側で構成オプションを設定すると、「」git fetch
は、アドバタイズされていないオブジェクト(帯域外またはサブモジュールポインターから取得された可能性が高い)を指定する「want」行を使用して要求を行うことができます。
ブランチチップから到達可能なオブジェクト、つまりアドバタイズされたブランチとによって隠されたブランチの結合のみtransfer.hideRefs
が処理されます。
到達可能性を確認するために履歴をさかのぼる必要があることに関連するコストがあることに注意してください。この機能は、sha1がわかっている特定のコミットのコンテンツを取得するときに使用できます。特に、浅いフェッチが使用されている場合は、リポジトリ全体のクローンを作成する必要はありません。
便利なケースは、例えば
- 履歴に大きなファイルを含むリポジトリ、
- サブモジュールのチェックアウトに必要なデータのみをフェッチし、
- 変更番号ではなくコミットの観点から考えると、sha1がどのブランチに属し、Gerritにあるかを正確に示さずに、sha1を共有する場合。( Gerritの変更にはすべて参照があるため、
Gerritのケースはすでに解決されています。)allowTipSHA1InWant
Git 2.6(2015年第3四半期)はそのモデルを改善します。ジェフキング()によるコミット2bc31d1、コミットcc118a6(2015年7月28日)を
参照してください。( Junio C Hamanoによってマージされました---コミット824a0be 、2015年8月19日)peff
gitster
refs
:ネガティブをサポートtransfer.hideRefs
構成を使用して参照の階層を非表示にした場合、
transfer.hideRefs
後でその構成をオーバーライドして「再表示」する方法はありません。
このパッチは「ネガティブ」非表示を実装しているため、別の一致で非表示にされた場合でも、一致はすぐに非表示としてマークされます。
通常の「最後の1つが勝つ」構成の優先順位が機能するように、構成機構によって提供される方法とは逆の順序で一致を適用するように注意します(.git/config
たとえば、のエントリはオーバーライドします/etc/gitconfig
)。だからあなたは今することができます:
git config --system transfer.hideRefs refs/secret git config transfer.hideRefs '!refs/secret/not-so-secret'
refs/secret
1つの特定のリポジトリの1つのパブリックビットを除いて、すべてのリポジトリに非表示にします。
Git 2.7(2015年11月/ 12月)は再び改善されます:
commit 948bfa2、commit 00b293e(2015年11月5日)、commit 78a766a、commit 92cab49、commit 92cab49、commit 92cab49(2015年11月3日)、commit 00b293e、commit 00b293e(2015年11月5日)、およびcommit 92cab49、commit 92cab49、commit 92cab49、Lukas Fleischer()による92cab49(2015年11月3日)をコミットします。
支援者:Eric Sunshine()。( Jeff Kingによってマージされました---コミットdbba85e、2015年11月20日)lfos
sunshineco
peff
config.txt
hideRefs
:名前空間を使用してのセマンティクスを文書化する
現在、
transfer.hideRefs
名前空間が設定されたときにどのように動作するかについての明確な定義はありません。その場合、プレフィックスは削除された名前と一致
することを説明します。hideRefs
これはhideRefs
、現在、receive-packでパターンが処理される方法です。
hiddenRefs:完全な参照を照合するためのサポートを追加します
hideRefs
ストリップされた参照の一致に加えて、完全な(ストリップされていない)参照が一致するパターンを追加できるようになりました。
削除された一致と完全な一致を区別するには、これらの新しいパターンの前に曲折アクセント記号(^
)を付ける必要があります。
したがって、新しいドキュメント:
transfer.hideRefs:
transfer.hiderefs
名前空間が使用されている場合、名前空間プレフィックスは、パターンと照合される前に各参照から削除されます。
たとえば、refs/heads/master
がで指定されtransfer.hideRefs
、現在の名前空間がで あるfoo
場合、thenrefs/namespaces/foo/refs/heads/master
はアドバタイズメントから省略されますが、いわゆる「have」行としてアドバタイズされます。 ストリッピングする前に参照を一致させるには、参照名の前にを追加します。とを組み合わせる場合は、最初に指定する必要があります。refs/heads/master
refs/namespaces/bar/refs/heads/master
^
!
^
!
R ..は、コメントの中でconfigに言及しています。uploadpack.allowAnySHA1InWant
これにより、任意のオブジェクトを要求する要求upload-pack
を受け入れることができます。fetch
(デフォルトはfalse
)。
David "novalis"Turnerによるcommitf8edeaa(2016年11月、Git v2.11.1)を参照してください( ):novalis
upload-pack
:オプションで任意のsha1のフェッチを許可する
ユーザーがリポジトリ内のすべてに絶対にアクセスすることを信頼している場合、到達可能性チェックを行うのは少しばかげているようです。
また、分散システムでは際どいものです。おそらく1つのサーバーが参照をアドバタイズしますが、別のサーバーはその参照を強制的にプッシュし、2つのHTTPリクエストがこれらの異なるサーバーに送信される可能性があります。
Git 2.34(Q4 2021)では、(man)の反対側で実行される " " ( man)は、git upload-pack
want - ref要求を処理するときにref名前空間を考慮するのを忘れていました。git fetch
Kim Altintop()によるcommit 53a66ec、commit 3955140、commit bac01c6(2021年8月13日)を参照してください。( Junio C Hamanoによってマージされました---コミット1ab13eb、2021年9月10日)kim
gitster
docs
:transfer.hideRefsと名前空間の相互作用を明確にするサインオフ-作成者:Kim Altintop
レビュー者:Jonathan Tan
のドキュメントの名前空間に関するセクションを展開して、との微妙な違いを
transfer.hideRefs
指摘します。upload-pack
receive-pack
3955140( "
upload-pack.c
:名前空間に関連するwant-refを処理する"、2021-07-30、Git v2.34.0-バッチ#5にリストされているマージ)は、非表示の参照のsを拒否するように教えられました。 非表示のrefの名前が明らかになることはありませんが、それが指すオブジェクトIDは明らかになる可能性があります。upload-pack
want-ref
git config
現在、そのマニュアルページに含まれています:
transfer.hiderefs
パターンと照合される前の参照。ストリッピングする前に参照を一致させるに^
は、参照名の前にを追加します。!
とを組み合わせる場合は^
、!
最初に指定する必要があります。
git config
現在、そのマニュアルページに含まれています:
広告から省略されています。
uploadpack.allowRefInWant
が設定さ れている場合、protocolv2 コマンドで存在しないかのようupload-pack
に扱います。 一方、refが指しているオブジェクトIDは、その名前(いわゆる「e」行)を指定せずにアドバタイズします。want-ref refs/heads/master
fetch
refs/namespaces/foo/refs/heads/master
receive-pack
.hav
クローンを作成するのは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 fetch origin specific_commit
git checkout -b temp FETCH_HEAD
好きな名前「temp」...このブランチは孤立している可能性があります
'git ls-remote'(http://git-scm.com/docs/git-ls-remote)はあなたが望むことをするべきだと思います。強制的にフェッチまたはプルする必要はありません。
最後に、 gitcherry-pickを使用して特定のコミットを複製する方法を見つけました。ローカルにリポジトリがなく、リモートから特定のコミットをプルしていると仮定すると、
1)ローカルおよびgitinitに空のリポジトリを作成します
2)git remote add origin " url-of-repository "
3)git fetch origin [これにより、マージしない限り、ファイルはローカルワークスペースに移動されません]
4)gitcherry-pick「Enter-long-commit-hash-that-you-need」
これで、ローカルにその特定のコミットからのファイルのみが保存されます。
これは、-> git log --pretty=onelineを使用して取得できます
要求されたコミットがリモートリポジトリのプルリクエストにある場合は、その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
プロジェクトで問題が発生したため、特定のコミットに戻らなければなりませんでした。次のコマンドで正常に完了しました。
git reset --hard <commitID>