做一个“git export”(比如“svn export”)?

问:

我一直想知道是否有一个好的“git 导出”解决方案可以创建一个没有 .git 存储库目录的树的副本。我知道的方法至少有以下三种:

git clone 然后删除 .git 存储库目录。 git checkout-index 暗示了此功能,但以“只需将所需的树读入索引…”开头,我不完全确定该怎么做。 git-export 是一个第三方脚本,它本质上是将 git 克隆到一个临时位置,然后 rsync --exclude=‘.git’ 到最终目的地。

这些解决方案中没有一个真正让我感到满意。最接近 svn export 的可能是选项 1,因为两者都要求目标目录首先为空。但是选项 2 似乎更好,假设我可以弄清楚将树读入索引意味着什么。

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

答1:

与HuntsBot一起,探索全球自由职业机会–huntsbot.com

实现此目的的最简单方法可能是使用 git archive。如果你真的只需要扩展的树,你可以做这样的事情。

git archive master | tar -x -C /somewhere/else

大多数时候,我需要从 git 中“导出”某些东西,无论如何我都想要一个压缩存档,所以我做这样的事情。

git archive master | bzip2 >source-tree.tar.bz2

压缩包:

git archive --format zip --output /full/path/to/zipfile.zip master 

git help archive 有关更多详细信息,它非常灵活。

请注意,即使存档不包含 .git 目录,它也会包含其他隐藏的特定于 git 的文件,如 .gitignore、.gitattributes 等。如果您不希望它们在存档中,请确保您在 .gitattributes 文件中使用 export-ignore 属性并在归档之前提交它。 Read more…

注意:如果你有兴趣导出索引,命令是

git checkout-index -a -f --prefix=/destination/path/

(有关详细信息,请参阅 Greg’s answer)

ZIP 存档:git archive --format zip --output /full/path master

请注意,存档将不包含 .git 目录,但将包含其他隐藏的 git 特定文件,如 .gitignore、.gitattributes 等。因此,如果您不想要它们,请确保使用 export-ignore 属性一个 .gitattributes 文件并在归档之前提交它。请参阅feeding.cloud.geek.nz/2010/02/…

要跟进 Streams 的注释:您可以在命令中添加一个 '--prefix=something/' 字符串来控制将打包在 zip 中的目录名称。例如,如果您使用 git archive --format zip --output /path/to/file.zip --prefix=newdir/ master,输出将被称为“file.zip”,但当您解压缩它时,顶级目录将是“newdir”。 (如果省略 --prefix 属性,顶级目录将是“文件”。)

最简单的方法:git archive -o latest.zip HEAD 它创建一个 Zip 存档,其中包含当前分支上最新提交的内容。请注意,输出格式由输出文件的扩展名推断。

它不支持 git 子模块 :(

答2:

huntsbot.com – 高效赚钱,自由工作

我发现了选项 2 的含义。从存储库中,您可以执行以下操作:

git checkout-index -a -f --prefix=/destination/path/

路径末尾的斜杠很重要,否则将导致文件位于 /destination 中,前缀为“路径”。

由于在正常情况下索引包含存储库的内容,因此“将所需的树读入索引”没有什么特别的事情要做。它已经在那里了。

-a 标志是检查索引中所有文件所必需的(我不确定在这种情况下省略这个标志意味着什么,因为它不符合我的要求)。 -f 标志强制覆盖输出中的任何现有文件,此命令通常不会这样做。

这似乎是我正在寻找的那种“git export”。

...并且不要忘记最后的斜线,否则您将无法获得预期的效果;)

git add 命令更改索引中的内容,因此无论 git status 显示为“待提交”的内容都是 HEAD 和索引内容之间的差异。

@conny:阅读您的评论,忘记了它并在没有尾部斜杠的情况下运行命令。提示:听从康尼的建议 -.-

+1 康尼的建议。另外,不要尝试创建“~/dest/”,因为这会在您的工作目录中创建一个名为“~”的目录,而不是您真正想要的。猜猜当你盲目地输入 rm -rf 会发生什么~

@KyleHeironimus - 如果您在前缀路径周围使用引号告诉shell不要执行波浪号扩展,那么您关于使用'~/dest/的警告是正确的。一个名为 ~ 的目录(不是 ‘~’ !)将在您的工作目录中创建。在这方面,git checkout-index 没有什么特别之处:mkdir ‘~/dest’ 也是如此(不要那样做!)。避免需要引用的文件名的另一个很好的理由(例如,其中有空格):-)`

答3:

huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。

git archive 也适用于远程存储库。

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master | tar -xf -

要在 repo 中导出特定路径,请添加任意数量的路径作为 git 的最后一个参数,例如:

git archive --format=tar \
--remote=ssh://remote_server/remote_repository master path1/ path2/ | tar -xv

这是我最喜欢的选项。它还有一个额外的好处,那就是它也适用于裸存储库。

改进的版本是:git archive --format=tar --prefix=PROJECT_NAME/ --remote=USER@SERVER:PROJECT_NAME.git master | tar -xf -(确保您的存档位于文件夹中)

注意:服务器必须启用此功能。

我试过了:git archive --format=zip --output foo.zip --remote=https://github.com/xxx.git master 并得到了致命的:协议不支持操作。命令流意外结束。

@andyf GitHub 有自己的方式:curl -L https://api.github.com/repos/VENDOR/PROJECT/tarball | tar xzf - 每docs

答4:

huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。

https://i.stack.imgur.com/p73W2.png

如果存储库托管在 GitHub 上,则为特殊情况的答案。

只需使用 svn export。

据我所知 Github 不允许archive --remote。尽管 GitHub 是 svn compatible 并且他们确实可以访问所有 git repos svn,因此您可以像往常一样使用 svn export,只需对您的 GitHub url 进行一些调整。

例如,要导出整个存储库,请注意 URL 中的 trunk 如何替换 master(或任何 project’s HEAD branch is set to):

svn export https://github.com/username/repo-name/trunk/

您可以导出单个文件甚至某个路径或文件夹:

svn export https://github.com/username/repo-name/trunk/src/lib/folder

使用 jQuery JavaScript 库的示例

HEAD 分支或 master 分支将可使用 trunk:

svn ls https://github.com/jquery/jquery/trunk

非HEAD 分支 可在 /branches/ 下访问:

svn ls https://github.com/jquery/jquery/branches/2.1-stable

/tags/ 下的所有 标签 以相同的方式:

svn ls https://github.com/jquery/jquery/tags/2.1.3

git archive 在 GitHub 上运行良好,只要您使用 git 协议,只需将 URL 中的 https:// 替换为 git:// 即可。我不知道为什么 GitHub 不宣传这个隐藏功能。

@NeilMayhew 这对我不起作用,我得到 fatal: The remote end hung up unexpectedly。使用 jQuery github repo 在两个不同的服务器上进行了尝试。

你是对的。我忘记了我使用 git config url..insteadOf 来缓存远程存储库。因此,我实际上使用的是 file:// URL。我怀疑 git archive 是否可以与 git:// URL 一起使用,因为它需要能够在远程端运行 git-upload-archive。应该可以使用 ssh 协议,但 github 不允许它 (Invalid command: 'git-upload-archive')。

如果我想在内部托管的 git 存储库上进行操作,有什么方法可以使用表现得像 github 的本地服务器工具?

赞成——Git 没有这个功能真是太奇怪了,我们不得不求助于 svn

答5:

huntsbot.com – 高效赚钱,自由工作

从 Git Manual:

使用 git-checkout-index “导出整棵树”

前缀功能基本上使得使用 git-checkout-index 作为“导出为树”功能变得微不足道。只需将所需的树读入索引,然后执行以下操作:

$ git checkout-index --prefix=git-export-dir/ -a

我认为混淆是“将所需的树读入索引”这句话。

如果你想在分支栏中导出目录 foo,那么这将是 git read-tree bar:foo 然后 git checkout-index --prefix=export_dir/ -a 之后也许你应该做 git update-index master

@JohnWeldon 是否需要您先克隆存储库?如果是这样,那么我不会接受它,因为子目录的“svn export”的全部意义在于直接获取该子目录的副本;如果有人有一个 1GB 的 Git 存储库,而我想要的只是一个 10kB 的子目录,那么要求我克隆整个东西是很疯狂的。

此外,我会回显@davetron5000,并附上评论“将所需的树读入索引”,我不知道这意味着什么。

答6:

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

我围绕 git-checkout-index 编写了一个简单的包装器,您可以像这样使用它:

git export ~/the/destination/dir

如果目标目录已存在,则需要添加 -f 或 --force。

安装简单;只需将脚本放在 PATH 中的某个位置,并确保它是可执行的。

The github repository for git-export

这个包装器不是平台无关的;它依赖于/bin/sh。因此,如果您使用的是 Windows,则此解决方案可能不适合您。

呃,这个脚本有 57 行文档、空白、设置、参数解析,只有一行实际做了一些事情......

答7:

huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求

与 SVN 相比,这似乎对 Git 来说不是问题。 Git 只在存储库根目录中放置一个 .git 文件夹,而 SVN 在每个子目录中放置一个 .svn 文件夹。所以“svn export”避免了递归命令行魔法,而使用 Git 递归是不必要的。

从 SVN 1.7 开始,也只有一个 .svn 文件夹:subversion.apache.org/docs/release-notes/1.7.html#single-db

这不会摆脱 svn export 删除的任何其他构建文件。所以这绝对不是答案。

答8:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

相当于

svn export . otherpath

在现有的回购中是

git archive branchname | (cd otherpath; tar x)

相当于

svn export url otherpath

git archive --remote=url branchname | (cd otherpath; tar x)

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

谢谢,这就是我所缺少的...另外,要检查导出的时间戳(它们不会像在文件上那样保留),请使用 git archive --format=tar --prefix=junk/ HEAD | (tar -t -v --full-time -f -) ...但是,使用时间戳归档并不是一件容易的事,所以我发布了 example below。

您可以对 tar 使用 C 选项而不是子 shell,如下所示:git archive branchname | tar xC otherpath

注意 tar 的 C 选项仅是 GNU Tar。

答9:

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

如果您没有使用 .gitattributes export-ignore 排除文件,请尝试 git checkout

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout -f -q

-f 从索引中检出路径时,不要在未合并的条目上失败;相反,未合并的条目将被忽略。

-q 避免冗长

此外,您可以获取任何分支或标签或从特定的提交修订版,如在 SVN 中只需添加 SHA1(Git 中的 SHA1 等同于 SVN 中的修订号)

mkdir /path/to/checkout/
git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout 2ef2e1f2de5f3d4f5e87df7d8 -f -q -- ./

/path/to/checkout/ 必须为空,Git 不会删除任何文件,但会覆盖同名文件而不会发出任何警告

更新:为避免斩首问题或在使用带有标签、分支或 SHA1 的签出导出时保持工作存储库完整,您需要在末尾添加 – ./

双破折号 – 告诉 git,破折号之后的所有内容都是路径或文件,在这种情况下,也告诉 git checkout 不要更改 HEAD

例子:

此命令将仅获取 libs 目录以及来自该确切提交的 readme.txt 文件

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout fef2e1f2de5f3d4f5e87df7d8 -f -q -- ./libs ./docs/readme.txt

这将创建(覆盖)my_file_2_behind_HEAD.txt 头部后面的两个提交 HEAD^2

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout HEAD^2 -f -q -- ./my_file_2_behind_HEAD.txt

获得另一个分支的出口

git --git-dir=/path/to/repo/.git --work-tree=/path/to/checkout/ checkout myotherbranch -f -q -- ./

请注意,./ 相对于存储库的根目录

实际上,在众多其他和赞成票中,这对我来说效果最好,没有任何压缩,与裸存储库(gitolite)一起工作得很好。

请注意,SHA1 签出将在存储库中创建“斩首”问题

实际上@ITGabs,这不会下载“.git”文件夹。所以下载的文件夹不是git仓库,所以技术上不算“斩首”

@FabioMarreco 斩首问题出在存储库上,不在导出/下载的文件中,我正在更新答案以获取更多详细信息

这对我很有用。但起初我收到“不是 git 存储库”错误消息。然后我发现“/path/to/repo/”必须指向.git文件夹。所以这有效:--git-dir=/path/to/repo/.git

答10:

保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com

我广泛使用 git-submodules。这个对我有用:

rsync -a ./FROM/ ./TO --exclude='.*'

这不会遗漏名称以点开头的文件,例如 .htaccess?

一个好的解决方案,我会将 --exclude='.*' 更改为 --exclude='.git*'

--exclude-vcs 如果你打算采取这种机智

./FROM/ 可以是远程仓库吗?

作为仅供参考,我的 rsync 副本将参数列为 --cvs-exclude。此外,它仍会复制 .gitattributes 和 .gitignore

答11:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

在寻找导出 git 存储库的方法时,我经常点击此页面。我对这个问题的回答考虑了 svn export 与 git 相比在设计上具有的三个属性,因为 svn 遵循集中存储库方法:

它通过不导出所有修订来最小化到远程存储库位置的流量

它不包含导出目录中的元信息

使用 svn 导出某个分支是通过指定适当的路径来完成的 git clone --depth 1 --branch master git://git.somewhere destination_path rm -rf destination_path/.git

在构建某个版本时,克隆一个稳定的分支(例如 --branch stable 或 --branch release/0.9)很有用。

如果目标存在且非空,则此方法不起作用。

唯一正确答案: 它来自深处。 git archive | tar 方法不适用于与 POSIX 不兼容的 shell 环境(例如,AppVeyor 的基于 CMD 或 PowerShell 的 CI) ,这是不理想的。 git checkout 方法修改了主工作树的索引,这很糟糕。 git checkout-index 方法需要预先修改主工作树的索引,这更糟糕。传统的 git clone 方法会在删除该历史记录之前克隆整个存储库的历史记录,这是一种浪费。这是剩下的唯一合理的解决方案。

要在本地导出,请注意要从中克隆的 Git 工作树的绝对路径应以 file:// 协议为前缀(例如,git clone --depth 1 --branch v3.14.15 file:///home/me/src_repo trg_repo)。否则将发出 "warning: --depth is ignored in local clones; use file:// instead." 并执行标准而不是浅层克隆,从而破坏了此答案的全部目的。 祝你好运!

原文链接:https://www.huntsbot.com/qa/KJvK/do-a-git-export-like-svn-export?lang=zh_CN&from=csdn

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值