将所有提交导出为ZIP文件或目录

4
如何将所有提交导出为ZIP文件(包含所有文件,而不仅仅是补丁/差异):
myproject-commit1-67d91ab.zip
myproject-commit2-9283acd.zip
myproject-commit3-c57daa6.zip
...

或者进入目录:

myproject-commit1-67d91ab/
myproject-commit2-9283acd/
myproject-commit3-c57daa6/

我正在考虑类似以下的命令:

git archive --format zip --output myproject-commit3.zip c57daa6

以下内容翻译自如何使用git-archive导出特定提交?,但如何获取所有提交

注:

  • the goal is to do an export of all files of each commit, so that I can have access to them even if I don't have git on the machine

  • the answer from How can I export Git change sets from one repository to another via sneaker net (external files)? creates a .bundle file, but it seems impossible to access it without git, so it's not what I'm looking for

  • this nearly works:

    for ((i = 0;; ++i)); do git checkout master~$i || break; tar czf ../myproject-commit$i.tgz .; done
    

    but it also archives all the files in the current directory which are not git added to the repo... How to avoid this problem?


尝试使用 git bundle 命令。它创建一个类似只读仓库的捆绑包。请参阅 https://www.git-scm.com/docs/git-bundle。 - ElpieKay
@phd,来自 https://dev59.com/C6nka4cB1Zd3GeqPPogC 的答案会创建一个 .bundle 文件,但似乎无法在没有 git 的情况下访问它,所以这并不是我正在寻找的东西。 - Basj
你还没有解释你想要什么。你应该从一开始就这样做。好的,“git archive”似乎是答案,但是没有单个命令。 - phd
@phd 感谢您的评论,我原以为说我想将每个提交导出为zip文件 myproject-commit3-67d91ab.zip 已经足够明确了,但现在我已经编辑过以添加更多细节。 - Basj
3个回答

5

除了你已经想过的方法,你不能做到。

具体来说,要将每个提交转换为zip归档文件(每个提交一个单独的归档文件),只需遍历每个提交,将每个提交转换为zip归档文件即可。

你的迭代方法只需要遍历所有可能的提交,而不仅仅是遍历master分支的所有第一个父提交,而且你必须在每个这样的提交上使用git archive。 因此:

git rev-list --all |
    while read hash; do git archive ...options... $hash
done

命令git rev-list --all告诉Git按某种顺序打印出所有可达的提交哈希值。为了改变顺序,可以使用git rev-listgit log提供的各种排序选项(例如--author-date-order--topo-order)。如果你不想要每个提交,而是只想要主分支的第一父级,则仍然可以使用git rev-list来实现:
git rev-list --first-parent master | ...

这里,由于Git只遍历从master标识的提交开始的一级父提交,因此哈希ID将按照Git认为的正向顺序输出,即沿着分支的一级父提交向后:

...--o--o--o--o--o--o------o   <-- master
      \        \          /
       \        X--X--...X   <-- somebranch
        \         /
         X--X----X--X   <-- anotherbranch
X的提交记录不会出现,因为它们不在第一个父级的血统上。(如果没有使用--first-parent,则由于所有somebranch上的提交记录以及除anotherbranch上的最后一个提交记录之外的所有提交记录都在master上,您将获得所有X提交记录。)
[Basj补充了以下内容,由于$ ((i = i + 1)),这似乎是特定于bash的:]编辑:这是一个立即可用的命令,可以按照问题所述执行。
git rev-list --all --reverse | while read hash; do git archive --format zip --output ../myproject-commit$((i=i+1))-$hash.zip $hash; done

感谢您的详细回答,@torek。我只是在最后附加了可用的命令。 - Basj

2

我稍微改进了@torek的解决方案。
这个方案导出了可以使用git log“正常可见”的提交(所有提交都在文件夹zip中导出):

mkdir zip && git log --format=%h --reverse |
    while read hash;
    do git archive --format zip --output zip/$((i=i+1))-project-$hash.zip $hash;
done

如果您还想包含日期和时间(不包括“project”),请使用以下代码:
mkdir zip && git log --format="%h %ad" --date=format:"%d.%m.%Y-%H.%M" --reverse |
    while read hash date;
    do git archive --format zip --output zip/$((i=i+1))-$hash-$date.zip $hash;
done

如果您希望将所有提交导出到文件夹(而不是zip压缩文件),请使用以下命令:

mkdir zip && git log --format="%h %ad" --date=format:"%d.%m.%Y-%H.%M" --reverse |
    while read hash date;
    do git archive --format zip --output zip/$((i=i+1))-$hash-$date.zip $hash;
done && find zip -name '*.zip' -exec sh -c 'unzip "$1" -d "${1%.*}"' _ {} \; && rm zip/*.zip

无论如何,如果您想保留文件模式(chmod),请使用此命令。它使用tar归档而不是zip归档:

mkdir tar && git log --format="%h %ad" --date=format:"%d.%m.%Y-%H.%M" --reverse |
    while read hash date;
    do git archive --format tar --output tar/$((i=i+1))-$hash-$date.tar $hash;
done && find tar -name '*.tar' -exec sh -c 'mkdir ${1%.*} && tar -xvf "$1" -C "${1%.*}"' _ {} \; && rm tar/*.tar

0

您可以使用以下命令将特定提交的项目以zip文件形式下载:

https://host_url/{user_name}/{project_name}/archive/{commit_id}.zip

编辑

你可以使用命令行完成此操作。

git archive -o commit_id.tar --remote=<repo_url> <commit_id>

在这种特定情况下,我不使用GitHub或任何类似的东西。我只有一个本地仓库,我认为Web解决方案在这里行不通。 - Basj
谢谢@Shravan40,但你可以看到我已经在问题本身中提到了这一点,问题更多的是:如何获得所有提交的存档? - Basj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接