git 浅克隆到特定标签

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8932389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 06:22:22  来源:igfitidea点击:

git shallow clone to specific tag

git

提问by Chris H

I want to clone the Linux kernel repo, but only from version 3.0 onwards, since the kernel repo is so huge it makes my versioning tools run faster if I can do a shallow clone. The core of my question is: how can I tell git what the "n" value is for the --depth parameter? I was hoping this would work:

我想克隆 Linux 内核存储库,但只能从 3.0 版开始,因为内核存储库非常庞大,如果我可以进行浅层克隆,它会使我的版本控制工具运行得更快。我的问题的核心是:如何告诉 git --depth 参数的“n”值是多少?我希望这会奏效:

git clone http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git--depth v3.0

git 克隆http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git--depth v3.0

thanks.

谢谢。

回答by n8henrie

How about cloning the tag to a depth of 1?

将标签克隆到深度 1 怎么样?

  • git clone --branch mytag0.1 --depth 1 https://example.com/my/repo.git
  • git clone --branch mytag0.1 --depth 1 https://example.com/my/repo.git

Notes:

笔记:

  • --depth 1implies --single-branch, so no info from other branches is brought to the cloned repository
  • if you want to clone a local repository, use file://instead of only the repository path
  • --depth 1意味着--single-branch,因此不会将来自其他分支的信息带入克隆的存储库
  • 如果要克隆本地存储库,请使用file://而不是仅使用存储库路径

回答by James

Read fully for a solution, but unfortunately, git clone does not work in the fashion you are requesting. The --depthparameter limits the number of revisionsnot the number of commits. There is not a clone parameter which limits the amount of commits. In your situation, even if you knew that there were only at most 10 revision differences from the file that has changed the most between v3.0 and the newest HEAD in the repo and used --depth 10you could still get most or the whole repo history. Because some objects may not have as many as 10 revisions and you will get their history all the way back to the beginning of their first appearance in the repo.

完整阅读以获取解决方案,但不幸的是, git clone 无法按照您要求的方式工作。该--depth参数限制数量而revisions不是数量commits。没有限制提交数量的克隆参数。在您的情况下,即使您知道在 v3.0 和 repo 中最新 HEAD 之间变化最大的文件最多只有 10 个修订差异,并且使用过,--depth 10您仍然可以获得大部分或整个 repo 历史记录。因为有些对象可能没有多达 10 次修订,而且您将一直获得它们的历史记录,直到它们在 repo 中首次出现的开始。

Now here is how to do what you like: The key to your issue is that you need the commits between v3.0 and the recent most reference you want. Here are the steps I did to do just that:

现在这里是如何做你喜欢做的事情:你的问题的关键是你需要 v3.0 和你想要的最新引用之间的提交。以下是我为做到这一点所做的步骤:

  • git clone http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git --depth 10075 smaller_kernel_repo
  • cd smaller_kerenel_repo
  • Determine the sha of v3.0 git log --oneline v3.0^..v3.0
  • Create a graft point starting with this sha (it is 02f8c6aee8df3cdc935e9bdd4f2d020306035dbe)
  • echo "02f8c6aee8df3cdc935e9bdd4f2d020306035dbe" > .git/info/grafts
  • To get around some issues with some kernel log entries do: export GIT_AUTHOR_NAME="tmp"and export GIT_COMMITTER_NAME="tmp"

  • There is a nice warning about in the man page about git filter-branchrewriting history by following graft points... so lets abuse that, now run git filter-branchand sit back and wait...(and wait and wait)

  • git clone http://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git --depth 10075 smaller_kernel_repo
  • cd smaller_kerenel_repo
  • 确定v3.0的sha git log --oneline v3.0^..v3.0
  • 创建一个以这个 sha 开头的嫁接点(它是 02f8c6aee8df3cdc935e9bdd4f2d020306035dbe)
  • echo "02f8c6aee8df3cdc935e9bdd4f2d020306035dbe" > .git/info/grafts
  • 为了解决一些核心日志条目的一些问题做的事:export GIT_AUTHOR_NAME="tmp"export GIT_COMMITTER_NAME="tmp"

  • 在手册页中有一个很好的警告,关于git filter-branch通过遵循移植点重写历史记录......所以让我们滥用它,现在运行git filter-branch并坐下来等待......(等待并等待)

Now you need to clean up everything:

现在你需要清理一切:

git reflog expire --expire=now --all
git repack -ad  # Remove dangling objects from packfiles
git prune       # Remove dangling loose objects

