git - 为什么我不能从浅克隆推送?

标签 git workflow git-clone

git clone --depth命令选项说

--depth <depth> 
Create a shallow clone with a history truncated to the specified number of revisions. 
A shallow repository has a number of limitations 
(you cannot clone or fetch from it, nor push from nor into it),
 but is adequate if you are only interested in the recent history of a large project with a long history,
 and would want to send in fixes as patches. 

为什么浅克隆有这个限制?为什么只有补丁工作流程?

对于某些项目工作流,我需要将来自单个分支的最新提交传递给编码人员,然后让他们能够 push他们(快进)对主服务器的开发。这部分是为了安全、IP 保护和 repo 大小,部分是为了减少大型 repo 给天真的编码人员带来的困惑。是否有允许这样做的 git 工作流程?


更新:基于 Karl Bielefeldt 的回答 git checkout --orphan应该是正确答案。但是仍然需要将该分支单独“克隆”给新用户,并能够有效地推送它。

手册页指出:

git checkout [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>] --orphan

Create a new orphan branch, named <new_branch>, started from <start_point> and switch to it. The first commit made on this new branch will have no parents and it will be the root of a new history totally disconnected from all the other branches and commits.

The index and the working tree are adjusted as if you had previously run git checkout <start_point>. This allows you to start a new history that records a set of paths similar to <start_point> by easily running git commit -a to make the root commit.

This can be useful when you want to publish the tree from a commit without exposing its full history. You might want to do this to publish an open source branch of a project whose current tree is "clean", but whose full history contains proprietary or otherwise encumbered bits of code.

If you want to start a disconnected history that records a set of paths that is totally different from the one of <start_point>, then you should clear the index and the working tree right after creating the orphan branch by running git rm -rf . from the top level of the working tree. Afterwards you will be ready to prepare your new files, repopulating the working tree, by copying them from elsewhere, extracting a tarball, etc.

VonC 指向 Junio 评论的链接很有趣。我认为手册应该在这种情况下提供指导,并允许正确的命令[例如clone <branch> --options ] 只提取 repo 的相关部分。显然push的概率通过在历史记录底部添加一些链接提交和 SHA1 来锁定 repo 匹配,可以增加成功率。


更新 Git 1.9.0:发行说明 2014 年 2 月 14 日。

“过去禁止从浅克隆存储库中获取数据, 主要是因为涉及的代码路径没有经过仔细审查 我们也懒得支持这种用法。本次发布尝试 允许对象从浅克隆存储库中传输出来 更可控的方式(即接收器成为浅存储库 具有截断的历史记录)。”

这对浅层克隆者来说是个好消息。 接下来 - 可能是窄克隆。

最佳答案

作为 Junio C. Hamano(Git 主要维护者)puts it :

Isn't the rule more or less like:

If your shallow repository's history does not extend long enough and the other repository forked before your truncated history, wyou cannot compute the common ancestor and you cannot push out.

2014 年更新:参见“Is git clone --depth 1 (shallow clone) more useful than it makes out?”:Git 1.9 将取消该限制!

2015 年更新:使用 Git 2.5+,您甚至可以获取单个提交。参见“Pull a specific commit from a remote git repository


原始答案(2011 年 8 月):

Actually, come to think of it, it is a lot stronger than "cannot compute the common".

The history may look like this:

          R---R---R
         /
  --R---R---X---X---S---S---S

where S are the commits you have in your shallow repository, and R are the commits that exist in the repository that receives your push.
Because your history is shallow, neither repository has 'X' that are the commits that need to exist in order to keep the history of recipient repository complete; the recipient is not shallow to begin with, and we do not want to make it shallow.

If you cloned shallowly some time ago, worked without communicating with the other side while the other side progressed, AND if the other side's progress included a rewind & rebuild of the history, you would see a similar topology.
The leftmost 'S' in the above picture might have been the tip of the branch when you shallowly cloned with depth 1, and since then the remote end may have discarded topmost three commits and have rebuilt its history that leads to the rightmost 'R'.
In such a case pushing to the remote's HEAD will fail.


所以它可以在某些情况下工作,但不被支持:

如果我必须对此说点什么......

  • I think "is not supported" is a succinct way to give good enough information, but it would only work for intelligent people.

  • Not everybody is intelligent; some try it out themselves, see that the operation seems to work for their limited number of trials, and would conclude it would work most of the time.
    And they congratulate their own intelligence for saying "most of the time", not "always".
    And they get upset when they see it does not work, even though they have been warned.


有关浅克隆更新过程的更多信息,请参阅“How to update a git shallow clone?”。

关于git - 为什么我不能从浅克隆推送?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6900103/

相关文章:

git添加错误: "fatal : malloc, out of memory"

Git push返回错误并且不提示输入密码

ruby - Grit 的克隆方法未定义?

c++ - 多平台 C++ 交叉编译器

Git "Fetch URL"和 "Push URL",有什么区别?

git - 克隆git repo的子树/子目录

GIT:仅从 GitHub 克隆特定分支

git - 使用 SHA 编辑文件 - git

git - 添加到 git staging 意味着什么?

azure - 是否可以在本地运行 Azure 逻辑应用