特定のリビジョン/チェンジセットでGitリポジトリを複製する方法は?


393

Mercurialで通常行うように、特定のリビジョンでgitリポジトリを複製するにはどうすればよいですか。

hg clone -r 3 /path/to/repository

3
ないチェンジセットリビジョンに固有の、しかし、特定のブランチの最新のクローンを作成することは効果的なつまりとすることができ git clone -b 10.1 https://github.com/MariaDB/server.git --depth=1 mariadb-server-src
MrMesees


履歴を浅くしますか?つまり、例ではリビジョン3のみを含めますか、それとも親ですか?
sschuberth 2017年

問題のリポジトリが別のリポジトリ内から複製されていて、その内部リポジトリを特定のshaで複製したい場合、gitサブモジュールは自動的にそれを自動的に行います。
J0hnG4lt 2017年

回答:


202

UPDATE 2 Git 2.5.0以降、以下で説明する機能は構成変数を使用してサーバー側で有効にできますuploadpack.allowReachableSHA1InWant。ここでは、GitHub機能リクエストGitHubコミットがこの機能を有効にしています。一部のGitサーバーはデフォルトでこのオプションをアクティブにします。たとえば、Bitbucket Serverはバージョン5.5以降で有効になっています。Stackexchangeでこの回答を参照してください構成オプションをアクティブにする方法のについては、Stackexchangeで。

UPDATE 1 Gitバージョンの1.7 < v < 2.5場合、「git clone」と「git reset」を使用します。 Vaibhav Bajpaiの回答でます。

完全なリポジトリを取得したくない場合は、おそらくを使用しないでくださいclone。いつでもフェッチを使用して、フェッチするブランチを選択できます。私はhgの専門家ではないので詳細はわかりません-rが、gitでは次のようなことができます。

# make a new blank repository in the current directory
git init

# add a remote
git remote add origin url://to/source/repository

# fetch a commit (or branch or tag) of interest
# Note: the full history up to this commit will be retrieved unless 
#       you limit it with '--depth=...' or '--shallow-since=...'
git fetch origin <sha1-of-commit-of-interest>

# reset this repository's master branch to the commit of interest
git reset --hard FETCH_HEAD

32
私はうまくいくとは思いませんgit fetch origin <sha1>。タグやブランチ名などの名前付き参照を渡す必要があるようです。kerneltrap.org/mailarchive/git/2009/1/13/4707444を
artur

48
@artur:動作しないと思いますか、それとも試してみましたが動作しませんか?
CBベイリー、

37
git 1.4ではgit fetch origin <SHA1>、リモートからマスターをフェッチしreset --hard、ブランチをローカルで実際にインスタンス化した後、を使用して必要なリビジョンに切り替えることができることがわかりました。個々のリビジョンを直接取得することができませんでした。git 1.7では、git fetch origin <SHA1>@ arturによって報告されたように機能しませんでした。をgit checkout <SHA1>続けて使用する必要がありますreset --hard
ジョーマクマホン

6
SHA-1によるフェッチは、httpおよびrsyncプロトコルでのみ機能します。kerneltrap.org/mailarchive/git/2009/1/14/4716044/…を
CharlesB

23
この回答は古くなっています。これはgit 1.7またはgit 1.8では機能せず、https://またはsshプロトコルでも機能しません。( "リモート参照df44398762393c67af487edeb0831ad9579df4aa"が見つかりませんでした–これは参照ではなく、コミットです。)
PaŭloEbermann 14

839
$ git clone $URL
$ cd $PROJECT_NAME
$ git reset --hard $SHA1

再び最新のコミットに戻るには

$ git pull

13
これは、commitがmasterブランチにある場合にのみ機能し、そうでない場合はローカル参照を混乱させます。そもそもなぜgit checkoutではなくgit resetなのですか?
Joky、

72
これはすべてを取得するため、大規模なリポジトリの場合は適切なオプションではありません。
シークレット

1
このソリューションは一番上にある必要があります。それが「最適ではない」ことを誰も気にしません。それがOPが要求したものです。具体的には、「特定のリビジョンでgitリポジトリを複製するにはどうすればよいですか」?
Florian Segginger 2016年

