没有.git目录的Git克隆

Jus*_*tin 134 git version-control git-clone

可能重复:
如何进行"git export"(如"svn export")

git做克隆时是否有传递给的标志,比如说不克隆.git目录?如果没有,.git克隆后删除目录的标志怎么样?

Ada*_*ruk 202

使用

git clone --depth=1 --branch=master git://someserver/somerepo dirformynewrepo
rm -rf ./dirformynewrepo/.git
Run Code Online (Sandbox Code Playgroud)
  • 深度选项将确保复制最少的历史记录以获得该回购.
  • 分支选项是可选的,如果未指定则获得master.
  • 第二行将使您的目录dirformynewrepo不再是Git存储库.
  • 如果您正在执行递归子模块克隆,则depth和branch参数不适用于子模块.

  • `!$`表示从前一个命令中取出最后一个参数. (46认同)
  • `!$/.git`是什么意思? (19认同)
  • 对于那些感兴趣的人,它是[字标识符]之一(https://gnu.org/software/bash/manual/html_node/Word-Designators.html),[历史扩展]的一部分(https:// www. Bash和zsh中的gnu.org/software/bash/manual/html_node/History-Interaction.html#History-Interaction)功能. (15认同)
  • 使用`!$`虽然在这个例子中技术上是正确的,但没有帮助那些不认识语法的人理解实际问题的答案.它还依赖于第一个命令直接跟在第一个命令之后,并且在同一个shell中.如果有人省略了这些隐含要求,他们最终可能会完全删除其他内容.因此,我建议您通过明确指定名称`dirformynewrepo`作为`rm`命令的参数来改进您的答案,因为它将使两个命令之间的连接更加清晰. (6认同)
  • 您可以使用--no-single-branch 选项来执行此操作,因为--depth 暗示--single-branch,您可以使用--no-single-branch 取消暗示它。(取自 git clone 手册页) (2认同)

Hua*_*Tao 26

因为你只需要文件,所以你不需要把它当作git仓库.

rsync -rlp --exclude '.git' user@host:path/to/git/repo/ .
Run Code Online (Sandbox Code Playgroud)

这仅适用于本地路径和远程ssh/rsync路径,如果远程服务器仅提供git://或https://访问,则它可能无效.

  • 如果源是一个裸仓库,这不起作用. (7认同)
  • 那么,如果服务器只提供 git:// 访问怎么办? (2认同)

Eri*_*ngs 14

或者,如果您安装了Node.js,则可以使用以下命令:

npx degit GIT_REPO

npxNode 附带,它允许您运行基于二进制节点的软件包,而无需先安装它们(或者,您可以先degit使用 全局安装npm i -g degit)。

Degit是由 Svelte 和 Rollup 的创建者 Rich Harris 创建的工具,他用它来通过克隆存储库而不保留 git 文件夹来快速创建新项目。但它也可以用来克隆任何仓库一次......


era*_*ros 11

git clone --separate-git-dir=$(mktemp -u) --depth=1 <repo> <dir> && rm <dir>/.git
Run Code Online (Sandbox Code Playgroud)

我更喜欢这个解决方案,因为我不喜欢rm -rf自动处理事情。它只是rm一个 .git 文件,这意味着它永远不会意外地出现rm -rf错误的 .git 目录

它依赖于mktemp命令,所以它可以在 *nix 系统上工作(据我所知,这需要进一步的工作才能mktemp在 MacOS 上工作,所以如果有人想评论一个工作解决方案,我会添加它)

在 zsh 中,我将其设为一个函数,以便确保dir定义了一个值:

alias np='node-project'
function node-project() {
  dir=${1:-.}
  git clone --separate-git-dir=$(mktemp -u) --depth=1 <my-node-repo> $dir && rm $dir/.git
}
Run Code Online (Sandbox Code Playgroud)

解释

--separate-git-dir标志允许您指定 .git 目录的路径。生成的“项目”将有一个 .git 文件(不是目录),其内容将是一行:

gitdir: <the dir you specified in the flag>
Run Code Online (Sandbox Code Playgroud)

因为我们在命令中使用了 tmp dir mktemp,所以实际的.git目录内容最终将位于 tmp dir 中。我们还使用了 a --depth=1,因此它在 tmp 目录上占用的空间更少。

  • 澄清一点 - 这仍然会创建一个“.git”等效文件夹,它只是存储在“mktemp”选择放置的位置,而不是“git clone”目的地。当您按照此答案执行“rm &lt;dir&gt;/.git”时,您实际上只是删除了使用普通“.git”文件在其他地方创建的 tmp 文件夹的符号链接。这些文件将被保留,直到操作系统进程自动清理“--separate-git-dir”使用的临时目录。因此,为了正确清理,您可能仍然需要“rm -rf”,仅适用于存储在临时文件夹而不是克隆目标中的“git”文件夹。 (4认同)

M I*_*ama 5

对于那些怀疑该--depth 1解决方案的人,因为它仍然下载.git目录并且您需要随后手动删除它,也许您需要知道git clone 实际上是如何工作的

当您通常克隆存储库时, git 将所有文件(跨越提交)下载到目录中.git。当您使用 克隆时--depth 1,git 仅将最新版本的文件下载到.git. 之后,git 将从工作目录中checkout检索这些文件.git(不再下载)。

通常,由于内部的文件对象是压缩的,因此通过下载文件而不是下载未压缩的文件.git可以节省更多带宽。git clone --depth 1对于一些网速慢的人来说,这是值得的(需要运行rm -rf)。

我个人认为git archive解决方案更好,但由于 GitHub 不支持它,所以--depth 1这是可行的方法。


小智 -2

你总是可以做

git clone git://repo.org/fossproject.git && rm -rf fossproject/.git
Run Code Online (Sandbox Code Playgroud)

  • 下载所有内容并稍后删除该目录?例如,emacs 的 .git 中有 95% 的 1GB。所以 --depth=1 显然是这里的解决方案。 (55认同)
  • 当我执行深度 = 1 时,我仍然看到 .git 文件夹 (2认同)
  • @AryehArmon 你当然看到了。使用 --depth 不会阻止创建 .git,它只是使其成为浅拷贝,因此 .git 的大小要小得多。但如果您根本不希望它存在,则需要随后将其删除。 (2认同)