我在低级别攻击git存储库,试图从中检索文件的历史记录。并且难以识别在同一版本中修改和重命名的文件。
我正在开发C#应用程序,我需要实现git log --follow FILENAME
功能。
修改很简单:如果SHA1不同,则在附加到修订版本的树中搜索具有给定路径的文件 - Voilà!
重命名也很简单:如果按给定路径搜索不成功 - 查找具有相同SHA1的对象,如前所见,如果找到 - Voilà!
但如果没有找到它可能是文件删除和我的搜索结束,或重命名和修改相同的修订...但如何区分这些情况?
我已经研究了我发现的关于Git内部的所有内容,但是仍然无法找到在这种情况下该做什么,在不同版本中对应于相同修改和重命名文件的树对象之间可能会有什么共同之处?
非常感谢您的帮助!
答案 0 :(得分:0)
Git已经拥有该功能。请参阅-M
的{{1}} / --find-renames
,-C
/ --find-copies
和-C -C
/ --find-copies-harder
选项(适用于diff
}和log
以及show
的{{1}}选项。
--follow
的原则是,如果它在修订版中看到新文件,它会查看该修订版中删除的文件,比较它们,如果有任何相似的文件,则声明它是重命名。
编辑:更多细节:为了检测复制/重命名,git首先比较两个版本,然后比较文件列表。对于仅出现在新版本中的每个路径,它会将内容与旧版本的文件内容进行比较,log
- 已删除,--find-renames
- 已修改或-M
- 全部且如果它们足够相似(需要差异),将其标记为适当重命名或复制。这是diff核心的一部分,可用于显示任何形式的差异的所有命令,包括名称状态,它不进行详细的逐行分析。除此之外,-C
通过逐个迭代修订来工作,具有重命名检测的名称 - 状态差异,并且如果文件被修改则输出修订,并在重命名时记住新(旧)名称。