Git:根据提交识别/标识未跟踪副本的版本/匹配 TL;博士

Git:根据提交识别/标识未跟踪副本的版本/匹配 TL;博士,git,duplicates,git-diff,Git,Duplicates,Git Diff,不管出于什么原因,有时候你(至少我)会在回购协议之外复制项目的某个状态 git是否有办法将这些文件与所有blob进行比较,并正确匹配相应的提交 例子 我在我的项目中有10次提交 a) 在commit#6,我会通过邮件发送项目档案 b1)在提交时,无论出于何种原因,我都会将我的项目复制到未经跟踪的 放置 b2)在提交时,无论出于何种原因,我都会将我的项目复制到 未追踪的地方,并进行更改 几个月后,我找到了副本,但不记得是否(意外)对其进行了任何更改 现在我想知道它们匹配什么提交,或者它们是否匹配我

不管出于什么原因,有时候你(至少我)会在回购协议之外复制项目的某个状态

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

例子 我在我的项目中有10次提交

  • a) 在commit#6,我会通过邮件发送项目档案
  • b1)在提交时,无论出于何种原因,我都会将我的项目复制到未经跟踪的 放置
  • b2)在提交时,无论出于何种原因,我都会将我的项目复制到 未追踪的地方,并进行更改
  • 几个月后,我找到了副本,但不记得是否(意外)对其进行了任何更改

    现在我想知道它们匹配什么提交,或者它们是否匹配我的任何提交(通常是想知道我是否可以删除它们)

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

    git自己能做到吗?有没有其他工具可以做到这一点

    免责声明 英语不是我的母语,请随意更正/编辑/重新构造这个问题

    Git没有内置任何功能

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

    以下是一种方法,以大纲的形式编写:

  • 创建一个空的临时索引
  • git将测试树中的每个文件添加到此临时索引
  • 使用
    git write tree
    将临时索引作为树写入存储库
  • 在步骤3中,
    git write tree
    的输出是一个树ID。现在,您只需(仅?!)访问存储库中的每个提交,或者至少访问每个感兴趣的提交,并将其
    对象与刚获得的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
    
    (这根本没有经过测试,并且缺少一些清理代码,例如删除临时索引)

  • 将归档文件制作成git repo

    git初始化 git添加。 git commit-m'hello world' git日志-1--pretty=raw

  • 我们可以得到一行

  • 查找指向原始项目中相同树的提交

    git log--pretty=raw | grep-b1

  • 如果两个提交指向同一棵树,则由这两个提交生成的两个归档文件应具有相同的内容


  • 就我所知,
    git diff--find copies
    在一个状态(提交/索引/工作树)内或两个给定状态(提交/…)之间查找副本,但不在所有提交中搜索(一个或多个)文件的副本为了找到每个文件的相同副本,
    git grep
    ing每个文件都是一个解决方案吗?那么
    git diff
    ing每个文件到每个
    git rev list--all
    ?是否有一种简单的方法来解析和处理结果并以方便的格式显示它们?在这种情况下,是否应该使用外部工具进行扩散?哪一个?谢谢你的回答。如果它有效,它实际上符合我给出的要求。不过,我很幸运,不仅能够找到完全相同的副本,因为每个文件都是完全相同的,而且如果有一种简单的方法来处理结果,我还必须将提交的所有文件都放在副本中(在我的情况下,我只复制了我的
    /code/
    子文件夹,而不是
    /documentation/
    子文件夹)(解析、排序、适当呈现)我可能会将每个文件分别分配到
    git rev list中的每个文件--all
    如果您要查找部分匹配或近似匹配,任务会变得更加困难。您可以对每个树和/或文件运行
    git diff
    ,但这将花费大量时间。您可能需要仔细选择所需的计算时间为了解决这个问题。谢谢你的回答!除了torek避免了额外的提交之外,这与torek的解决方案基本相同吗?@sqln00b是的。
    git commit
    是git的陶瓷命令之一,它隐藏了细节,对用户更友好,@torek使用的管道命令更熟练,需要额外的努力学习。