20
@FlorianSegginger特定のリビジョンのクローンを作成する場合、おそらくすべてをクローンしたくはなく、そのリビジョンだけをクローンしたいでしょう。私にはそれが尋ねられた質問でした。このソリューションは、「リポジトリ内の特定のリビジョンをどのように表示しますか?」という別の質問に答えます。リポジトリ全体をフェッチすることは、ここで多くの人が避けたいことです。
Renato

1
クローン中にリビジョンを指定できる--depthため、大規模なリポジトリにとって非常に重要な使用が可能になるため、実際の質問のIMHOには対応していません。このソリューションでは、すべてのオブジェクトをプルしてから、以前のリビジョンにリセットする必要があります。これは非常に時間がかかり、ネットワーク帯域幅を浪費します。
void.pointer 2018

54

gitリポジトリを複製すると、リポジトリ全体が適切に複製されます。複製するリビジョンを1つだけ選択する方法はありません。ただし、を実行するとgit clone、を実行して特定のリビジョンをチェックアウトできますcheckout <rev>


4
1つのリビジョンだけを複製したくありません。クローンの制限を指定したいだけです。つまり、指定したリビジョンまでのすべてを複製したいのです。
John

6
それはできません。git cloneリポジトリ全体を取得します。取得したら、特定のリビジョンをチェックアウトできます。

4
注意すべき点が1つあります。Gitは通常、履歴の保存に関してかなり効率的であるため、リビジョンの半分だけを複製するだけで大​​量のスペースを節約するようなものではありません。
2010

それは「スペースを節約する」ことではなく、特定のリビジョンにたどり着くことだけが目的です。たとえば、新しい変更がバグを導入した場合など、その最新の変更はしたくないのですが、Gitは実行できません。この?それは正しくありません-古いバージョンにロールバックできないのに、なぜソース管理があるのでしょうか?
BrainSlugs83 2013

1
:あり、はい- 「クローンへの唯一の1つのリビジョンを選択する方法はありません」git clone --single-branch ...
morxaは

33

1つの特定のコミットのみを複製するには特定のブランチまたはタグでには、以下を使用します。

git clone --depth=1 --branch NAME https://github.com/your/repo.git

残念ながら、 NAMEブランチ名またはタグ名しか使用できません(SHAをコミットしないでください)。

--depthフラグを省略して履歴全体をダウンロードし、そのブランチまたはタグをチェックアウトします。

git clone --branch NAME https://github.com/your/repo.git

これは最近のバージョンのgitで動作します(私はversionで実行しました2.18.0)。


古いバージョン2.17.1ではない
RzR

4
これにはもっと賛成票が必要です。これは他の古い回答よりもはるかに優れています。
エティエンヌ

32

最初から特定のポイントまですべてを取得したい場合は、Charles Baileyの回答が最適です。逆を行い、現在の日付からさかのぼって履歴のサブセットを取得したい場合git clone --depth [N] は、Nが必要な履歴の回転数を使用できます。しかしながら:

-深さ

指定したリビジョン数に切り捨てられた履歴を持つ浅いクローンを作成します。浅いリポジトリにはいくつかの制限があります(クローンを作成したり、そこからフェッチしたり、そこからプッシュしたりすることはできません)が、長い歴史を持つ大規模プロジェクトの最近の履歴のみに関心があり、修正をパッチとして送信します。


4
新しいバージョンのgitでは浅いクローンが改善されており、そこからプルしたりプッシュしたりできます。
orion78fr 2016年

26

要約すると(git v。1.7.2.1):

  1. 定期的に git cloneレポが欲しい場所でに実行します(日付までにすべてを取得します—私は知っています、何が望んでいるのではなく、私たちはそこに着いています)
  2. git checkout <sha1 rev> あなたが望む回転の
  3. git reset --hard
  4. git checkout -b master

6
ステップ3と4は何をしますか?
BrainSlugs83 2013

ステップ4ではうまくいきませんでしたが、ステップ3まではうまくいきました。ありがとう
Gene Bo

@ BrainSlugs83:ステップ4は、ローカルブランチを作成し、masterそれに切り替える。
LarsH

3
@phill:なぜgit reset --hard?そのためのドキュメントには、「インデックスと作業ツリーをリセットします。作業ツリー内の追跡ファイルへの変更は<commit> [デフォルトはHEADになり、現在は<sha1 rev>]なので破棄されます。」ただし、現時点ではクローン作成以降の変更はありません。その目的は何ですか。現在のブランチを切り捨て<sha1 rev>ますか?
LarsH

19

