给定 git 存储库中的单个分支,我如何获取文件的所有版本?最终所需的输出是每个版本一个新的输出文件(尽管将所有版本打印到 STDOUT 也很好,只要很容易确定每个版本的范围即可)。
这是我目前使用的:
branch=master
filename=...whatever...
myids=( $(git rev-list --objects $branch -- $filename | grep $filename | perl -e 'for (<>) { print substr($_, 0, 40) . "\n"; }') )
for (( i=0,j=1; i < ${#myids[@]}; i++,j++ ))
do
echo $i $j
name="output_$j.txt"
git cat-file -p ${myids[$i]} > $name
done
我在做什么的解释:
- 使用
rev-list
查找相关哈希值 - 去除提交和树的散列,只留下文件的散列(这些行还包括文件名)
- 去掉文件名
- 通过
cat-file
运行哈希并生成输出文件
我遇到的两个主要问题是 1) 它不够健壮,因为 grep
可能有误报,我不确定它是否会跟随文件重命名,以及 2)感觉 super hacky。
是否有更好的方法来做到这一点,或许可以更好地利用 git 的 API?
最佳答案
不是最好的解决方案,但这是一种可能性
如果这只是您尝试做的一次性事情,您可以尝试使用以下脚本,但是它使用的是 1.9.4 版的 Git 瓷器,所以它是绝对不是一个健壮、可靠的解决方案,因为它取决于您使用的 Git 版本:
#!/bin/bash
mkdir temp
filepath=osx/.gitconfig
for sha in $(git log --format="%H" $filepath); do
git show $sha:$filepath > temp/$sha.file
done
它只是使用 git log
查找修改文件的所有提交:
$ git log --format="%H" osx/.gitconfig
338243aa6b68edad1dc3b2eebf66e108e9a4d685
7a4667138a519691386940ac23f9c8271ce14c77
475593a612141506f59a141e38b8c6a3a2917f85
03fa0711032cfdfc37fb431d60567ef22d75c7e5
3f7d8f0fc7e1d7a614f2aef8f53947ec2ce61296
c5fef8fccef3fc13f9dea17db209f2ceaab70002
287dadd8bcaf7e9197c6a16d57d3bacb72a41812
1f34ee1ab6965635a8f412bf3387f9dfdf197a1d
然后使用 <revision>:<filepath>
从该修订版输出文件版本的语法。
git log
虽然有时可以简化您的图形历史记录,因此您甚至可能想要传递 --full-history
标记为 git log
,但我不确定对于这个特定用例是否有必要。
不过,这对重命名的文件有多好?为了使用正确的文件路径,您可能需要让脚本更智能地跟踪它。
不过,我想再次强调,这不是最好的解决方案,更好的解决方案是改用 Git 管道命令,因为它们不会太依赖于Git 版本,并将更加向后和向前兼容。
文档
关于git - 从单个分支获取文件的所有版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25086777/