简体   繁体   English

如何将文件的所有 git 版本保存到磁盘?

[英]How to save all git versions of a file to disk?

Having a file.py which has three versions in git with three unique commit hashes.有一个file.py ,它在 git 中具有三个版本,具有三个唯一的提交哈希。

So how can I programmatically restore all of the versions into specific files, such as:那么如何以编程方式将所有版本恢复到特定文件中,例如:

0_<git_hash>_file.py
1_<git_hash>_file.py
2_<git_hash>_file.py

Solution does not have to be Python, but looking into the Python git package currently.解决方案不一定是 Python,而是当前查看 Python git包。

n=0
git log --pretty= --diff-filter=d --raw -- $file | 
while read m1 m2 h1 h2 rest; do
        eval git show $h2 > $((n++))_${h2}.$file
done

or或者

n=0
git log --pretty=%h --diff-filter=d -- $file |
while read; do
        eval git show $REPLY:$file > $((n++))_$REPLY.$file
done

depending on whether you want the blob's or the commit's hash in the resulting file name.取决于您是否想要结果文件名中的 blob 或提交的哈希。

You can get a specified version of a file without checking out the corresponding commit using git show .您可以使用git show获取指定版本的文件,而无需检查相应的提交。 For example:例如:

git show git_hash:./file.py

will print the contents of file.py as of the specified commit to standard output.将在指定提交时打印file.py的内容到标准输出。 (Presumably the Git Python interface, which I haven't used, provides similar functionality.) The leading ./ avoids path resolution problems in some cases (I don't remember the details). (大概是我没用过的 Git Python 接口,提供了类似的功能。)前导./在某些情况下避免了路径解析问题(我不记得细节了)。

I've written a Perl script that does this kind of thing for several different version control systems (most of which I no longer use): https://github.com/Keith-S-Thompson/get-versions (no warranties).我已经编写了一个 Perl 脚本,它为几种不同的版本控制系统(其中大部分我不再使用)执行这种操作: https : //github.com/Keith-S-Thompson/get-versions (无保证) .

As requested, here's an example of running get-versions on a copy of its own repo:根据要求,以下是在其自己的存储库副本上运行get-versions的示例:

$ ls -l
total 56
-rw-r--r-- 1 kst kst 18092 Aug  9  2015 COPYING
-rw-r--r-- 1 kst kst  6234 Apr 16  2018 README.md
-rw-r--r-- 1 kst kst   940 Apr 25  2018 TODO.md
-rwxr-xr-x 1 kst kst 20977 Apr 16  2018 get-versions
$ get-versions -pad 3 -last 3 get-versions 
$ ls -l
total 128
-rw-r--r-- 1 kst kst 18092 Aug  9  2015 COPYING
-rw-r--r-- 1 kst kst  6234 Apr 16  2018 README.md
-rw-r--r-- 1 kst kst   940 Apr 25  2018 TODO.md
-rwxr-xr-x 1 kst kst 20977 Apr 16  2018 get-versions
-r--r--r-- 1 kst kst 20752 Mar  2 10:54 get-versions,012
-r--r--r-- 1 kst kst 20766 Mar  2 10:54 get-versions,013
-r--r--r-- 1 kst kst 20977 Mar  2 10:54 get-versions,014
$ 

get-versions -help prints an entirely too verbose usage message. get-versions -help打印一个完全过于冗长的使用消息。 (Adding a man page is on my TODO list, as is preserving execute permissions.) (添加手册页在我的待办事项列表中,保留执行权限也是如此。)

Use git rev-list to get the list of commits, and git show to output the file:使用 git rev-list 获取提交列表,使用 git show 输出文件:

i=0; git rev-list --abbrev-commit HEAD | 
while read sha; do
    git show $sha:./file.py > $((i++))_${sha}_file.py
done

This version might avoid problems with i++ being executed in a subshell and not affecting the parent:此版本可能会避免在子 shell 中执行i++而不会影响父级的问题:

i=0; git rev-list --abbrev-commit HEAD |
while read sha; do
    git show $sha:./file.py > ${i}_${sha}_file.py
    ((i++))
done

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM