Git:根据提交识别/识别未跟踪复制/匹配的版本

时间:2016-07-03 19:25:27

标签: git duplicates git-diff

TL; DR

无论出于何种原因,有时你(至少我)最终会将你项目的某个状态复制到你的仓库之外。

有没有办法让git将这些文件与所有blob进行比较并正确匹配相应的提交?

实施例

我的项目中有10个提交。

  1. a)在提交#6,我发送每个邮件的项目档案
  2. b1)在提交#6出于任何原因我将我的项目复制到未跟踪状态 地方
  3. b2)无论出于什么原因,我都会将项目复制到#6 一个没有跟踪的地方并做出改变
  4. 几个月后我找到副本,但不记得我(不小心)是否对它们做了任何更改。

    现在我想找出它们匹配的提交或者它们是否与我的任何提交相匹配(通常是为了确定我是否可以删除它们)。

    理想情况下,我可以找出它们最匹配的提交以及与每次提交相比有多少添加,删除和修改的行。

    git可以自己做吗?还有其他工具可以做到吗?

    声明

    英语不是我的母语,请随时纠正/编辑/重组此问题

2 个答案:

答案 0 :(得分:1)

Git中没有内置来做到这一点。

使用脚本可以实现相对简单的方法,方法是将新提交(或至少一个树,我们不需要提交)添加到由存档版本组成的存储库中。只有当新树在文件名和内容以及权限(可执行与不可执行)方面与原始树完全相同时,这才有效。例如,如果在发送文件时遗漏了.gitignore,则新树将与具有.gitignore文件的实际提交不匹配。

这是一种方法,写成大纲:

  1. 创建一个空的临时索引
  2. git add测试树中的每个文件到此临时索引
  3. 使用git write-tree将临时索引作为树
  4. 写入存储库

    步骤3中git write-tree的输出是树ID。现在您只需要(仅?!)访问存储库中的每个提交,或者至少访问每个感兴趣的提交,并将 tree对象与您刚刚获得的ID进行比较:

    GIT_INDEX_FILE=$(mktemp) || exit $?
    export GIT_INDEX_FILE
    git add ...
    tree=$(git write-tree) || exit $?
    git rev-list --all | while read hash; do
        commit=$(git rev-parse -q --verify $hash^{commit} 2>/dev/null) || continue
        testtree=$(git rev-parse $commit^{tree})
        if [ $testtree = $tree ]; then
            echo "test tree matches existing commit $commit"
            [ $commit != $hash ] &&
                echo "(via $hash, which is a $(git cat-file -t $hash))"
            echo git describe says: $(git describe $commit)
        fi
    done
    

    (这根本没有经过测试,并且缺少一些清理代码,例如删除临时索引)。

答案 1 :(得分:0)

  1. 将存档设为git仓库。

    git init git add。 git commit -m'hello world' git log -1 --pretty = raw

  2. 我们可以获得一行tree <40-digit-sha1>

    1. 查找指向原始项目中同一树的提交。

      git log --pretty = raw | grep -B 1&lt; 40-digit-sha1&gt;

    2. 如果2次提交指向同一棵树,则由这2次提交制作的2份档案应具有相同的内容。