鉴于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)感觉超级hacky。
有没有更好的方法来做到这一点,也许更好地利用git的API?
答案 0 :(得分:2)
如果这只是您尝试做的一次性事情,您可以尝试使用以下脚本,但它使用的是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版本,并且会更加向后兼容。
答案 1 :(得分:1)
我建议在文件本身上使用git-log
,而不是git-rev-list
:
#!/bin/bash
filename=...whatever...
i=1
for hash in `git log --pretty=format:%H -- $filename`
do
git show $hash:$filename > output_$i.txt
((i++))
done