如何使用 git-archive 包含裸存储库中的子模块?

发布于 2024-10-27 21:02:11 字数 473 浏览 1 评论 0原文

我正在设置部署脚本。基本流程是:

  1. 将更改推送到服务器上的裸存储库
  2. 然后基于新标签将创建一个用于发布的新文件夹。
  3. 使用 git archive 将文件移动到发布目录
  4. 运行一些迁移脚本并将其投入使用(如果一切成功)。

问题是我的存储库包含一个子模块,该子模块不会放入存档中,因此不会放入发布目录中。

我见过 git-archive-all,但这在裸存储库上不起作用。

如果不可能,我正在考虑

  1. 使存储库不裸露,并更新工作副本,这将允许我使用 git-archive-all。或者
  2. 在服务器上有子模块的第二个裸存储库,我可以从中获取存档(必须对此进行研究以确保我获得正确的修订版)。

I'm in the process of setting up a deployment script. The basic process is:

  1. Push changes to a bare repository on the server
  2. Then based on new tags will create a new folder for the release.
  3. Use git archive to move the files into the release directory
  4. Runs some migrations scripts and puts it live (if all is successful).

The issue is my repository contains a submodule, which doesn't get put in the archive, and therefore doesn't get put in the release directory.

I've seen git-archive-all, but that doesn't work on a bare repository.

If its not possible, I'm considering,

  1. making the repository not bare, and updating the working copy, which would allow me to use git-archive-all. Or
  2. having a second bare repository of the submodule on the server, which I could get an archive from (would have to look into this to make sure I'm getting the right revision).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

你怎么敢 2024-11-03 21:02:11

基于此处的答案和评论。您可以创建非裸存储库并运行:

git ls-files --recurse-submodules | tar caf ../prog.tar.gz -T-
  • 要处理以连字符开头的文件,请使用 --verbatim-files-from
  • 要将文件放入存档内的文件夹中,请使用 --xform s: ^:prog/:

完整版:

git ls-files --recurse-submodules | tar caf ../prog.tar.gz --xform s:^:prog/: --verbatim-files-from -T-

Based on answers and comments here. You can create non-bare repo and run:

git ls-files --recurse-submodules | tar caf ../prog.tar.gz -T-
  • To handle files starting with hypen, use --verbatim-files-from
  • To put files in folder inside the archive, use --xform s:^:prog/:

Full version:

git ls-files --recurse-submodules | tar caf ../prog.tar.gz --xform s:^:prog/: --verbatim-files-from -T-
硪扪都還晓 2024-11-03 21:02:11

我使用这个 python 包 https://github.com/Kentzo/git-archive-all。您可以使用 OSX 上的命令来安装它

pip install git-archive-all

,也可以使用 brew install git-archive-all 来安装它

I use this python package https://github.com/Kentzo/git-archive-all. You can install it by using

pip install git-archive-all

On OSX, you can install it also using brew install git-archive-all

记忆里有你的影子 2024-11-03 21:02:11

如果您的子模块位于可从服务器访问的存储库中,我宁愿有一个接收后挂钩,它将

  • 更新完整的非裸存储库(因此除了原始裸存储库之外还有第二个存储库),包括子模块(git子模块更新 --init)
  • 来自第二个存储库的 git archive (您一定会获得正确的版本,因为非裸存储库将引用子模块的正确版本)
    由于非裸存储库将包含父存储库及其子模块,因此 git archive-all 将能够检测 .git 子目录并将存档所有内容

如果子模块无法从服务器访问,则意味着:

  • 需要将其推送到服务器上自己的存储库中
  • 父存储库中的子模块需要使用相对路径进行引用,以便父存储库仍然可用一旦推送到服务器上就能够检索所述子模块。

If your submodule is in a repo accessible from the server, I would rather have a post-receive hook which would

  • update a full non-bare repo (so a second repo beside your original bare one), including the submodule (git submodule update --init)
  • git archive from that second repo (you would be sure to get the right version since the non-bare repo would reference the right version of the submodule)
    Since the non-bare repo would contain the parent repo and its submodules, git archive-all would be able to detect the .git subdirectories and would archive everything.

If the submodule isn't accessible from the server, that means:

  • it needs to be pushed in its own repo on the server
  • the submodule in the parent repo needs to be reference with a relative path, in order for the parent repo to still be able to retrieve said submodule once pushed on the server.
转瞬即逝 2024-11-03 21:02:11

这是几行:

prefix=$(basename "$(pwd -P)")
{
  git ls-files
  git submodule foreach --recursive --quiet \
                'git ls-files --with-tree="$sha1" | sed "s#^#$path/#"'
} | sed "s#^#$prefix/#" | xargs tar -c -C.. -f "$prefix.tar.xz" --

Here it is as a few-liner:

prefix=$(basename "$(pwd -P)")
{
  git ls-files
  git submodule foreach --recursive --quiet \
                'git ls-files --with-tree="$sha1" | sed "s#^#$path/#"'
} | sed "s#^#$prefix/#" | xargs tar -c -C.. -f "$prefix.tar.xz" --
用心笑 2024-11-03 21:02:11

我的案例构建系统依赖 git 来了解它构建的源代码的版本。
为了创建完整 git 树的非常小的存档保留 git,我使用了

git clone --recursive --progress [email protected]:myrepo --shallow-submodules --depth 1

提示 -只有超级大的存储库才需要深度超长的历史或大量的大文件。就我而言,浅克隆有助于将 .git 包的大小从 2.5GB 减小到 94MB

然后从工作树中删除文件,除了 .git

cd myrepo/
fd -IH '[^(.git)]' --max-depth 1 --exec-batch rm -rf --

fd 可能是通过apt install fd-find安装,也可以使用默认的util find或bash的extglob

下一步压缩解

cd ..
tar cvzf myrepo.tgz myrepo/

压缩

tar xf myrepo.tgz
cd myrepo
git checkout -f --recurse-submodules

现在所有工作树都是在实际状态下。

使用 --depth 1 你总是只有一个分支和唯一的一次提交。


最后要注意的是,

不可能一次克隆仓库裸露和递归,因为子模块 git 需要实际的工作树。

--recurse-submodules[=]
创建克隆后,根据提供的路径规范初始化并克隆其中的子模块。如果没有路径规范
前提是,所有子模块都被初始化和克隆。对于由以下组成的路径规范,可以多次给出此选项
多个条目。生成的克隆将 submodule.active 设置为提供的路径规范或“。” (指所有子模块)如果
没有提供路径规范。

子模块使用其默认设置进行初始化和克隆。这相当于运行 git submodule update --init
--克隆完成后立即递归。如果克隆的存储库没有,则忽略此选项
工作树/签出(即,如果 --no-checkout/-n--bare--mirror 中的任何一个给出了

I my case build system relies on git to know version of source code it builds from.
To create a very minimal archive of full git tree keeping git i used

git clone --recursive --progress [email protected]:myrepo --shallow-submodules --depth 1

hint --depth is required for only super big repos with super long history or with amount of big files. in my case shallow cloning helps to reduce size of .git pack from 2.5GB to 94MB

then remove files from worktree except .git

cd myrepo/
fd -IH '[^(.git)]' --max-depth 1 --exec-batch rm -rf --

fd could be installed via apt install fd-find, also can use default util find or bash's extglob

next step compress

cd ..
tar cvzf myrepo.tgz myrepo/

uncompress

tar xf myrepo.tgz
cd myrepo
git checkout -f --recurse-submodules

now all worktree is in actual state.

with --depth 1 you always will have only one branch with the only one commit.


last note

there is no possibility to clone repo bare and recursive at a time, for submodules git requires actual worktree.

--recurse-submodules[=<pathspec>]
After the clone is created, initialize and clone submodules within based on the provided pathspec. If no pathspec is
provided, all submodules are initialized and cloned. This option can be given multiple times for pathspecs consisting of
multiple entries. The resulting clone has submodule.active set to the provided pathspec, or "." (meaning all submodules) if
no pathspec is provided.

Submodules are initialized and cloned using their default settings. This is equivalent to running git submodule update --init
--recursive <pathspec> immediately after the clone is finished. This option is ignored if the cloned repository does not have
a worktree/checkout (i.e. if any of --no-checkout/-n, --bare, or --mirror is given)

泪之魂 2024-11-03 21:02:11

在常规归档命令之后运行以下命令:
git submodule foreach 'cd REPO_ROOT/$path && git 归档头 | tar -x -C TARGET_ROOT/$path'

这里 REPO_ROOT 是您的存储库所在的位置,TARGET_ROOT 是您放置存档版本的位置。 (我假设您有一个 TARGET_ROOT 文件夹,其中包含第一个 git archive 调用的扩展版本。如果您想要最终的 zip/tar,可以 tar/zip 最终文件夹)

git 子模块foreach 提供$path 变量。有关更多详细信息,请参阅每个部分的 git help submodule

Run the following after the regular archive command:
git submodule foreach 'cd REPO_ROOT/$path && git archive HEAD | tar -x -C TARGET_ROOT/$path'

Here the REPO_ROOT is where your repo stands and the TARGET_ROOT is where you put your archived version. (I assume that you have a TARGET_ROOT folder where the expanded version of the first git archive call. If you want a final zip/tar, you can tar/zip the final folder)

git submodule foreach provides the $path variable. See git help submodule foreach section for more details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文