[英]How to interpret git error during repo update?
我正在尝试更新我的Github存储库。
操作系统/配置 :在MacBook Air上使用OS X 10.10.5(Yosemite)
完成以下命令后:
$ git init
$ git add
$ git commit -m "added new stuff"
$ git remote add origin https://github.com/user/repo.git
$ git push -u origin master
我收到此错误:
To https://github.com/user/repo.git>
! [rejected] master -> master (fetch first)
error: failed to push some refs to
'https://github.com/user/repo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first 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.
然后我尝试了...
$ git pull --commit https://github.com/user/repo.git
我知道了
Merge https://github.com/user/repo
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
题
这些错误在英语中是什么意思? 接下来我该怎么办?
有没有一种方法可以仅“转储”队列中的所有内容(而无需尝试“拉出”),这样我就可以继续进行新的提交了? 我对下一步该怎么办感到很困惑。
首先,让我建议您阅读Pro Git书 ,因为git随附的大多数文档都非常糟糕,尤其是对于新手。 (与5年前相比有所改进,但仍然有很多不足之处。)
就是说,让我在这里尝试快速介绍“您需要知道的内容”。
git push
的反义不是git pull
,实际上是git fetch
。 我认为您收到的错误消息不应直接引用git pull
; 我们也会对此进行详细介绍。 git log
输出中看到的长40个字符的十六进制内容。 每个提交都有一组由SHA-1 ID标识的“父”提交。 您可以自己使用SHA-1 ID,但是它们对人类非常不友好,您永远不会记住应该以f13c9ab
还是0e1d227
或其他任何f13c9ab
0e1d227
(这些都是缩写 ID!)。 master
。 分支名称只是您告诉git用来跟踪在该分支上所做的最新提交的名称。 给定最后三项,让我们绘制一个提交图片段:
... <- 1f3a33c <- 98ab102 <-- branch
在这里,分支的尖端是commit 98ab102
,其父节点是1f3a33c
。 我们可以说名称branch
“指向” 98ab102
,它指向其父级,依此类推。
当您创建一个新的存储库( git init
,假设实际上是2 )时,它完全没有提交,因此第一个提交没有父级。 它是第二个和第三个提交,以此类推,它指向以前的提交。
当您进行“合并”时,您告诉git接受两个(或三个,但现在仅说两个)现有的提交,并通过合并来自某些提交的所有更改来进行一个新的提交,将两者作为父提交共同点。 合并不是那么复杂,但是您通常应该在故意将工作划分为不同的开发线之后进行合并。
您已经创建了一个新的存储库( git init
),至少放入了一个提交( git commit
),并添加了一个“远程”( git remote add origin ...
)。 最后一步说:“我有一个对等git,我想称其为origin
,所以请记住该名称下的URL。”
然后,您要求您的git调用“ origin”( git push ... origin
),并根据您的分支名称“ master”( git push ... master
)找到您提交的提交。 这是有点棘手的地方。 当你的git的会谈,他混帐,应他的混帐使用什么名字? 简短的答案是, 他的 git也将使用master
名称。 这是可变的,但是更改不是您想要的。
(您还通过-u
标志要求让git在您的git配置中记录此交换。我们暂时将其保留。)
当您的git调用自己的git时,您的git会说“在这里,查看这些闪亮的新提交”(然后他做了),然后您的git说道:“为什么不将这些新提交完全按原样添加到您的存储库中, 4和使您的master
指向这些承诺中最重要的一个?” 他的回答是:“嗯,我能做到这一点,但我会失去一些提交我有你没有。” 在这里您可以看到被rejected
消息。
也许您希望他们到目前为止忘记他们的东西。 如果是这样,您可以要求“强制推送”,即使您的git“丢失”了某些提交,您也可以让他们的git告诉他们设置master
。 是否执行此操作仍由他们决定,但通常不是您想要的。
也许您想拿起他们拥有的东西并将其添加到您的收藏夹中,或者拿起他们拥有的东西并抛弃自己的工作。 这是您要git fetch
。
什么git fetch
呢,去复杂尽可能,5是调用通过互联网,手机同行,并找出他们有什么, 你不知道。 它带来了所有这些提交(记住,交换是通过提交进行的),并将它们(类似于Borg)添加到您的存储库中。 然后,这是至关重要的部分,它将更改其分支名称,以便它们不会干扰您的分支名称。
git fetch
用于与您的同级同步的名称称为“远程跟踪分支”,有时也称为“远程分支”。 关于“远程分支机构”的一件奇怪的事是它们实际上不在远程! 它们保存在您自己的存储库中。 原因很简单:它们是git上次与该远程通话时的远程快照。 在两个git挂断Internet电话后,可以更改遥控器。 (当然,远程实际更改的速度取决于远程git的繁忙程度。)
此处的重命名模式很简单:以遥控器的分支名称(如master
)并在前面添加遥控器的名称( origin
):您的origin/master
“跟踪” origin
的master
。 (有一种全名表格,如果您意外地命名了自己的纯本地,非远程跟踪分支或origin/oops
分支的话,则可以使用,但最好的选择是一开始就不要这样做。 )
git pull
从哪里来? 注意,到目前为止,都是git push
和git fetch
。 但是,假设您已经完成了git fetch
并完成了他们的工作? 现在你有一个有点问题:你有你的工作,你有自己的工作,而这两个有分歧。
如果你们都是从一个共同的基础开始,我们可以这样绘制您的提交图:
... base <- yours <-- HEAD -> master
\
theirs <-- origin/master
这次我放入HEAD ->
以显示您所在的分支(运行git status
,您应该在其输出中看到“ on branch master”)。
将这两个不同的工作联系在一起的一种简单方法是使用git merge
。 如果你想这样做,你只要运行git merge origin/master
(注意斜线:你希望你的git找到你的 origin/master
,它在拿起git fetch
和合并到这一点你的master
,使一个新的提交在您的master
)。 结果看起来像这样:
... base <- yours <- merge <-- HEAD -> master
\ /
theirs <-- origin/master
处理此问题的另一种方法(实际上通常是更好的方法)是使用git rebase
,我在这里不做详细介绍。 关于使用rebase
,有很多StackOverflow答案。 但是,如果这样做,您将获得:
... base <- theirs <- yours <-- HEAD -> master
\
.......... <-- origin/master
(请注意,在所有情况下, origin/master
仍然指向最尖端的“其”提交。)
现在要牢记的主要一点是,无论您做什么,如果想让他们的git接受您的提交而不必强行按下,则需要使您的工作成为他们的附加内容,以便您新的提交“指向”他们的。 push
过程并不重要,您的工作是将其作为合并提交的“第二父级”,还是直接在其提交上进行构建; 它只需要通过提交ID指向其提交即可。 (但同样,重新设置通常比合并好!)
git pull
(finally!)... 简化的git pull
所做的只是运行git fetch
然后git merge
。 简而言之,它是一个方便脚本:您总是先获取然后合并,因此我们将为您提供一个先获取然后合并的脚本。
当然, git merge
通常是错误的。 默认情况下,它确实应该使用git rebase
。
您可以使 git pull
使用git rebase
6,但是我认为至少(或者特别是对新手)使用两个单独的步骤是明智的,部分原因是如果出现问题,从中恢复的方式会有所不同两种不同的动作。 要摆脱失败的合并,请使用git merge --abort
。 要摆脱失败的rebase,可以使用git rebase --abort
。 (这些曾经更加不同,现在只是“中止一切失败”,这是一个很大的改进。但是您需要知道该怎么做,如果您从git merge
或git rebase
开始,这将变得非常清楚。)
最后,您需要在此处执行的操作取决于您要执行的操作以及遥控器允许您执行的操作。 如果您想放下它们的东西,请使用git push -f
(强制),要知道您正在以这种方式使他们(无论他们为谁)感到痛苦,并且他们可能会完全禁止这样做。 如果要保留它们的内容,请先使用git fetch
,然后按自己的意愿保留它们的内容(合并,变基,重做等)。
1或带有补丁,您可以通过电子邮件与同行交换。 也可以“捆绑”提交并通过其他方法转移它们。 但是在这种情况下,我们正在通过Internet电话进行基于提交的交换。
2您可以在现有存储库中安全地运行git init
。 它的作用很小,但就我们的目的而言,它基本上什么也没做,因此需要说“假设它确实能做到”。
3 Git将此称为“章鱼”合并,即使只有3个或4个父级而不是8个。
4 Git通常只会添加“更多内容”。 我喜欢将其称为“ Git Borg” ,其中git在其现有系列中增加了您的技术独特性。
5 git的一个共同主题是“这是不太你想要什么?没关系,我们会保持现有的东西, 但要更复杂 ,所以你可以做你想做什么呢!”
6见脚注5。
GIT告诉您先获取。 您可以在日志中看到
$ git fetch -all
可能其他人已经推动精通,而您的承诺落伍了。 因此,您必须获取,合并更改集,然后才能再次推送。
如果显示遥控器上有更改,请执行“ Pull”操作,这将更新您的工作目录。
$ git pull
然后您将更改推送到遥控器
$ git push -u origin master
我希望这会帮助您将更改推向大师
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.