34

每当我尝试使用上传文件时git push -u origin main ,都会出现如下错误

error: src refspec main does not match any
error: failed to push some refs to 'github.com:xxxxxx/xxx-project.git'

但如果我这样做git push -u origin master,它工作得很好,并将我的文件上传到一个名为master. 在签 .git/refs/heads入我的项目时,我看到只有一个名为的文件master,所以我执行git remote update了添加.git/refs/remotes/origin/main但仍然git push -u origin main没有工作的文件。

我试过git push origin HEAD:main但产生了错误:

! [rejected] HEAD -> main (non-fast-forward) error: failed to push some refs to 'github.com:xxxxxxx/xxx-project.git' hint: Updates were rejected because a pushed branch tip is behind its remote hint: counterpart. Check out this branch and integrate the remote changes hint: (e.g. 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.

我想使用 .push 将我的代码推送到主分支git push -u origin main。我怎么做 ?

PS - git 版本 2.29.2,pop_os 20.10.1

Edit1 -git push -f origin HEAD:main将我的代码推送到main分支,但我怎样才能用文件替换master文件mainrefs/heads这样我就不必提及头部并强制我的推送?

4

7 回答 7

49

这是一个多部分的答案,因为这里有两个单独的问题现在纠缠在一起。以下是我们将涵盖的内容的摘要:

  • main对比master
  • error: src refspec main does not match any
  • 协调单独mainmaster分支

这些中的每一个都在其自己的部分中。

main对比master

Git 本身没有特殊的分支名称。1 您可以使用mainmastertrunk或任何其他名称作为您的第一个分支的名称。Git 传统上在master这里使用这个名称,但有一个项目可以使这个名称可配置,因此如果您是法语或西班牙语,您可以使用名称principalor ,première或者primero如果您更喜欢毛利语,您可以使用matuaor tuatahi。目前,您可以在 a git init, 2期间或之后手动执行此操作,但该项目使 Git 自动执行此操作,无需第二步:如果出于任何原因您需要默认任何其他名称,您可以对其进行配置。

与此同时,GitHub 已经选择了跨越式发展,将其默认的初始分支名称main改为master. 但这会让你的Git 和GitHub 的Git 不同步。更多关于 GitHub 的转换,请参阅 Github 中主分支和主分支的区别?


1这种说法存在一些技术缺陷。众所周知,技术上正确是最好的正确,所以让我在这个脚注中添加一些警告:

  • merge branch X into Y当您在分支上Y并运行时,合并会自动生成表单的消息。但是,当您打开时,Git 传统上只生成格式为 的消息。git merge Xmastermerge branch X

  • 一个新的空存储库由git init没有提交,因此没有分支(因为分支只能通过提交才能存在)。但是,您必须这个新的空存储库中的某个分支上。所以 Git 将一些名称存储在名为 的符号引用中HEAD。这是您所在的分支名称,即使该分支名称不存在(尚不存在)。很长一段时间以来,Git 都在其中硬编码了一些代码来将分支名称粘贴master在其中。(实际上,这就是 GitHub 改变的地方。)

  • 源代码和文档中还有许多其他字符串文字master;他们正在转换为使用配置设置,但这都需要时间。

2如果您有 Git 2.28 或更高版本,请在您的系统或全局配置中运行和/或设置with 。如果您安装了较早版本的 Git,或者已经运行,只需使用重命名为您喜欢的任何名称。git init --initial-branch=nameinit.defaultBranchgit configgit initgit branch -mmaster


error: src refspec main does not match any

这条来自 Git 的错误消息对于新手来说非常神秘,但实际上非常简单。问题是它加载了行话(websterwikipedia),并将“source”缩写为“src”。

Git 是关于提交的。当我们克隆一个存储库时,我们的 Git 可以访问其他 Git。另一个 Git 查找一个存储库,而另一个存储库充满了提交。然后我们让我们的 Git 在本地创建一个新的存储库,将所有提交转移到其中,并将所有分支名称转换为远程跟踪名称。然后我们的 Git 在这个新的存储库中创建一个分支名称,基于它们的一个分支名称。至少,这是正常的过程。(而且,如果您知道所有这些术语的含义,那就太好了!如果不知道,现在不要太担心它们。这里要记住的一点是,我们得到了他们所有的提交,而没有他们的分支,然后我们通常让我们的 Git创建一个分支来匹配他们的一个。)

由于 Git 是关于提交的,所以这个过程——复制他们所有的提交,但只复制他们的一个分支名称到我们自己的存储库中拼写相同的名称——就是我们所需要的。我们的 Git重命名了它们所有的分支名称这一事实——因此除了一个例外,我们根本没有任何分支——通常并不是很重要。我们自己的 Git 会在必要时自动处理这个问题。

当我们使用 时git push,我们要求我们的 Git 程序(它正在读取我们自己的 Git 存储库)连接到其他一些 Git 程序(通常在服务器机器上运行),然后该程序可以写入其他一些 Git 存储库。我们希望我们的 Git 向他们的 Git 发送我们的一些提交。特别是,我们想向他们发送我们的提交:我们刚刚提交的那些。毕竟,这些是我们放置所有好新东西的地方。(Git 是关于提交的,所以这是我们唯一可以放任何东西的地方。)

但是,一旦我们发送了这些提交,我们需要在他们的 Git 中设置他们的分支名称之一以记住我们的新提交。那是因为 Git查找提交的方式是使用分支名称。3 每个commit的真实姓名都是大而丑的hash ID号,没人想记住或看;所以我们让 Git 使用分支名称记住这些数字。这样,我们只需要查看分支名称,这些名称对我们来说可能是有意义的:trunk, 或feature/tall, 或tuatahi, 或其他。

默认情况下,我们使用的git push方式非常简单:

git push origin main

例如。该git push部分是表示发送提交并要求他们设置名称的命令。这origin部分是 Git 所说的远程:一个短名称,主要包含一个 URL。最后的main部分,在这里,是我们的分支名称。那是我们的Git 用来查找我们的提交的那个。我们会让我们的 Git 发送我们的提交,然后让他们的 Git 也设置他们的 main

最后一部分——我们在main这里放的地方——就是 Git 所说的refspec。Refspecs 实际上让我们输入两个名称,用冒号分隔,或者其他几个形式。例如,我们可以在Arka 的回答HEAD:main中使用as (尽管出于技术原因,我们可能希望在许多情况下使用)。但在简单的情况下,我们可以只使用一个分支名称:. 简单分支名称是 refspec 的一种简单形式。HEAD:refs/heads/maingit push origin main

为此,源名称必须是我们自己的 Git 存储库中现有分支的名称。 这就是事情出错的地方。

(在 Git 中推送提交时,另请参阅消息 'src refspec master does not match any'


3 Git 可以使用任何名称,而不仅仅是分支名称。例如,标签名称可以正常工作。但是这个答案是关于分支名称的,因为问题是关于分支名称的,而分支名称是这里最常用的名称。


如果我们的Git 只创建了master怎么办?

假设我们正在使用 GitHub,并且我们已经要求 GitHub 为我们创建一个新的存储库。他们运行一种git init提供的形式,作为新存储库的初始分支名称 name main。他们也可能会也可能不会创建一个提交。假设我们确实让他们创建了这个提交。根据我们使用 Web 界面选择的内容,该提交将保存README和/或文件。LICENSE创建该初始提交实际上会创建分支名称main

如果我们现在克隆他们的存储库,我们将获得他们的一个提交,它将在他们的分支名称下main。我们的 Git 会将它们重命名mainorigin/main,然后创建一个新的分支名称main,以匹配它们的名称。所以一切都会好的。

但是,如果我们使用自己创建自己的Git 存储库,git init我们的 Git 可能会设置我们,以便我们的第一次提交将创建 name master。我们不会有main分支:我们将有一个master分支。

或者,如果我们没有让 GitHub 创建初始提交,那么 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

将使我们都使用的(单个)分支名称 be xyzzy。如果你想main在这里,将你的重命名mastermain.

如果你不小心做了两个分支怎么办?

假设我们使用 GitHub 创建了一个新的存储库,其新的默认分支名称main包括一个初始提交以及通常的 README 和 LICENSE 文件。然后,不假思索地,我们git init在自己的机器上使用它的默认分支名称创建了自己的新存储库,master并在我们的master.

如果我们现在将我们的重命名mastermain

git branch -m master main

然后尝试推动:

git push -u origin main

我们得到一个不同的错误:

 ! [rejected]        main -> main (non-fast-forward)

这样做的原因很简单:他们有一个提交,他们发现使用他们的name main,而我们没有。如果他们更改名称main以查找我们发送给他们的最后一次提交,他们将丢失他们所做的初始提交,以及 README 和 LICENSE 文件。

你有很多选择:

  • 您可以忽略他们所做的初始提交。毕竟,这只是一个样板提交。你可以告诉他们把它完全扔掉。使用git push --force许多现有 StackOverflow 答案中的任何一个。

  • 您可以获取他们的初始提交并根据这些提交重新提交您的提交。这可能有点棘手,因为您的第一个提交是root 提交。如果您的第一次提交包含 README 和/或 LICENSE 文件,您将在此处遇到添加/添加冲突。在这种情况下,强制推送可能更简单。

  • 您可以获得他们的初始提交并合并您的提交。在现代 Git 中,这需要使用该--allow-unrelated-histories选项。与 rebase 方法一样,如果您的提交包含 README 和/或 LICENSE 文件,您将遇到添加/添加冲突。生成的存储库还将有两个根提交。这些都不是严重的问题,但它们可能会有点烦人。

要获得他们的提交,只需运行git fetch origin. 这将获得 GitHub 的第一次提交,并使用origin/main您自己的 Git 存储库中的名称来记住它。然后您可以:

git rebase origin/main

或者:

git merge --allow-unrelated-histories origin/main

实现rebase或merge。您可以选择是否将您的分支重命名为main,如果您尚未这样做,则可以在执行所有这些操作之前或之后的任何时间。

于 2020-12-07T00:25:50.077 回答
27

几个小时前,我遇到了类似的问题,但最终弄清楚了错误不断出现的原因以及解决方案。

我做了什么:

  • 我在 GitHub 上创建了一个 git 存储库

  • 在我的代码编辑器(vs 代码)中将我的项目初​​始化为 git 存储库

  • 我使用将 URL 添加到我的存储库中

    git remote add origin https://github.com/xxxxxx/xxxxx.git
    

到这个时候

git remote -v 

可能按预期给出

origin  https://github.com/xxxx/xxxx.git (fetch)
origin  https://github.com/xxxx/xxxx.git (push)

请注意

git branch 

此时不会向您显示任何内容,因为您尚未创建任何分支,也无法创建任何分支。

问题:

当我尝试

git push -u origin main

我有

error: src refspec main does not match any
error: failed to push some refs to 'github.com:xxxx/xxxx.git'

即使使用 git 推荐的命令

git push --set-upstream origin master (or main preferably) 

我得到了同样的错误。

现在解决方案:

在您的项目中添加一个文件,例如 README.md

git add .
git commit -m "added README.md"
git branch -M main   

-M 是重命名你的分支,如果你不希望它被称为 master

最后,

git push origin main
于 2021-03-16T12:32:14.977 回答
6

在进行了更多研究并且空无一物之后,我尝试了一个hack。这里是。

git push -f origin HEAD:main我完全删除了我的本地项目文件夹之后,然后从主分支克隆了我的项目。现在我可以git push origin main用来推送我想要的任何更改。我检查了,现在我的项目位置有一个main文件。.git/refs/heads

于 2020-12-06T22:24:49.327 回答
4

如果这是您第一次推送到主分支,请在提交更改后按照这些步骤操作。我遇到了这个错误错误:

src refspec main does not match any
error: failed to push some refs to 'https://github.com/<my_project_name>.git

并且我在提交之后使用这些步骤进行了修复。在以下代码中更改您的 github 的 URL:

git branch -M main
git remote add origin https://github.com/Sidrah-Madiha/<my_project_url>.git
git push -u origin main
于 2021-03-10T19:18:05.677 回答
1

对我来说,将它添加到~/.ssh/config

Host github.com
  Hostname github.com
  User <your username>
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519

注意:id_ed25519.pub是在我的github授权的SSH密钥中添加的

于 2021-02-15T09:57:02.913 回答
1

您可以使用:

git add . 

如果已经完成,请尝试提交:

git commit -m "First commit for example..."
git branch -M main   

最后:

git push origin main
于 2021-07-24T10:01:42.977 回答
0

您也可能会从主分支克隆您的存储库,现在您正尝试将其提交到主分支。如果您的本地存储库位于主分支中,并且您尝试将其提交到远程存储库的主分支,请尝试使用以下命令。

git push -f origin master:main

于 2021-12-19T10:46:47.783 回答