繁体   English   中英

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

[英]How to clone git repository with specific revision/changeset?

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

hg clone -r 3 /path/to/repository
$ git clone $URL
$ cd $PROJECT_NAME
$ git reset --hard $SHA1

再次回到最近的提交

$ git pull

更新 2Git 2.5.0 开始,可以在服务器端使用配置变量uploadpack.allowReachableSHA1InWant启用下面描述的功能,这里是GitHub 功能请求GitHub 提交启用此功能 请注意,某些 Git 服务器默认启用此选项,例如 Bitbucket Server 从5.5+ 版本开始启用它。 有关如何激活配置选项的示例,请参阅Stackexchange 上的答案

更新 1对于 Git 版本1.7 < v < 2.5使用 git clone 和 git reset,如Vaibhav Bajpai 的回答中所述

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

要在特定分支或标签上克隆一个特定的提交,请使用:

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 (我用版本2.18.0 )。

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

如果您的意思是要获取从开始到特定点的所有内容,那么 Charles Bailey 的答案是完美的。 如果您想反向操作并检索从当前日期返回的历史子集,您可以使用git clone --depth [N]其中 N 是您想要的历史转数。 然而:

- 深度

创建一个将历史记录截断为指定修订数量的浅层克隆。 浅层存储库有很多限制(你不能从它克隆或获取,也不能从它推入或推入),但如果你只对一个历史悠久的大型项目的近期历史感兴趣,并且想要将修复作为补丁发送。

总结一下(git v. 1.7.2.1):

  1. 在你想要仓库的地方做一个常规的git clone (让所有的东西都是最新的——我知道,不是想要的,我们正在那里)
  2. git checkout <sha1 rev>你想要的 rev
  3. git reset --hard
  4. git checkout -b master

您可以简单地使用git checkout <commit hash>

在这个序列中

bash git clone [URLTORepository] git checkout [commithash]

提交哈希看起来像这样“45ef55ac20ce2389c9180658fdba35f4a663d204”

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

好吧,它是 2014 年,看起来 Charles Bailey 从 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

希望这个解决方案还能再工作几年! :-)

无需下载整个历史记录,也无需调用git init

git clone --depth=1 URL
git fetch --depth=1 origin SHA1
git checkout SHA1
git branch -D @{-1}  # if you want to tidy up the fetched branch

对于 CB Baileys 的回答,这有一个缺点,即您仍然会下载 1 个不必要的修订版。 但它在技术上是一个git clone (OP 想要的),它不会强迫您下载某个分支的整个历史记录。

使用上述答案中的 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

然后创建我的新空白 repo,以我的本地副本作为其来源

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,作为一个新的 repo,所以我做了

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 --git-dir=../ui/.git format-patch -k -1 --stdout <sha1> | git am -3 -k git --git-dir=../ui/.git format-patch -k -1 --stdout <sha1> | git am -3 -k远程挑选樱桃然后使用git push origin将整个地块上传回新家。

希望能帮助某人

我的版本是接受和最受好评的答案的组合。 但它有点不同,因为每个人都使用 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>

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




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

克隆单个分支的完整工作流程,选择一个提交,然后检查该特定提交...此方法需要 git 版本 2.28.0 或更高版本才能使用选项--no-write-fetch-head ,已使用版本 2.35 进行测试。 3. (如果您已经知道所需提交的完整 sha1 hash,请跳至最终代码块中提供的第二种方法)

#Create empty git repo
mkdir repo && cd repo && git init

#add remote, configure it to track <branch>
git remote add --no-tags -t <branch> -m <branch> origin <url>

#fetch objects from remote repo
git fetch --no-write-fetch-head

#examine commits and logs to decide which one we will use
git log --oneline origin

#Once you have found the commit of interest copy the abbreviated hash or save as variable
commit=<sha1>

#rename our default branch to match remote branch
git branch -m <branch>

#set branch head to desired commit
git branch <branch> $commit

#set remote branch as upstream for <branch>
git branch -u origin <branch>

#All done time to checkout
git checkout

要选择性地截断本地分支的历史记录,请执行:

git fetch --no-write-fetch-head --depth <n> ./ <branch>

要截断远程分支历史记录,您可以执行以下操作,但请记住,如果您将历史记录截断为比您签出的提交更新的提交, git status将告诉您您已经从远程分支<n>提交

git fetch --no-write-fetch-head --depth <n>

如果您不需要远程跟踪并且已经知道完整的提交 hash:

mkdir repo && cd repo && git init
git remote --no-tags add origin <url>
git fetch --depth 1 --no-write-fetch-head origin <sha1>
#Set default local branch (master in this case) head to <sha1>
git branch master <sha1>
git checkout

在我看来,使这种方法更好的是它真正只获取一次提交。 我们还避免创建 FETCH_HEAD 或 ORIG_HEAD,使我们的 .git 目录干净利落。 这也使 reflog 保持干净(只有一个条目),而不是由于git reset --hard commit无需远程跟踪和使用fetch --depth 1它创建尽可能小的克隆(浅克隆) .

我能够使用 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>
mkdir linux-4.3.20151106
cd linux-4.3.20151106/
git init
git fetch git@github.com:torvalds/linux.git 9154301a47b33bdc273d8254c407792524367558

error: unknown option `no-write-fetch-head'        
usage: git fetch [<options>] [<repository> [<refspec>...]]   or: git fetch [<options>] <group>                                      
   or: git fetch --multiple [<options>] [(<repository> | <group>)...]   or: git fetch --all [<options>]       



 git --version
git version 2.17.1

export https_proxy=http://192.168.1.3:1080;export http_proxy=http://192.168.1.3:1080
add-apt-repository ppa:git-core/ppa
apt update
apt-get install --only-upgrade git

 git --version
git version 2.38.0


 git fetch git@github.com:torvalds/linux.git 9154301a47b33bdc273d8254c407792524367558 --no-write-fetch-head --depth=1 
remote: Enumerating objects: 54692, done.
remote: Counting objects: 100% (54692/54692), done.
remote: Compressing objects: 100% (50960/50960), done.
remote: Total 54692 (delta 3828), reused 29210 (delta 2966), pack-reused 0
Receiving objects: 100% (54692/54692), 147.35 MiB | 2.85 MiB/s, done.
Resolving deltas: 100% (3828/3828), done.
 


git branch master 9154301a47b33bdc273d8254c407792524367558


git checkout
 

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

cd repository (navigate to the repository)

git fetch origin 2600f4f928773d79164964137d514b85400b09b2

git checkout FETCH_HEAD

对于单个文件,当提交号已知时,可以使用 wget 在线工具:

wget https://raw.githubusercontent.com/torvalds/linux/896066ee1cf4d653057dac4e952f49c96ad16fa7/README

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

hg clone -r 3 /path/to/repository

您是否听说过Rigidhackpro是伪造的黑客,曾对我姐姐进行过尝试。 我可以向任何人开出的唯一真正合法的黑客专家是fasthackresults @ Gmail,com他是技术和信用评分操作的专家

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>.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM