【问题标题】:git archive export with submodules (git archive all / recursive)带有子模块的 git 存档导出(git 存档全部/递归)
【发布时间】:2013-01-24 20:12:36
【问题描述】:

我有一个用 git 版本化的网站目录。我将子模块用于 Twitter Bootstrap、colorbox 和 lessjs 等所需库,因为我不应该跟踪源代码,而只跟踪我使用的代码版本。

现在我想部署项目,因此我也需要子模块代码。 通过使用git archive,我无法从子模块中获取源文件/代码。

以下三种方法尝试实现我想要的但不起作用: 第一种方法

#!/bin/sh

export revision="$1"

export GIT_INDEX_FILE=".git/tmpindex"
rm -f "$GIT_INDEX_FILE"

git read-tree $revision

export up="$(pwd)"

read_one_level () {
        export GIT_ALTERNATE_OBJECT_DIRECTORIES="$GIT_ALTERNATE_OBJECT_DIRECTORIES":$(
            git submodule foreach 'echo "$up/$path/.git/objects"' |
            grep -E -v '^(Entering|No submodule mapping found)' |
            tr '\n' : |
            sed 's/:$//'
        )

        git submodule foreach '
                cd "$up"
                subcommit=$(git rev-parse :"$path")
                git rm --cached "$path"
                git read-tree -i --prefix="$path/" $subcommit
        ' >/dev/null
}

while git ls-files -s | grep -q ^160000; do
    read_one_level
done

git archive --format=tar $(git write-tree)

rm -f "$GIT_INDEX_FILE" 

http://git.661346.n2.nabble.com/Running-git-archive-recursively-over-submodules-td4577012.html 中的托马斯·拉斯特

这给我在 Windows 和 Linux 上的错误,即找不到对象文件。

第二种方法 https://github.com/meitar/git-archive-all.sh

抱怨在 Windows 上找不到 mktemp。并且更正对git archive(来自git-archive)的调用不会在tar ...:(

第三种方法 https://github.com/Kentzo/git-archive-all

在我看来已经过时了,因为不兼容最新的 python 3.3,并且使用 2.7 仍然不能完全工作,因为 samefile 抱怨。

所以我现在的问题是: 最近有什么方法/方法来处理导出/归档一个包含子模块的 git 项目吗?

或者我应该检查这个工作流程的子树吗?

提前致谢

【问题讨论】:

  • 我是 Kentzo/git-archive-all 的作者。它现在兼容 python 3.3。还有什么问题?

标签: git-submodules git-archive


【解决方案1】:

https://github.com/Kentzo/git-archive-all 正如@Kentzo 所说,现在在 linux 下工作。

在 cygwin 环境中(通过 cygwin 安装程序安装了 git 和 python)它也可以在那里工作。

【讨论】:

  • git-archive-all 在 (pypi.org/project/git-archive-all) 可用,使用pip install git-archive-all 安装它...但注意:仅将 .tgz 格式作为输出文件。
  • 对不起,我刚刚检测到我的系统(Fedora 33)安装了1.17版本……最新版本没有tar、tar.gz、tar.xz等问题。
【解决方案2】:

我们可以做一个快速的 bash 脚本,在 tar、模块和子模块中存档,在我们连接 tar 和压缩之后,这里是一个包含 2 个子模块的示例:

#!/bin/bash

set -e

pwd=$(pwd)
date=$(date +%Y%m%d)
package=gitreponame
branch=master
name=tarbz2name
submodule1=/src/app/sub1/
submodule2=/src/sub2/

pushd ${package}
git checkout ${branch}
git pull
tag=$(git rev-list HEAD -n 1 | cut -c 1-7)
git archive --prefix="${name}/" --format=tar master > "$pwd"/${name}-${date}-${tag}.tar

git submodule update --init

cd ${submodule1}
git archive  --prefix="${name}${submodule1}" --format=tar master > "$pwd"/sb1.tar
cd -

cd ${submodule2}
git archive --prefix="${name}${submodule2}" --format=tar master > "$pwd"/sb2.tar
popd

tar -Af ${name}-${date}-${tag}.tar sb1.tar
tar -Af ${name}-${date}-${tag}.tar sb2.tar
bzip2 ${name}-${date}-${tag}.tar
rm sb1.tar sb2.tar

【讨论】:

    【解决方案3】:

    第二种方法:https://github.com/meitar/git-archive-all.sh 部署为独立的 Bash 脚本,并且似乎仍在维护中。我发现这是一种快速拍摄项目子模块快照的简单方法。它甚至可以捕获更早的版本(有点,见下文):

    git-archive-all.sh --tree-ish (tag) ## for example
    

    可能会或可能不会破坏交易的几个问题:

    • 我在尝试使用 --format 选项时遇到了问题 - 但默认值 tar 通常可以正常工作。

    • (非常)大问题:它捕获了我的子模块,但仅在其当前版本中 - 而不是指定版本。哎呀!

    作为 Bash 脚本,这可能需要某种 Linux 兼容层(如 Cygwin)才能在 Windows 下运行。


    看起来这应该是 Git 的内置功能——用脚本拼凑起来太复杂了。我想没有多少人使用子模块 git-archive,所以想要同时使用的人更少。

    【讨论】:

    • 这种方法的显着好处是它甚至可以捕获更早的版本(尽管结果证明它并没有真正起作用)。我也看不到如何使用@Kentzo 解决方案自动执行此操作。 @Sergio 解决方案似乎(有点)这样做,但我自己还没有测试过。我想你必须对这些解决方案中的all 进行实际的结帐(和子模块更新)——这对于普通的git archive 来说是不需要的。
    【解决方案4】:

    我正在使用以下代码

    git archive -o release.zip HEAD
    git submodule --quiet foreach 'cd $toplevel; zip -ru release.zip $sm_path'
    

    创建包含所有子模块的 git 存储库的完整存档。

    如果你想变得花哨,你甚至可以通过

    重写 zip 评论
    echo -e "Repository:\n$(git rev-parse HEAD)\nSubmodule status:\n$(git submodule status)" | zip -u release.zip -z
    

    所有在 windows 上使用 infozip。

    【讨论】:

    • $path 已弃用,建议使用 $sm_path 代替(以避免与 Windows 中的 PATH 变量冲突。
    • @BramSchoenmakers 谢谢,已修复。
    【解决方案5】:

    我使用bash 开发了git-archive-with-submodules。它还具有允许创建包含未提交更改的存档的好功能。

    【讨论】:

      【解决方案6】:

      如果你和我一样是 KISS 的朋友,你可以使用@t-b 的答案,因为我发现这个解决方案不会归档嵌套的子模块。以下代码会有所帮助

      # archive main directory
      $ git archive --format tar -o release.tar HEAD
      # descend recursively and archive each submodule
      $ git submodule --quiet foreach --recursive 'git archive --format tar --prefix=$displaypath/ -o submodule.tar HEAD'
      # concatenate with main archive
      $ TOPDIR=$(pwd) git submodule --quiet foreach --recursive 'cd $TOPDIR; tar --concatenate --file=release.tar $displaypath/submodule.tar; rm -fv $displaypath/submodule.tar'
      $ gzip -9 release.tar
      

      结果将是文件 result.tar.gz ...当然,您可以选择另一个提交而不是 HEAD。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-20
        • 2012-08-17
        • 2016-04-21
        • 1970-01-01
        • 2021-04-13
        • 1970-01-01
        • 2012-04-27
        相关资源
        最近更新 更多