TL; DR-クローンを作成するコミットに対してソースリポジトリにタグを作成し、フェッチコマンドでタグを使用します。後で元のリポジトリからタグを削除してクリーンアップできます。

さて、その2014年とチャールズベイリーの2010年からの承認された回答は今では本当に古く、他の回答のほとんど(すべて?)はクローン作成に関するものであり、多くの人々はこれを避けたいと考えています。

次のソリューションは、OPや他の多くのユーザーが求めているものを実現します。これは、履歴を含むが特定のコミットまでのリポジトリのコピーを作成する方法です。

以下は、特定のポイントまでローカルリポジトリ(つまり、別のディレクトリのリポジトリ)を複製するためにgitバージョン2.1.2で使用したコマンドです。

# in the source repository, create a tag against the commit you want to check out
git tag -m "Temporary tag" tmptag <sha1>

# create a new directory and change into that directory
cd somewhere_else;mkdir newdir;cd newdir

# ...and create a new repository
git init

# add the source repository as a remote (this can be a URL or a directory)
git remote add origin /path/to/original/repo

# fetch the tag, which will include the entire repo and history up to that point
git fetch origin refs/tags/tmptag

# reset the head of the repository
git reset --hard FETCH_HEAD

# you can now change back to the original repository and remove the temporary tag
cd original_repo
git tag -d tmptag

うまくいけば、このソリューションはさらに数年間機能し続けます!:-)


2
これは、あなたがリポジトリの所有者であるという良い考えです。あなたが維持していない公開リポジトリで動作するかどうかは
わかり

18

簡単に使える git checkout <commit hash>

この順序で

bash git clone [URLTORepository] git checkout [commithash]

コミットハッシュは「45ef55ac20ce2389c9180658fdba35f4a663d204」のようになります


以前のように-クローンした後にチェックアウトする理由。クローンを作成すると、ローカルリポジトリに完全な履歴が残ります。この回答に賛成票が多すぎるのはなぜですか?
ドミトリーPerfilyev

2

上記の回答のうち2つを使用する(特定のリビジョン/チェンジセットでgitリポジトリのクローンを作成する方法および特定のリビジョン/チェンジセットでgitリポジトリのクローンを作成する方法?)ポイントまでクローンを作成する場合、そのポイントは単なるSHAではなくタグ/ブランチでなければならず、FETCH_HEADが混乱します。git fetchセットに続いて、ブランチまたはタグ名を使用すると、応答が返されます。SHA-1を単に使用すると、応答が返されません。
これが私がやったことです:-実際の元から、完全なリポジトリの完全に機能するクローンを作成します

cd <path to create repo>
git clone git@<our gitlab server>:ui-developers/ui.git 

次に、興味深い場所にローカルブランチを作成します

git checkout 2050c8829c67f04b0db81e6247bb589c950afb14
git checkout -b origin_point

次に、ローカルコピーを起点として新しい空のリポジトリを作成します

cd <path to create repo>
mkdir reduced-repo
cd reduced-repo
git init
git remote add local_copy <path to create repo>/ui
git fetch local_copy origin_point

その時点で私はこの反応を得ました。上記のブランチの代わりにSHA-1を使用した場合、何も起こらないため、応答が機能したことを意味するため、

/ var / www / html / ui-hacking $ git fetch local_copy origin_point
リモート:オブジェクトのカウント:45493、完了。
リモート:オブジェクトの圧縮:100%(15928/15928)、完了。
リモート:合計45493(デルタ27508)、再利用45387(デルタ27463)
オブジェクトの受信:100%(45493/45493)、53.64 MiB | 50.59 MiB /秒、完了。
デルタの解決:100%(27508/27508)、完了。
/ var / www / html / uiから
 *ブランチorigin_point-> FETCH_HEAD
 * [新しいブランチ] origin_point-> origin / origin_point

さて、私の場合、私はそれをgitlabに戻す必要がありました。

git remote add origin git@<our gitlab server>:ui-developers/new-ui.git

つまり、git --git-dir=../ui/.git format-patch -k -1 --stdout <sha1> | git am -3 -kリモートでリモートで選択するために使用してorigin_pointからリポを再構築し、それを使用git push originしてロット全体を新しいホームにアップロードすることができました。

誰かを助けることを願っています


「FETCH_HEADが混乱する」とはどういう意味ですか?そして、あなたのgit fetch local_copy origin_pointJamesGsとの違いは何 git fetch origin refs/tags/tmptagですか?
not2qubit 2017

