如何克隆具有特定版本/变更集的git存储库?

时间:2010-08-15 20:45:53

标签: git git-clone revision

如何克隆具有特定修订版的git存储库,就像我在Mercurial中常做的那样:

hg clone -r 3 /path/to/repository

16 个答案:

答案 0 :(得分:773)

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

再次回到最近的提交

$ git pull

答案 1 :(得分:164)

更新2 由于Git 2.5.0可以在配置变量 uploadpack.allowReachableSHA1InWant 的服务器端启用下面描述的功能,因此{{3}和GitHub feature request。请注意,默认情况下,某些Git服务器会激活此选项,例如Bitbucket Server自GitHub commit enabling this feature启用它。有关如何激活配置选项的详细信息,请参阅此version 5.5+

更新1 对于Git版本1.7 < v < 2.5,请使用git clone和git reset,如answer on Stackexchange

中所述

如果您不想获取完整存储库,那么您可能不应该使用clone。您始终可以使用fetch来选择要获取的分支。我不是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

答案 2 :(得分:49)

克隆一个git存储库,恰当地克隆整个存储库:没有办法只选择一个要克隆的修订版本。但是,执行git clone后,您可以通过checkout <rev>签出特定修订。

答案 3 :(得分:30)

如果你的意思是想要从一开始到特定的地方取得所有东西,Charles Bailey的回答是完美的。如果您想要反向并检索从当前日期返回的历史记录的子集,您可以使用git clone --depth [N],其中N是您想要的历史记录转数。但是:

  

- 深度

     
    

创建一个浅层克隆,其历史记录被截断为指定的修订版本数。浅存储库有许多限制(您不能克隆或获取它,也不能从中推送或插入它),但如果您只对历史悠久的大型项目的近期历史感兴趣并且希望将修补程序作为补丁发送。

  

答案 4 :(得分:24)

总结一下(git v.1.7.2.1):

  1. 定期git clone你想要回购(让所有东西都到期 - 我知道,不是想要什么,我们到达那里)
  2. 您想要的
  3. git checkout <sha1 rev>
  4. git reset --hard
  5. git checkout -b master

答案 5 :(得分:19)

TL; DR - 只需在源存储库中针对要克隆的提交创建一个标记,并在fetch命令中使用该标记。您可以稍后从原始仓库中删除标签以进行清理。

嗯,它的2014年看起来像Charles Bailey从2010年开始接受的答案已经过时了,而且大多数(所有?)其他答案都涉及克隆,许多人都希望避免这种做法。 / p>

以下解决方案实现了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

希望这个解决方案能够持续工作几年! : - )

答案 6 :(得分:10)

您只能使用git checkout <commit hash>

按此顺序

bash git clone [URLTORepository] git checkout [commithash]

commit hash看起来像这样“45ef55ac20ce2389c9180658fdba35f4a663d204”

答案 7 :(得分:7)

要在特定分支或标签上仅克隆单个特定提交,请使用

xpath

不幸的是,git clone --depth=1 --branch NAME https://github.com/your/repo.git 只能是分支名称或标记名称(不能提交SHA)。

省略NAME标志以下载整个历史记录,然后检出该分支或标记:

--depth

这与最新版本的git兼容(我对git clone --branch NAME https://github.com/your/repo.git 版使用)。

答案 8 :(得分:2)

使用以上2个答案(How to clone git repository with specific revision/changeset?How to clone git repository with specific revision/changeset?) 帮助我提出了一个决定性的。如果你想克隆到一个点,那么这一点必须是一个标签/分支,而不仅仅是一个SHA或FETCH_HEAD混淆。在git fetch set之后,如果你使用分支或标签名称,你得到一个响应,如果你只是使用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
remote: Counting objects: 45493, done.
remote: Compressing objects: 100% (15928/15928), done.
remote: Total 45493 (delta 27508), reused 45387 (delta 27463)
Receiving objects: 100% (45493/45493), 53.64 MiB | 50.59 MiB/s, done.
Resolving deltas: 100% (27508/27508), done.
From /var/www/html/ui
 * branch            origin_point -> FETCH_HEAD
 * [new branch]      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将整批货物上传回新家。

希望能帮到某人

答案 9 :(得分:2)

我的版本是已接受和最受欢迎的答案的组合。但它有点不同,因为每个人都使用SHA1但没有人告诉你如何获得它

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

现在你可以看到所有分支&amp;提交

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

最后你知道所需提交的SHA1

git reset --hard <sha1>

答案 10 :(得分:2)

git clone https://github.com/ORGANIZATION/repository.git(克隆存储库)

cd repository (navigate to the repository)

git fetch origin 2600f4f928773d79164964137d514b85400b09b2

git checkout FETCH_HEAD

答案 11 :(得分:0)

简单。您只需要为当前分支设置上游

free(array);

全部

答案 12 :(得分:0)

我将此代码段与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 $@




答案 13 :(得分: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,则无法获得没有历史记录的修订,而您可以为其创建标签并克隆特殊标签。

答案 14 :(得分:0)

我能够使用 git clone --config 选项完成此操作,这是我从这个答案中了解到的: https://stackoverflow.com/a/43759576/1330650

我的场景涉及 Azure DevOps 管道中的稀疏检出,我需要使用提交哈希而不是分支名称克隆存储库。 clone 命令不接受提交哈希作为参数。解决方法是设置一个包含 refspec 的配置变量 (-c),因为该 refspec 可以使用提交哈希而不是分支名称:

git clone -c remote.origin.fetch=+<commit hash>:refs/remotes/origin/<commit hash> <repo_url> --no-checkout --progress --depth 1
git sparse-checkout init --cone
git sparse-checkout set <file list>
git checkout <commit hash>

答案 15 :(得分:-5)

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

git使用origin这个词而不是众所周知的revision

以下是手册$ git help clone

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