如何确定文件是否与git历史记录中的文件相同

时间:2013-10-16 07:25:49

标签: git

我有任意文件foo,没有提交给git。

我还有一个文件,其整个历史记录保存在git bar中。

如何确定foo是否与曾经存在的bar版本完全相同?

2 个答案:

答案 0 :(得分:2)

很容易判断文件foo的内容是否出现在回购中的某个位置:

file=foo  # or argument to script, etc
sha1=$(git hash-object -t blob $file)
repotype=$(git cat-file -t $sha1 2>/dev/null) || {
    echo "file \"$file\" is not in the repo"
    exit 1
}
[ $repotype = blob ] || {
    echo "uh oh: file \"$file\" matches non-file ($repotype) object"
    exit 1
}

但是,仅仅因为foo作为blob出现在回购协议中,并不意味着它出现在名称bar下(或者甚至可能根本不出现,它可能是git add ed但从未在提交下签到)。那么现在看看每个(合理的?)提交,提取目标路径的blob-ID,如果它不在那里则跳过提交:

target_path=bar

git rev-list --branches |     # or --all, or HEAD, or (etc)
while read id; do
    file_id=$(git rev-parse -q --verify $id:$target_path) || continue
    [ $file_id = $sha1 ] || continue
    echo "found \"$file\" as \"$target_path\" in $id"
    # do more here if you like, e.g., git show $id
done

如果要在任何名称下找到它,而不是某个特定的显式名称,则可以git ls-tree -r每次提交以查找所有blob并检查其ID。

(注意:除了零碎之外未经测试,偶尔可能会在路上重新输入或改变,提防拼写错误或愚蠢错误)

答案 1 :(得分:0)

使用md5sumgit loggrep的组合可行:

for SHA in `git log --pretty=format:"%h" bar`; do 
  git show $SHA:bar | md5sum
done | grep `md5sum foo| cut -d' ' -f1`

上面的命令git log --pretty=format:"%h" bar获取bar文件的所有提交列表,然后我们对每一个提交md5sum(git show以显示该提交中的文件)。最后,我们grep md5sum foo文件