克隆和远程之间的 Git 差异,如果您无法获取?



我有一个场景,我的存储库的克隆定期创建到只读目录存档的目的。

我有一些脚本,在上下文中需要从克隆目录中运行,我试图找到一些方法来检查是否存在比克隆目录中某个文件的新版本。

我是一个相对较新的git用户,但是我能想到的每一种方法似乎都是基于这样的想法,即至少能够执行fetch操作来获取克隆完成后的提交历史。但是我不能这样做,因为克隆目录是只读的。

来自其他CM系统,我一直在想一定有一些方法可以让我从远程获取文件的最新版本的ID,并将其与不依赖于首先抓取但没有成功的克隆进行比较。

我已经提到了这篇文章,但唯一的答案似乎是没有其他选择来获取。

您不能直接获得实际的diff。

可以查看您是否更新了,如果不是,则使用具有内容的系统(根据定义,该系统不是只读)来提供diff,因为旧版本必须1在新版本的历史记录中。

要获得新版本与旧版本的完整差异,请在新系统上运行此命令:

$ git diff <old-commit-sha1> <new-commit-sha1>

将此diff限制为单个路径(从而检查该路径是否需要更新):

$ git diff <old-sha1> <new-sha1> -- <path>

如果非只读的系统不允许您运行足够多的命令来生成所需的diff,那么您需要一个第三个地方(系统或git存储库)来生成这个diff,方法是克隆更高级的存储库,使用克隆(它拥有所需的一切)执行diff,然后选择性地删除这个克隆。如果您可以保留此克隆并使其保持读写状态,那么您将在下一次运行相同任务时处于更好的状态。此外,您会发现可以完全放弃只读克隆,因为此时您只使用它做一件事:使用它来保留前一次提交的SHA-1。

您所需要的只是旧提交的SHA-1 ID,因为新系统有完整的历史记录(但请再次参阅脚注1)。此外,这就是标签的作用:标签指的是一个特定的提交,2给出了一个人类可读的名称,否则它只是一个丑陋的SHA-1。(嗯,带注释的标记提供的不仅仅是一个名称。特别是,他们让你提供一个PGP签名,表明你也认可特定的SHA-1。

好吧,但是你怎么知道你是最新的呢?

要做到这一点,必须至少具有对读写存储库的一些访问权限。然后,您只需要查看SHA-1与它们的一个分支之间的关系,并将SHA-1与您的分支之间的关系进行比较(无论它是否具有相同的名称)。

有一个人类可读的版本,git show remote <remote-name>,它会显示这样的内容:

$ git show remote origin
... [snip]
    master             pushes to master             (local out of date)

和更可脚本化的需要找到实际的sha -1:

$ git ls-remote origin

第二个生成大量细节,默认情况下提供所有内容;添加--heads, --tags,和/或特定的引用,只得到一个项目;例如:

$ git ls-remote origin refs/heads/master
 <big ugly sha-1>   refs/heads/master

将此SHA-1与您自己的SHA-1进行比较:

$ git rev-parse master
<big ugly sha-1>

如果它们不同,则在非只读存储库中有新的提交。注意,这些新的提交可能不会影响您所关心的某些特定的路径;要找到答案,您必须使用具有这些提交的存储库,以便您可以在您关心的两个提交中找到路径的SHA-1。

例如:

$ git rev-parse master:.gitignore
50ac108339a8c7164e0620a074049ad03cb80aee

您可以为特定的版本执行此操作:

$ git rev-parse <sha-1>:.gitignore

但是你必须有提交。


1这假设控制读写存储库的人没有修改或删除其中的一些。当然,每当您将数据控制权交给他人时,您都会做出这样的假设。如果您记住了一个特定的SHA-1,那么它是一个加密签名的事实意味着您可以测试它们是否更改了您的数据,但仅凭它本身还不足以恢复它:您需要其他克隆(s)。

2标签可以直接指向树或blob,或者指向另一个标签,而不是指向提交,但这不是通常的情况

最新更新