This process is time consuming but not very complex. Hopefully it will save you all the time you were hoping for in the long run. At this point you will have is essentially a repo with an amended history of only v3.0 onwards from the linux-stable.git repo. Just like if used the --depthon clone you have the same restrictions on the repo and would only be able to modify and send patches from the history you already have. There are ways around that.. but it deserves its own Q&A.

这个过程很耗时,但不是很复杂。希望从长远来看,它可以为您节省所有的时间。在这一点上,您将拥有一个从 linux-stable.git 存储库开始,只有 v3.0 以后的修改历史记录的存储库。就像使用--depthon clone 一样,您对 repo 有相同的限制,并且只能修改和发送您已有的历史记录中的补丁。有很多方法可以解决这个问题……但它值得自己进行问答。

I am in the process of testing out the last few steps myself, but the git filter-branchoperation is still going. I'll update this post with any issues, but I'll go ahead and post it so you can start on this process if you find it acceptable.

我自己正在测试最后几步,但git filter-branch操作仍在进行。如果有任何问题,我会更新这篇文章,但我会继续发布它,以便您在认为可以接受的情况下开始此过程。

UPDATE

更新

Workaround for issue (fatal: empty ident <> not allowed). This issue stems with a problem in the commit history of the linux repo.

问题的解决方法(致命:空标识 <> 不允许)。此问题源于 linux 存储库的提交历史记录中的问题。

Change the git filter-branchcommand to:

git filter-branch命令更改为:

git filter-branch --commit-filter '
    if [ "$GIT_AUTHOR_EMAIL" = "" ];
    then
            GIT_AUTHOR_EMAIL="tmp@tmp";
            GIT_AUTHOR_NAME='tmp'
            GIT_COMMITTER_NAME='Me'
            GIT_COMMITTER_EMAIL='[email protected]'
            git commit-tree "$@";
    else
            git commit-tree "$@";
    fi '

回答by matt wilkie

For someone who already has a clone this command will get the number of commits between tip of current branch and the tag 5.6:

对于已经拥有克隆的人,此命令将获取当前分支的提示和标签之间的提交次数5.6

$ git rev-list HEAD ^5.6 --count
407

I found this project implementing rev-list using the GitHub API: https://github.com/cjlarose/github-rev-list

我发现这个项目使用 GitHub API 实现了 rev-list:https: //github.com/cjlarose/github-rev-list

The very lengthy man page on rev-listindicates there is a lot going on behind the scenes. There are many different paths to possibly count commits through with branches and merges coming and going. For this use case though that can probably be ignored(?)

rev-list上很长的手册页表明幕后有很多事情要做。有许多不同的路径可以计算通过分支和合并来来回回的提交。对于这个用例,虽然可能可以忽略(?)

回答by tomgi

Unfortunately the --depthparameter of git cloneaccepts only a number, the number of revisions to which the cloning repository should be truncated.

不幸的是,--depth参数git clone只接受一个数字,即克隆存储库应该被截断的修订数量。

A possible solution is to clone entire repository, and then truncate its history to keep only commits after v3.0. Here is a good how-to: http://bogdan.org.ua/2011/03/28/how-to-truncate-git-history-sample-script-included.html

一种可能的解决方案是克隆整个存储库,然后截断其历史记录以仅保留 v3.0 之后的提交。这是一个很好的操作方法:http: //bogdan.org.ua/2011/03/28/how-to-truncate-git-history-sample-script-included.html

git checkout --orphan temp v3.0
git commit -m "Truncated history"
git rebase --onto temp v3.0 master
git branch -D temp
git gc

回答by VonC

The --depthparameter seems to be only a number (the "specified numberof revisions"), not a tag.

--depth参数似乎只是一个数字(“指定的修订数量”),而不是一个标签。

Possible idea (to be tested):

可能的想法(有待测试):

You could use git describethough in order to get the most recent tag from you current HEAD, as well as the number of commit between said tag and HEAD.
If that "most recent tag" isn't your tag, simply repeat the process, starting from the commit referenced by that latest tag, up until you find your tag (v3.0in your case for instance).

您可以使用git describe虽然从当前 HEAD 中获取最新标签,以及所述标签和HEAD.
如果“最近的标签”不是您的标签,只需重复该过程,从该最新标签引用的提交开始,直到您找到您的标签(v3.0例如在您的情况下)。

The sum of all those commit numbers will give you the depth to give to the git clonecommand, provided your tag is accessible from your current HEAD.

所有这些的总和提交的数字会给你深度给予了git clone命令,只要你的标签是从当前访问HEAD