这是一个由多部分组成的答案,因为这里有两个独立的问题现在纠缠在一起。以下是我们将要介绍的内容的摘要:
-
main
vs master
error: src refspec main does not match any
- 调和分开
main
and master
分支机构
其中每一个都位于其自己的部分中。
main
vs master
Git itself has no special branch names.1 You could use main
, master
, trunk
, or any other name as the name of your first branch. Git has traditionally used the name master
here, but there is a project to make this configurable, so that if you are French or Spanish you can use the name principal
or première
or primero
, or if you prefer Maori, you can use matua
or tuatahi
. Currently, you can do this manually during or after a git init
,2 but the project makes Git just do it automatically, without requiring a second step: If for any reason you want any other name by default, you can configure that.
与此同时,GitHub 已经选择向前迈进并为其默认的初始分支名称main
代替master
。但这留下了your吉特和GitHub's可以说,Git 不同步。有关 GitHub 变更的更多信息,请参阅Github 中主分支和主分支的区别? https://stackoverflow.com/q/64249491/1256452
1There are some technical flaws in this kind of claim. As we know, technically correct is the best kind of correct https://www.reddit.com/r/OutOfTheLoop/comments/48a9bw/why_is_technically_correct_the_best_kind_of/, so let me add a few caveats in this footnote:
-
合并自动生成以下形式的消息merge branch X into Y
当你在分支上时Y
并运行git merge X
。然而,当你在master
, Git 传统上仅生成以下形式的消息merge branch X
.
-
由以下人员创建的新的空存储库git init
没有提交,因此没有分支(因为分支只能通过提交而存在)。然而,你必须是on这个新的空存储库中的某个分支。所以 Git 在名为的符号引用中存储了一些名称HEAD
。这是您所在的分支名称,即使该分支名称(尚不存在)也是如此。很长一段时间以来,Git 已经硬编码了一些代码来粘贴分支名称master
在那里。 (这实际上是 GitHub 所做的改变。)
-
还有一堆其他字符串文字正在读取master
也在源代码和文档中;他们正在转换为使用配置设置,但这都需要时间。
2If you have Git 2.28 or later, run git init --initial-branch=name
, and/or set init.defaultBranch
with git config
in your system or global configuration. If you have an earlier version of Git installed, or have already run git init
, simply use git branch -m
to rename master
to whatever name you like.
error: src refspec main does not match any
来自 Git 的这条错误消息对于新手来说相当神秘,但实际上非常简单。问题是它充满了行话(webster https://www.merriam-webster.com/dictionary/jargon; 维基百科 https://en.wikipedia.org/wiki/Jargon),并将“source”缩写为“src”。
Git 的核心就是提交。什么时候我们clone一个存储库,我们让 Git 可以访问其他 Git。另一个 Git 会查找存储库,而另一个存储库充满了提交。然后我们让 Git 在本地创建一个新的存储库,并将其传输到其中all他们的承诺,并把他们所有的分支机构名称 into 远程跟踪名称。然后我们的 Git 在这个新存储库中创建,one分支名称,基于其分支名称之一。至少,这是正常的过程。 (而且,如果您知道所有这些术语的含义,那就太好了!如果不知道,现在不要太担心它们。这里要记住的一点是,我们得到他们所有的承诺 and 他们没有任何分支机构,然后我们通常就有了 Gitcreate一根树枝与他们的一根树枝相匹配。)
由于 Git 的全部内容都是关于提交的,因此我们所需要的就是复制所有提交,但仅将其中一个分支名称复制到我们自己的存储库中拼写相同的名称的过程。事实上我们的 Git重命名所有分支名称- 因此,除了一个例外,我们根本没有任何分支 - 通常不是很重要。我们自己的 Git 稍后会在必要时自动处理此问题。
当我们使用git push
,我们要求正在读取我们自己的 Git 存储库的 Git 程序连接到其他一些 Git 程序(通常在服务器计算机上运行),然后该程序可以写入其他一些 Git 存储库。我们希望我们的 Git 向他们的 Git 发送我们的一些提交。特别是,我们想发送给他们our new承诺:我们刚做的那些。毕竟,这些是我们放置所有好新东西的地方。 (Git 就是关于提交的,所以这是我们唯一可以放置任何东西的地方。)
Once we've sent these commits, though, we need to their Git to set one of their branch names to remember our new commits. That's because the way Git finds commits is to use branch names.3 The real names of each commit are big ugly hash ID numbers, which nobody wants to remember or look at; so we have Git remember these numbers using the branch names. That way, we only have to look at the branch names, and these names can be meaningful to us: trunk
, or feature/tall
, or tuatahi
, or whatever.
默认情况下和惯例,我们使用的方式执行此操作git push
很简单:
git push origin main
例如。这git push
部分是命令,意思是发送提交并要求他们设置一个名称. The origin
部分是 Git 所说的remote:一个简短的名称,主要包含一个 URL。这main
最后的部分是our分店名称。就是那个ourGit 用于查找我们的承诺。我们会让 Git 发送我们的提交,然后要求他们的 Git 设置their main
too.
最后一部分——我们放入的地方main
这里——Git 称之为refspec。 Refspecs 实际上让我们输入two名称,用冒号或其他几种形式分隔。例如,我们可以使用HEAD:main
as in 阿尔卡的回答 https://stackoverflow.com/a/65173712/1256452(尽管出于技术原因我们可能想使用HEAD:refs/heads/main
在许多情况下)。但在简单的情况下,我们可以只使用一个分支名称:git push origin main
。简单分支名称是 refspec 的简单形式。
为此,源名称必须是我们自己的 Git 存储库中现有分支的名称。这就是问题所在。
(也可以看看在 Git 中推送提交时出现消息“src refspec master does not match any” https://stackoverflow.com/q/4181861/1256452P)
3Git can use any name, not just a branch name. For instance, a tag name works fine. But this answer is about branch names because the question is about branch names, and branch names are the most common ones to use here.
What if our仅 Git 创建master
?
假设我们正在使用 GitHub,并且我们要求 GitHub 制作一个新存储库为了我们。他们运行一种形式git init
提供名称作为新存储库的初始分支名称main
。他们也可能会也可能不会创建一次提交。假设我们确实让他们创建了这一提交。那个承诺将保持README
and/or LICENSE
文件,基于我们使用网络界面选择的内容。创建初始提交实际上创建了分支名称main
.
如果我们现在clone他们的存储库,我们将获得他们的一次提交,该提交将位于他们的分支名称下main
。我们的 Git 将重命名它们main
to origin/main
然后创建一个新的分支名称,main
,以匹配他们的。所以一切都会好起来的。
但是,如果我们创建自己的emptyGit 存储库,使用git init
我们自己,我们的 Git 可能会设置我们,以便我们的第一次提交将创建名称master
. We 不会有main
branch:我们会有一个master
代替分支。
或者,如果我们没有 GitHub,请创建一个初始的commit,GitHub 存储库将完全为空。因为它没有提交,所以它没有分支:只有指定某个提交时,分支名称才允许存在。因此,如果我们克隆这个空存储库,我们也将没有分支,并且我们的 Git 将不知道使用main
:我们的 Git 可能会使用master
。我们又回到了同样的情况,我们的 Git 认为要创建的第一个名称应该是master
.
因此,在这些不同的情况下,我们进行第一次提交,它们都在名为master
。如果我们现在运行:
git push -u origin main
(有或没有-u
;我不会详细介绍-u
这里)我们的 Git 在 Git 存储库中查找名为的分支main
。没有一个!所以我们的 Git 给了我们:
error: src refspec main does not match any
错误信息。
为了解决这个问题,我们可以git push origin master
—它发送我们的提交,然后要求 GitHub 在 GitHub 存储库中创建一个新分支,该分支名称为master
——或者重命名我们的master
到我们想要的任何名称,然后使用该名称:
git branch -m master xyzzy
git push -u origin xyzzy
将使我们都使用的(单个)分支名称成为xyzzy
。如果你想main
在这里,重命名你的master
to main
.
如果您不小心创建了两个分支怎么办?
假设我们使用 GitHub 创建一个新的存储库,并使用新的默认分支名称main
,其中包括使用通常的 README 和 LICENSE 文件进行初始提交。然后我们想都没想就用了git init
在我们自己的机器上创建我们自己的新存储库,并使用其默认分支名称master
,我们做出了一两次承诺master
.
如果我们现在重命名我们的master
to main
:
git branch -m master main
然后尝试推动:
git push -u origin main
我们得到一个不同的 error:
! [rejected] main -> main (non-fast-forward)
原因很简单:They有一个提交,他们发现使用their name main
,我们没有。如果他们改变名字main
要找到我们发送给他们的最后一次提交,他们会lose the 初始提交他们制作了自述文件和许可证文件。
你在这里有很多选择:
-
您可以忽略他们所做的初始提交。毕竟,这只是一个样板提交。你可以告诉他们把它完全扔掉。使用git push --force
正如许多现有的 StackOverflow 答案中所概述的那样。
-
您可以获得他们的初始提交和rebase您对这些提交的提交。这可能有点棘手,因为你的第一次提交是根提交。如果您的第一次提交包含自述文件和/或许可证文件,您将在此处遇到添加/添加冲突。在这种情况下,强制推送可能更简单。
-
您可以获得他们的初始提交和merge你的承诺。在现代 Git 中,这需要使用--allow-unrelated-histories
选项。与 rebase 方法一样,如果您的提交包含 README 和/或 LICENSE 文件,您将遇到添加/添加冲突。生成的存储库还将有两个根提交。这些都不是严重的问题,但它们可能会有点烦人。
要获得他们的提交,只需运行git fetch origin
。这将获得 GitHub 的第一次提交,并使用该名称origin/main
在您自己的 Git 存储库中以记住它。然后您可以:
git rebase origin/main
or:
git merge --allow-unrelated-histories origin/main
来实现rebase或者merge。您可以选择是否将分支重命名为main
,如果您还没有这样做,请在执行所有这些操作之前或之后的任何时间执行此操作。