本文介绍了在push --force之后检索孤立的提交对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

执行 push --force 总是很冒险的,这是一个示例,它可能会产生一些问题,例如远程丢失修订版.

Doing push --force is always kinda risky and here is an example of how it could produce some problems like loosing revisions remotely.

假设某人鲍勃已将远程 master 分支从 B 更新为 C .还有另一个人 Mike 尚未获取此更新,并且他的 master HEAD 仍然是 B .然后 Mike push --force 并突然将远程 master 重新回滚到 B :

Suppose, there is some person Bob that has updated remote master branch from B to C. And there is another person Mike that doesn't fetch this update yet and HEAD of his master is still B. Then Mike do push --force and suddenly roll back remote master to B again:

mike@laptop $> git push --force origin
Counting objects: 19, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (12/12), 2.27 KiB, done.
Total 12 (delta 8), reused 0 (delta 0)
remote: => Syncing... [OK]
To git@gitserver.com:path/to/project.git
   C..B  master -> master (forced update)

换句话说,在迈克做到这一点之前,远程主机就像 A --- B --- C 一样,他将其更改为 A---B .

In other words, before Mike did that, remote master was like A---B---C and he changed it to A---B.

如您所见,这里的 C 修订版仅是远程的-它存在于git-server和 Bob 的笔记本电脑上,因为他将其推送到了远程 master .这意味着迈克的笔记本电脑上没有这样的本地参考 C .

As you can see, C revision here is remote only - it exists on git-server and on the Bob's laptop, because he pushed it to the remote master. It means that there is no such local ref C on the Mike's laptop.

问题1 :迈克如何将远程 master 设置回 C ?

Question 1: how can Mike set remote master back to C?

Mike 尝试再次使用 push --force 解决该问题,例如提供类似问题的答案,但是它没有用,因为没有本地引用:

Mike has tried to solve that problem with push --force again like the answer for similar question offers, but it doesn't work because there is no suck local ref:

mike@laptop $> git push --force origin C:master
error: src refspec C does not match any.
error: failed to push some refs to 'git@gitserver.com:path/to/project.git'

问题2 : Mike 如何从git服务器获取 C 版本?如果他不能做到这一点-为什么git会那样设计?在极少数情况下与安全有关吗?它到底能防止什么问题?

Question 2: how can Mike fetch C revision from the git server? And if he can't do that - why git designed like that? Is it about safety in some rare cases? What problems it exactly prevents?

通常 fetch 仅检索分支和标签,但是 C 不属于任何分支(这意味着 C 是父提交或 HEAD ).

Usually fetch retrieves branches and tags only, but C doesn't belong to any branch (which means that there is no any remote branch that C is parent commit or HEAD of).

PS:假设 Mike 对git服务器没有ssh访问权限,这意味着无法从服务器端调用git.

PS: let's assume that Mike has no ssh access to git server, it means that there is no way to call git from the server side.

PPS:迈克不希望 Bob 知道该事故,因此回答使 Bob 再次推动该提交"是不是这个问题是关于什么的.

PPS: Mike doesn't want Bob to know about that accident, so answer "Make Bob to push this commit again" is not what this question is about.

推荐答案

任何在本地提交了 C 的人都可以使用 git branch some-name C 来提供C 一个名称,然后 git push origin some-name:master 到(尝试)将 C 附加回原点上的master.

Anyone who has commit C locally can use git branch some-name C to give C a name, then git push origin some-name:master to (try to) append C back to master on origin.

没有 C 的任何人根本无法恢复 C (即使它位于原始对象存储库中).

Anyone who doesn't have C can't recover C at all (even if it's in origin's object store).

迈克 无法解决此问题,除了使用包含提交 C (可能是共享的,可能是 Bob ,可能是在 C 在主服务器上时克隆的其他一些回购).

Mike cannot fix the problem except using a repo that contains commit C (possibly the shared one, possibly Bob's, possibly some other repo that was cloned when C was on master).

您不能推送本地没有的提交. git-push 的本地一半必须能够遍历历史记录以找出要上传的对象,如果没有可用的历史记录,则无法做到这一点.

You can't push commits you don't have locally. The local half of git-push has to be able to walk history to figure out what objects to upload, and it can't do that if it doesn't have that history available.

您无法获取引用无法访问的提交,因为实际上每个git安全层都基于逐个引用而不是逐个对象进行安全性,并且因为没有真正的远程引用松散对象的原因.Git的远程处理层完全围绕复制引用而构建.

You can't fetch commits that aren't reachable from refs, because literally every git security layer out there does security on a ref-by-ref basis, not an object-by-object basis, and because there's no real reason to reference loose objects remotely. Git's remoting layer is entirely built around copying refs around.

但是,如果服务器已启用该功能,则可以使用git-archive获取任意提交的内容.大多数都没有,即使您有,也没有足够的信息来重构提交对象.

But you can fetch arbitrary commits' contents using git-archive, if the server has that feature turned on. Most don't, and even if yours does, it's not enough information to reconstruct the commit object.

(c)irc://freenode/#git,ojacobson

(c) irc://freenode/#git, ojacobson

这篇关于在push --force之后检索孤立的提交对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-04 20:44