[英]Git cloning a repository that is already a clone
对已经是另一个远程存储库克隆的存储库进行git clone
是否有任何不良副作用?
There's no side effects but you should understand exactly what happens when you clone a repository.没有副作用,但您应该确切了解克隆存储库时会发生什么。
The "problem" is that when you clone a repository "the normal way"—that is, without any funky knobs adjusted when calling git clone
—you do not end up with a repository which is the same as the source one. “问题”在于,当您以“正常方式”克隆存储库时——也就是说,在调用git clone
时没有调整任何时髦的旋钮——您最终不会得到与源代码相同的存储库。 It indeed contains exactly the same history but it has different branch layout.它确实包含完全相同的历史记录,但具有不同的分支布局。
To explain it in a non-scientific way, let's take an example:为了以非科学的方式解释它,让我们举个例子:
A source repo contains branches "master", "dev" and "release".源代码库包含分支“master”、“dev”和“release”。
It also contains two tags, "v1" and "v2".它还包含两个标签,“v1”和“v2”。
The "HEAD" reference in that repository points to a branch "master".该存储库中的“HEAD”引用指向分支“master”。
When you clone this repo, your local clone will have:当您克隆此 repo 时,您的本地克隆将具有:
The three remote-tracking branches: "origin/master", "origin/dev" and "origin/release".三个远程跟踪分支:“origin/master”、“origin/dev”和“origin/release”。
The two tags, "v1" and "v2".两个标签,“v1”和“v2”。
A local branch named "master" which points to the same commit the remote-tracking branch "origin/master" does.一个名为“master”的本地分支指向与远程跟踪分支“origin/master”相同的提交。
If you now clone this clone the result will have:如果你现在克隆这个克隆,结果将是:
A single remote-tracking branch "origin/master".单个远程跟踪分支“origin/master”。
A single local branch "master".单个本地分支“master”。
The two tags, "v1" and "v2".两个标签,“v1”和“v2”。
This might appear weird, but in fact this is explicitly stated in the manual page:这可能看起来很奇怪,但实际上手册页中明确说明了这一点:
Clones a repository into a newly created directory, creates remote-tracking branches for each branch in the cloned repository (visible using
git branch -r
), and creates and checks out an initial branch that is forked from the cloned repository's currently active branch.将存储库克隆到新创建的目录中,为克隆存储库中的每个分支创建远程跟踪分支(使用git branch -r
可见),并创建并检出从克隆存储库当前活动分支分叉的初始分支。After the clone, a plain git fetch without arguments will update all the remote-tracking branches, and a git pull without arguments will in addition merge the remote master branch into the current master branch, if any (this is untrue when "--single-branch" is given; see below).克隆之后,不带参数的普通 git fetch 将更新所有远程跟踪分支,并且不带参数的 git pull 还会将远程 master 分支合并到当前 master 分支(如果有的话)(当“--single”时这是不正确的) -branch”给出;见下文)。
This default configuration is achieved by creating references to the remote branch heads under
refs/remotes/origin
and by initializingremote.origin.url
andremote.origin.fetch
configuration variables.这个默认配置是通过在refs/remotes/origin
下创建对远程分支头的引用并通过初始化remote.origin.url
和remote.origin.fetch
配置变量来实现的。
So "clone" in git clone
means that all the history is cloned (unless told otherwise) but the layout of branches is different.所以git clone
“clone”意味着所有的历史都被克隆了(除非另有说明)但分支的布局是不同的。
The reasoning is this: exactly because Git is a distributed VCS, all branches in your non-bare repository are "yours" in the sense that you do work on them and only you decide how they get synchronized with the branches in other repostories, when and why.理由是这样的:正是因为Git 是一个分布式 VCS,所以您的非裸存储库中的所有分支都是“您的”,因为您确实在处理它们,并且只有您决定它们如何与其他存储库中的分支同步,当为什么。
So when you clone a repo "the normal way" Git:因此,当您以“正常方式”克隆一个仓库时,Git:
Only fetches the branches local to that repo: no remote-tracking branches are consdered.仅获取该存储库的本地分支:不考虑远程跟踪分支。
This is because the remote-tracking branches serve as bookmarks to the states of other repositories, and no work is done on them.这是因为远程跟踪分支用作其他存储库状态的书签,并且没有对它们进行任何工作。
To understand why Git behaves this way, consider that when you clone a Joe's repository most of the time you want Joe's work, not the stuff he fetched from whatever random repositories he communicated with.要理解为什么 Git 会这样,请考虑一下,当您克隆 Joe 的存储库时,大多数时候您想要的是 Joe 的工作,而不是他从与之通信的任何随机存储库中获取的内容。
Turns all the fetched branches into remote-tracking branches in the resulting repo.将所有获取的分支转换为生成的 repo 中的远程跟踪分支。
Creates a single local branch and checks it out.创建一个本地分支并检查它。
This is merely a convenience which only adds to a possible confusion.这只是一种便利,只会增加可能的混淆。
Well, git clone
accepts a "--mirror" command-line option which produces a true copy of the origin repo but the resulting repo will be bare.好吧, git clone
接受“--mirror”命令行选项,该选项会生成原始存储库的真实副本,但生成的存储库将是空的。 Should you re-clone the resulting repo again using the "--mirror" command-line option, you will again get the true copy.如果您再次使用“--mirror”命令行选项重新克隆生成的存储库,您将再次获得真正的副本。
If you did a "normal" clone (which, I reckon, you did) you still are able to get everything from that repository but git clone
won't cut it: you'll need to do git init
followed by git remote add origin <url>
followed by a specially crafted git fetch
.如果你做了一个“正常”的克隆(我认为你做到了),你仍然可以从那个存储库中获取所有东西,但git clone
不会削减它:你需要先执行git init
然后执行git remote add origin <url>
后跟一个特制的git fetch
。
Exactly how to craft that git fetch
, depends on what you really want to grab from the source repo, and where to put it.确切地说,如何制作git fetch
取决于您真正想从源代码库中获取什么以及将它放在哪里。 For a start, consider that the source repo now has "origin/master" and "master", and they might very well contain diverged histories.首先,请考虑源存储库现在具有“origin/master”和“master”,它们很可能包含不同的历史记录。
Also note that cloning a non-bare repo using git clone --mirror
will work but the result will not be very sensible as in this case git clone
will dutifully copy all the branches—both local and remote-tracking—from the source repo verbatim, and remote-tracking branches in not something you typically expect to be present in a bare repo.另请注意,使用git clone --mirror
克隆非裸git clone --mirror
将起作用,但结果将不是很明智,因为在这种情况下git clone
将尽职尽责地从源仓库逐字复制所有分支(本地和远程跟踪) ,和远程跟踪分支不是您通常希望出现在裸仓库中的东西。
如果最初没有检出它们,您肯定会错过初始存储库的分支。
No side effects.无副作用。 You can safely clone a repository that comes as result of git clone
operation.您可以安全地克隆作为git clone
操作结果的存储库。 By the way, this is where git differs from centralized systems like Subversion: the cloned repository is an exact copy of the original one (except from the branches that need to be checkeout manually).顺便说一下,这就是 git 与像 Subversion 这样的集中式系统不同的地方:克隆的存储库是原始存储库的精确副本(除了需要手动检出的分支)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.