git fetch local_copy origin_point空のreduced-repoディレクトリがある状態のままにします.git。これらの指示に他に欠けているものがあります...
not2qubit

2

私のバージョンは、受け入れられた回答と最も賛成された回答の組み合わせでした。しかし、それは少し異なります。誰もがSHA1を使用していますが、誰もそれを取得する方法を教えていないからです。

$ git init
$ git remote add <remote_url>
$ git fetch --all

今、あなたはすべてのブランチとコミットを見ることができます

$ git branch -a
$ git log remotes/origin/master <-- or any other branch

最後に、必要なコミットのSHA1を知っています

git reset --hard <sha1>

1

GNU makeでこのスニペットを使用して、リビジョンタグ、ブランチ、ハッシュを閉じます

gitバージョン2.17.1でテストされました

${dir}:
    mkdir -p ${@D}
    git clone --recursive --depth 1 --branch ${revison} ${url} ${@} \
 || git clone --recursive --branch ${revison} ${url} ${@} \
 || git clone ${url} ${@}
    cd ${@} && git reset --hard ${revison}
    ls $@





0

git clone https://github.com/ORGANIZATION/repository.git (リポジトリのクローンを作成)

cd repository (navigate to the repository)

git fetch origin 2600f4f928773d79164964137d514b85400b09b2

git checkout FETCH_HEAD


2
クローンした後でフェッチする理由 クローンを作成すると、ローカルリポジトリに完全な履歴が残ります。なぜこの回答には2つの賛成票があるのですか?
madhairsilence

0
# clone special tag/branch without history
git clone  --branch=<tag/branch> --depth=1 <repository>


# clone special revision with minimal histories
git clone --branch <branch> <repository> --shallow-since=yyyy-MM-ddTHH:mm:ss  # get the commit time
cd <dir>
git reset --hard <revision> 

uploadpack.allowReachableSHA1InWant=trueサーバー側で設定されていない場合、履歴なしでリビジョンを取得することはできませんが、そのためのタグを作成し、代わりに特別なタグを複製することができます。


-3

それは簡単です。現在のブランチのアップストリームを設定するだけです

$ git clone repo
$ git checkout -b newbranch
$ git branch --set-upstream-to=origin/branch newbranch
$ git pull

それで全部です


-4
git clone -o <sha1-of-the-commit> <repository-url> <local-dir-name>

gitorigin広く知られている代わりに単語を使用しますrevision

以下はマニュアルからの抜粋です $ git help clone

--origin <name>, -o <name>
    Instead of using the remote name origin to keep track of the upstream repository, use <name>.

4
なぜあなたはここで反対票を投じているのかわからない。これはまさに私のユースケースで見たかったことです。Linuxカーネルの特定のバージョンを、リリースとしてタグ付けする意味がなかったバージョンから取得しました(RPiの人々に問題があるようです)。 Linuxのマルチギガバイトの履歴全体をダウンロードします。ちなみに、それは御馳走を働いた。
Fordi

1
--depth=1回答で言及されていないので、ここで言及されていないものをさらに追加した場合、なぜこの回答はうまくいったと思いますか?問題が解決したことを嬉しく思いますが、この回答は誤解を招くものであり、一部でも質問に回答するものではありません。したがって、反対票。
Emil Styrke、2015年

5
@Fordi:いいえ。この答えをそのまま使用すると、バニラから得られるのとまったく同じツリーが得git clone <url> <local_dir_name>られます。自分で試してみてください。唯一の違いは、リモート(を使用して示されているgit remote)は、慣習的な "origin"という名前ではなく、いくつかの不可解なsha1シーケンスと呼ばれることです。言い換えれば、<sha1-of-the-commit>この回答で言及されていることは、サーバーからフェッチされたリビジョンやチェックアウトされるブランチには何関係もありません。
Emil Styrke、2015年

6
@Fordi:私はやったgit clone -o 896066ee1cf4d653057dac4e952f49c96ad16fa7 https://github.com/torvalds/linux.git linux --depth=1。これは私に修正8a28d674を与えます、そしてあなたとこの答えが主張するようにではありません 896066ee
Emil Styrke、2015年

4
「起源」は「改訂」とは何の関係もないことを強調し、この答えは完全に間違っています。
Eevee、2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.