推送到git时出现非快进错误 [英] Non-fast-forward error when pushing to git
问题描述
当尝试推送到wordpress git repo时出现non-fast-forward
错误,但是像错误消息中所说的那样拉动会给我一条消息,指示一切都是最新的.这是在拉,合并和提交之后.这是我的日志: http://pastebin.com/6M4qLqjG
简而言之,我尝试推动:
ajh$ git push staging master
我得到这个错误,告诉我先拉:
To git@git.wpengine.com:staging/gordo.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'git@git.wpengine.com:staging/gordo.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.
但是如果我尝试拉扯,它将说它是最新的:
ajh$ git pull staging master
From git.wpengine.com:staging/gordo
* branch master -> FETCH_HEAD
Already up-to-date.
这会循环,不知道发生了什么.有什么想法可以使我的repo和本地排队吗?我以前从未见过此non-fast-forward
错误,不确定该怎么做.它还告诉我要结帐母版,但是我只是拉了一下并与母版合并,所以我不认为我应该再尝试一次.
=========使用fix进行编辑============ 这是一个pastebin,其中包含我用来正确推送内容的终端命令.我仍然可以使用关于到底发生了什么的解释.我可以重复这些步骤,但是我真的不明白为什么它们会起作用,而常规的推/拉却不起作用.
基本上,我创建了一个新分支,从master签出,它快速转发了我.在我必须执行git push staging staging
的地方有些奇怪的事情,这上面的分支令人困惑
我查看了您的第二个pastebin链接,发现很多困惑(这并不奇怪,因为git的术语似乎故意故意混淆了 ing )
我认为最好的选择是退后一步,首先看看git术语,并从pastebin中举一些例子.
让我们从远程"开始.
什么是遥控器?
远程只是一个名称,例如origin
或staging
或upstream
,它为git(和您)提供对应git仓库的完整URL的简称.但是git利用了这个短名称,为您提供了远程跟踪分支",我们尚无法描述.首先,我们需要谈论分支".
什么是分支?
以下是粘贴框的一部分:
1. The-Dorfchester:gordo.dev ajh$ git checkout -b trouble
2. M .idea/workspace.xml
3. M wp-content/themes/goTheme2015/blog-loadMore.php
4. M wp-content/themes/goTheme2015/home.php
5. M wp-content/themes/goTheme2015/stylesheets/layout.css
6. M wp-content/themes/goTheme2015/stylesheets/layout.scss
7. Switched to a new branch 'trouble'
8. The-Dorfchester:gordo.dev ajh$ git push trouble
9. warning: push.default is unset; ...
在第1行,您创建了一个新的分支名称trouble
.
在git中,分支"一词至少具有两个不同的含义. 1 有分支名称,例如trouble
,然后在存储在存储库中的提交图,形成了实际的分支.为了与分支名称 区别开来,我们称它们为提交图片段".由于这些都是笨拙的术语,因此请注意,从技术上来讲,提交图是有向无环图或"DAG".因此,此图的一部分是"DAGlet". 2
DAGlet很重要,因为来自git的投诉:
! [rejected] master -> master (non-fast-forward)
在您要求git进行将忘记" DAG的一部分(即丢失DAGlet")的推送时发生.我们待会儿会再讲.
分支与提交
我将假设您有一个合理的提交"概念,该概念在git中保存了您工作的完整快照,更准确地说,是索引"或临时区域"中任何内容的副本—以及提交消息,您的姓名和电子邮件以及进行提交的时间.不过,他们还有另外一件非常重要的事情,我们将在下一节中介绍.
现在让我们看一下2-7行.当您执行此git checkout -b trouble
时,git指出它会将一堆未修改的文件保留为未修改的文件.
我知道您正在尝试执行git push
,并且git push
会推送 commits ,而不是文件.因此,如果您已修改但未提交的文件,则 不能提交那些未提交的更改.
(您没有在其中显示git status
,但是git status
确实是用于查看修改和未提交文件情况的最佳命令.它告诉您您在哪个分支现在(在这里是trouble
,如果您的分支正在跟踪"另一个分支,那么分支的前和/或后是多远.不过,您的git checkout -b
实际上为我们运行了git status
.)>
这意味着在某个时候,您可能应该运行git commit
进行新的提交.当您执行进行新提交时,它会去哪里?
提交添加到分支
每当您进行新提交时,您的新提交都具有上面的另一件事":它具有父ID .对于大多数新提交,其父ID为当前提交".这会将新的提交链接回它之前的提交,我们可以将其绘制为一个小箭头:
A <- B <- C <- D
在这里,我们从最近一次(也是当前的)提交开始,我将其称为D
. D
存储其父提交C
的ID; C
存储其父级B
的ID;和B
存储其父级A
的ID.
我们刚刚绘制了一个DAGlet:我们选择一个起始提交(在本例中为D
),该提交使我们获得了一系列较早的提交.如果我们进行新提交(我们将其称为E
),它将指向D
:
A <- B <- C <- D <- E
我们有更长的DAGlet.
分支名称从何而来?
分支 name 使我们可以找到特定的提交.几乎所有的分支名称都是:它是提交的指针.如果您在分支master
上并且进行了新的提交,则git首先查找当前的提交-它有一个丑陋的40个字符的SHA-1真名",有时您会看到的缩写版本就像b66c9f0
一样,然后从暂存区域,您的姓名和电子邮件,您的提交消息以及此父ID进行一次新提交.然后-这是棘手的部分-git将 new 提交的SHA-1写入分支名称.
以这种方式,分支本身已经增长,并且分支 name 指向分支末尾的新"tip commit".如果它过去以D
结尾,则现在您的D <- E
的名称为master
指向E
而不是D
.提交E
现在是最顶端"的,您的分支(名称)指向E
,整个链从E
开始形成分支(DAGlet).这是之前和之后的:
[before]
A <- B <- C <- D <-- master
[after]
A <- B <- C <- D <- E <-- master
为什么这一切都重要?
当您进入git push
某些提交时,您的git手将提交到另一个git的提交-监听远程存储的URL的git-然后要求该git设置它的分支到您要推送的最尖端的提交.
但是,假设您要求git将您的master
(提交E
)推到他们的一边,并使他们的master
也指向E
.但是,无论出于何种原因,它们的master
现在都存在,但指向不同的提交:
A <- B <- C <- D <- F <-- master (in their repo)
\
E <-- (your proposed replacement)
如果他们的git在回购中将其master
设置为指向提交E
,则将使他们使用与您相同的DAGlet:E
指向D
,指向C
,等等.提交F
-他们拥有的,而您没有的-将丢失.
这是non-fast-forward
的意思.这意味着它们的分支名称指向您在
推入的DAGlet中不具有的提交. .该承诺指向一些父母,这些父母指向更多的父母,依此类推.最终(或什至立即)这些历史提交合并在一起,但是至少有一个您没有的提交,如果它们将分支名称指向您的DAGlet(其副本),则会丢失.
到目前为止的评论:
-
git push
:这需要一个远程名称,即像origin
或staging
这样的短名称,该名称提供用于推送的URL.这是push
之后的第一个单词.任何附加词都是"refspecs",我们尚未定义,但现在让我们说它们由分支名称组成(多数情况下是正确的).您给git一个分支名称,如master
或trouble
,它会尝试使用远程服务器上的另一个分支名称将该名称下的提交推送到远程服务器. (哪个分支名称在远程?好了,我们稍后会看到其他名称.) -
您推送的DAGlet应该简单地 extend 扩展其分支,并向其添加新的提交.从技术上讲,您要求他们将分支设置为的提交应该是他们已经拥有的尖端提交(这是没有实际推动"的情况),或者最终应该指向该提交.您可以添加一个或多个提交,但是在序列中的某个位置,您的一个新提交必须指向其现有的技巧提交.
-
或者,您可以推送他们根本没有的分支名称.如果您在遥控器上创建该名称,则不会丢失任何提交.
侧边栏:push.default
让我们考虑第9行,warning: push.default is unset
.此警告一直贯穿第28行.每次使用远程但没有其他refspec参数运行git push
时,都会发出此警告.要关闭git,建议将push.default
设置为simple
或upstream
.
您可以在每个存储库中执行一次此操作,或在您的个人全局配置(通常是在其中设置用户名和电子邮件)中进行设置:
$ git config --global push.default simple
例如.
如果您确实使用simple
,则git会将您当前的分支(例如trouble
)推送到远程,要求远程更新其其 trouble
.也就是说,这些按分支名称 和simple
进行的推送要求此处的两个不同git(您的系统上的您和他们的远程系统上的git)使用相同的分支名称.>
这回答了您的git要求其git更新哪个分支名称"的问题:如果您推送分支 (我将跳过 Git的 更常见的结帐形式是 在第80行,您遇到了另一个错误: 您当前(仍)在分支 答案很复杂,但是在这种情况下,(至少)某些文件(例如 如果工作树中的文件与当前提交中的文件匹配,则git会感到安全,可以清除工作树版本并将其替换为切换到分支(在这种情况下为 因此,git拒绝更改分支,要求您提交更改的文件,或使用 现在我们进入第89–91行: 这在当前分支 现在我们打第92行: 这要求您的git推送到名为 这两个都和以前有同样的问题: 这使我们进入第131行: 最后,一个命令git喜欢! :-)这次, 让我们跳过另一次错误的结帐,然后继续执行第154行(及其伴随的成功消息): 这一作品.但这并不是因为成功的 一旦提交它们,以使您的工作树干净,使用 第155行确认成功.第156行是 然后运行 这使我们一路到达388行(及其响应行): 此 与以前相同的错误: 这是正确的,但我们只是看到您的 它什么都不做(并且成功). (顺便说一句,这里省略了有关 1 多少含义取决于您如何计算一些更精细的除法.有关更多信息,请参见此问题. 2 请注意,DAGlet是我自己的发明,因此,如果您开始使用它,则可能必须为您的听众定义它. I'm getting a In short, I try to push: and I get this error, telling me to pull first: But if I try to pull, it will say it's up to date: And this will loop, don't know what is going on. Any ideas what I can do to git my repo and local lined up? I've never seen this =========edit with fix============
Here is a pastebin with the terminal commands I used to get things pushed properly. I could still use explanation on what exactly is going on though. I can duplicate these steps but I don't really understand why they work and the regular push/pull didn't. Basically I created a new branch, checked out from master, and it fast-forwarded me. Something weird going on where I have to push to do I looked at your second pastebin link and I see a lot of confusion (not surprising since git's terminology seems almost deliberately confusing). I think the best bet here is to step back and take a look at git terminology first, with some examples from the pastebin. Let's start with "remote". A remote is just a name, like Here's a bit from the pastebin: At line 1, you've created a new branch name, In git, the word "branch" has at least two distinct meanings.1 There are branch names, like DAGlets matter because this complaint from git: happens when you're asking git to do a push that will "forget" part of a DAG, i.e., will "lose a DAGlet". We'll get back to this later. I'm going to assume you have a reasonable notion of "a commit", which in git, saves a complete snapshot of your work—more precisely, a copy of whatever is in the "index" or "staging area"—along with a commit message, your name and email, and the time you make the commit. They have one more thing that's very important, though, which we'll get to in the next section. Let's take a look at lines 2-7 now. When you did this I know you're trying to do a (You don't show a What this means is that at some point, you probably should run Whenever you make a new commit, your new commit has that "one more thing" above: it has a parent ID. For most new commits, the parent ID is "the current commit". This links the new commit back to one before it, and we can draw that as a little arrow: Here, we start with the most recent (and current) commit, which I'm calling We've just drawn a DAGlet: we pick a starting commit (in this case, and we have a longer DAGlet. A branch name lets us find a specific commit. That's almost all a branch name is: it's a pointer to a commit. If you're on branch In this way, the branch itself has grown, and the branch name points to the new "tip commit", at the end of the branch. If it used to end at
When you go to Suppose, though, that you ask your git to push your If their git sets their This is what The DAGlet you push should simply extend their branch, adding new commits on to it. Technically speaking, the commit you ask them to set their branch to, should either be the tip commit they already have (this is a "no actual push" situation), or should eventually point back to that commit. You can add one commit or many, but somewhere in the sequence, one of your new commits has to point back to their existing tip commit. Or, you can push a branch name that they don't have at all. If you create the name on the remote, there won't be any commits for it to lose. Let's consider line 9, the You can do this once per repository, or set it in your personal global configuration (where you normally set your user name and email): for instance. If you do use This answers the question "which branch name does your git ask their git to update": if you're pushing branch That's pretty simple, and that is why this is called Consider lines 35–37: The (I'm going to skip the Git's The more common form of checkout is On line 80 you got a different error: You're currently (still) on branch The answer to that is a bit complicated, but in this case, the errors occur for (at least) some files like If the file in the work-tree matched the file in the current commit, git would feel safe in wiping out the work-tree version and replacing it with the switch-to branch ( So, git refused to change branches, requesting that you either commit your changed files, or use Now we get to lines 89–91: This made a new commit, on the current branch Now we hit line 92: This asks your git to push to the remote named These both have the same problem as before: the word This brings us to line 131: Finally, a command git likes! :-) This time Let's skip one more wrong checkout and proceed to line 154 (and its attendant success messages): This one works. It's not because of the successful Once they were committed, so that your work-tree was clean, git would have been fine with Line 155 acknowledges the success. Line 156 is the output from You then ran That gets us all the way to line 388 (and its response lines): This This is the same error as before: This one is correct, but we just saw that your and it does nothing (and succeeds). (Incidentally, the big spew about 1How many meanings depends on how you count some finer divisions. See this question for more. 2Be aware that DAGlet is my own invention, so if you start using it, you may have to define it for your audience. 这篇关于推送到git时出现非快进错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!trouble
,您的git将要求其git更新名为trouble
的分支.如果您的git正在推送您的master
,它将要求他们的git更新其master
.如果您未命名分支,则要推送的分支是您当前的分支,并且没有棘手的东西,例如在您的存储库中有一个拼写为 35. The-Dorfchester:gordo.dev ajh$ git push trouble trouble
36. fatal: 'trouble' does not appear to be a git repository
37. fatal: Could not read from remote repository.
git push
命令将遥控器作为push
之后的第一个单词.单词trouble
被当作遥控器使用,不起作用(您没有名为trouble
的遥控器). push
代码充满了历史负担,因此之后尝试使用trouble
作为URL,但这也不起作用.git show-branch
输出,因为某些内容已经弄乱了它,删除了前导空白,使其难以阅读.)
git checkout
,这里出了什么问题checkout
命令(在我看来)不必要地复杂,因为它具有太多的操作模式.如果git使用单独的命令切换到不同的分支"与在不更改当前分支的情况下从某个分支中检查特定文件"相比,将不会造成混淆.但是这些都集中在一个git checkout
命令中,所以让我们看一下第75–79行:
75. The-Dorfchester:gordo.dev ajh$ git checkout staging master
76. error: pathspec 'staging' did not match any file(s) known to git.
77. error: pathspec 'master' did not match any file(s) known to git.
78. The-Dorfchester:gordo.dev ajh$ git checkout staging
79. error: pathspec 'staging' did not match any file(s) known to git.
git checkout branch-name
,但是在这种情况下,您要调用其他git checkout
,即git checkout [ branch-name ] [ -- ] path1 path2 ... pathN
,但是可以省去--
.由于staging
不是有效的分支名称,因此将其解释为 path
. (master
是有效的分支名称并不重要,因为staging
处于git checkout
允许分支名称的唯一参数位置.)
80. The-Dorfchester:gordo.dev ajh$ git checkout master
81. error: Your local changes to the following files would be overwritten by checkout:
82. .idea/workspace.xml
83. wp-content/themes/goTheme2015/blog-loadMore.php
84. wp-content/themes/goTheme2015/home.php
85. wp-content/themes/goTheme2015/stylesheets/layout.css
86. wp-content/themes/goTheme2015/stylesheets/layout.scss
87. Please, commit your changes or stash them before you can switch branches.
trouble
上,并且您要求git移至分支master
.要从一个分支移动到另一个分支,git必须替换工作树中某些文件的内容.哪些文件?.idea/workspace.xml
)(1)存储在 current的最新提交中,会发生错误. em>分支; (2)同样在 new 分支的提示中进行提交; (3) new 分支中该文件的内容与当前提交中该文件的内容不同.master
)技巧提交版本.但是您的工作树中的这些文件不与当前提交匹配.我们在运行git status
的原始git checkout -b
中看到了这一点.git stash
提交它们(区别在于git stash
在 no 分支上提交它们而不是当前分支.好,所以您终于提交了它们
89. The-Dorfchester:gordo.dev ajh$ git commit -am "idk"
90. [trouble 820decb] idk
91. 5 files changed, 39 insertions(+), 93 deletions(-)
trouble
上进行了新提交.然后,它将分支移动到指向新提交的位置,该提交的40个字符的SHA-1以820decb
开头.
92. The-Dorfchester:gordo.dev ajh$ git push master
master
的远程服务器.没有一个错误,并且您会收到与先前相同的错误.所有这些还吐出了巨大的烦人设置您的push.default
"消息,这使我们进入了第119行以及第125行:
119. The-Dorfchester:gordo.dev ajh$ git pull master
...
125. The-Dorfchester:gordo.dev ajh$ git push --set-upstream master trouble
master
字在一个远程名称的插槽中,但不是有效的远程.
131. The-Dorfchester:gordo.dev ajh$ git push --set-upstream staging trouble
staging
在用于远程的插槽中,而trouble
在用于"refspec"的插槽中,两者均起作用. (--set-upstream
告诉git push
,一旦推送成功,它应将staging
的trouble
记录为本地staging
的上游分支".参见此答案.)
154. The-Dorfchester:gordo.dev ajh$ git checkout master
155. Switched to branch 'master'
156. Your branch is behind 'staging/master' by 16 commits, and can be fast-forwarded.
157. (use "git pull" to update your local branch)
git push
:这次成功了,因为您最终在trouble
分支上提交了.这样,修改过的文件就安全地存储在存储库中,因为新提交的40个字符的真实名称" SHA-1 ID以820decb
开头.git checkout master
git就可以了.您还将trouble
推送到了名为"staging"的远程服务器上,并在其中也为其命名为trouble
,但这对于git checkout master
步骤并不重要.git status
的输出,告诉您master
位于上游(您的git称为staging/master
)落后16次提交-如果您没有,则有16次提交-并且不是领先于其上游.再次,请参阅我的其他答案(已在上方链接)以获取更多信息.git pull
,实际上是git fetch
,然后是git merge
(这是这两个步骤的便捷包装,但事实证明第二个是错误对于大多数人来说都是如此,因此它是可配置的). git merge
进行了快进"合并,这意味着您没有新的提交,而他们也有新的提交,因此您的git能够将分支向前滑动"到新的分支尖端,并添加了新的DAGlet到您现有的DAG,完全没有大惊小怪.
388. The-Dorfchester:gordo.dev ajh$ git commit -am "pull from staging/master to master, idk"
389. On branch master
390. Your branch is up-to-date with 'staging/master'.
391. nothing to commit, working directory clean
git commit
命令找不到要提交的内容,也没有进行任何新的提交.您的分支master
没有添加新的提交,并且分支提示与以前相同.
392. The-Dorfchester:gordo.dev ajh$ git push master
git push
首先需要一个远程名称.关于push.default
的大声疾呼使我们一路走到:
419. The-Dorfchester:gordo.dev ajh$ git push staging master
git commit
之前未添加任何新提交.因此,您的git在staging
上调用git并发现无事可做:
420. Everything up-to-date
push.default
的内容,因为您为git push
和提供了一个refspec.push.default
设置是如果您不不给出refspec,则应该执行push;即,如果您仅给出refspec,或者不给出任何内容,则如果您不给出git push
,则它将指出基于当前分支的上游设置使用的遥控器.)
non-fast-forward
error when trying to push to a wordpress git repo, but pulling like the error message says gives me a message that everything is up to date. This is right after a pull, merge, and commit. Here is my log: http://pastebin.com/6M4qLqjGajh$ git push staging master
To git@git.wpengine.com:staging/gordo.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'git@git.wpengine.com:staging/gordo.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.
ajh$ git pull staging master
From git.wpengine.com:staging/gordo
* branch master -> FETCH_HEAD
Already up-to-date.
non-fast-forward
error before, not sure what to make of this. It is also telling me to checkout the master, but I just pulled and merged with master so I don't think I should try that again.git push staging staging
, the branches on this are confusingWhat is a remote?
origin
or staging
or upstream
, that provides git (and you) a short name for the full URL of a counterpart git repository. But git takes advantage of this short name to give you "remote-tracking branches", which we can't describe yet. First we need to talk about "branches".What is a branch?
1. The-Dorfchester:gordo.dev ajh$ git checkout -b trouble
2. M .idea/workspace.xml
3. M wp-content/themes/goTheme2015/blog-loadMore.php
4. M wp-content/themes/goTheme2015/home.php
5. M wp-content/themes/goTheme2015/stylesheets/layout.css
6. M wp-content/themes/goTheme2015/stylesheets/layout.scss
7. Switched to a new branch 'trouble'
8. The-Dorfchester:gordo.dev ajh$ git push trouble
9. warning: push.default is unset; ...
trouble
.trouble
, and then there are sequences in the graph of commits stored in the repository, which form actual branches. To distinguish these from branch names, let's call them "commit graph fragments". Since these are unwieldy terms, let's note that the commit graph is, technically speaking, a Directed Acyclic Graph or "DAG". A piece of this graph is therefore a "DAGlet".2 ! [rejected] master -> master (non-fast-forward)
Branches vs commits
git checkout -b trouble
, git noted that it was retaining a bunch of modified-and-not-committed files as modified-and-not-committed.git push
, and git push
pushes commits, not files. So if you have modified but uncommitted files, those uncommitted changes cannot be pushed.git status
in there, but git status
is really the best command to use to see what's going on in terms of modified-and-uncommitted files. It tells you what branch you're on now (which would be trouble
here, and if your branch is "tracking" another branch, how far ahead and/or behind your branch is. Your git checkout -b
effectively ran git status
for us, though.)git commit
to make a new commit. When you do make a new commit, where does it go?Commits add to a branch
A <- B <- C <- D
D
. D
stores the ID of its parent commit C
; C
stores the ID of its parent B
; and B
stores the ID of its parent A
.D
), and that commit gets us a chain of older commits. If we make a new commit—let's call it E
—it will point back to D
:A <- B <- C <- D <- E
Where does the branch name come in?
master
and you make a new commit, git starts by finding the current commit—it has a big ugly 40-character SHA-1 "true name", and sometimes you'll see an abbreviated version of this like b66c9f0
—and making a new commit from the staging area, your name and email, your commit message, and this parent ID. Then—this is the tricky part—git writes the new commit's SHA-1 into the branch name.D
, you now have D <- E
with the name master
pointing to E
instead of D
. Commit E
is now "tip-most", and your branch (name) points to E
, with the whole chain starting at E
forming the branch (DAGlet). Here's the before-and-after:[before]
A <- B <- C <- D <-- master
[after]
A <- B <- C <- D <- E <-- master
Why does all this matter?
git push
some commit(s), you have your git hand the commits to the other git—the git that listens to the URL stored under the remote—and then ask that git to set its branch to the tip-most commit you're pushing.master
(commit E
) to their side and make their master
point to E
too. But—for whatever reason—their master
exists now but points to a different commit:A <- B <- C <- D <- F <-- master (in their repo)
\
E <-- (your proposed replacement)
master
in their repo to point to commit E
, you'll get them to use the same DAGlet you have: E
pointing to D
, pointing to C
, and so on. Commit F
—the commit they have, that you don't—will be lost.non-fast-forward
means. It means they have their branch-name pointing to a commit that you don't have in whatever DAGlet you're pushing. That commit points back to some parents, which point to more parents, and so on. Eventually—or even immediately—those historical commits join up, but there's at least one commit they have that you don't, that would be lost if they make their branch-name point to (their copy of) your DAGlet.Review so far:
git push
: this needs a remote, i.e., a short name like origin
or staging
that provides the URL for pushing-to. That's the first word after push
. Any additional words are "refspecs", which we haven't defined, but for now let's just say they're made up of branch-names (which is mostly true). You give git a branch name like master
or trouble
and it tries to push the commits you have under that name, to the remote, using another branch name on the remote. (Which branch name, on the remote? Well, we'll see something else on this in a moment.)Sidebar:
push.default
warning: push.default is unset
. This warning runs all the way through line 28. This warning comes out every time you run git push
with a remote, but with no additional refspec arguments. To make git shut up, I recommend setting push.default
, to either simple
or upstream
.$ git config --global push.default simple
simple
, git will push your current branch (e.g., trouble
) to the remote, asking the remote to update its trouble
. That is, these pushes work by branch names and simple
demands that the two different gits here (yours, on your system, and theirs, on the remote system) use the same branch name.trouble
, your git will ask their git to update their branch named trouble
. If your git is pushing your master
, it will ask that their git update their master
. The branch you'll push, if you don't name a branch, is your current branch, and there's no tricky stuff like having a branch in your repository that's spelled Raymond-Luxury-Yacht, but on the remote, it's spelled Throatwobbler-Mangrove.simple
. There are four other options but I'll leave them out for this posting.What went wrong here?
35. The-Dorfchester:gordo.dev ajh$ git push trouble trouble
36. fatal: 'trouble' does not appear to be a git repository
37. fatal: Could not read from remote repository.
git push
command takes a remote as its first word after push
. The word trouble
, treated as a remote, doesn't work (you don't have a remote named trouble
). The push
code is full of historical baggage so it tried to use trouble
as a URL after that, and that didn't work either.git show-branch
output as something has mangled it, deleting leading white space, making it too hard to read.)git checkout
, and what went wrong herecheckout
command is (in my opinion) unnecessarily complex as it has too many modes of operation. It would be less confusing if git used separate commands for "switch to a different branch" vs "check specific files out of some branch, without changing the current branch". But these are all lumped into one git checkout
command, so let's look at lines 75–79:75. The-Dorfchester:gordo.dev ajh$ git checkout staging master
76. error: pathspec 'staging' did not match any file(s) known to git.
77. error: pathspec 'master' did not match any file(s) known to git.
78. The-Dorfchester:gordo.dev ajh$ git checkout staging
79. error: pathspec 'staging' did not match any file(s) known to git.
git checkout branch-name
, but in this case, you're invoking a different git checkout
, which is git checkout [ branch-name ] [ -- ] path1 path2 ... pathN
, but you can leave out the --
. Since staging
is not a valid branch name, it's interpreted as a path
instead. (It doesn't matter that master
is a valid branch name, because staging
was in the only argument-position where git checkout
allows a branch name.)80. The-Dorfchester:gordo.dev ajh$ git checkout master
81. error: Your local changes to the following files would be overwritten by checkout:
82. .idea/workspace.xml
83. wp-content/themes/goTheme2015/blog-loadMore.php
84. wp-content/themes/goTheme2015/home.php
85. wp-content/themes/goTheme2015/stylesheets/layout.css
86. wp-content/themes/goTheme2015/stylesheets/layout.scss
87. Please, commit your changes or stash them before you can switch branches.
trouble
and you asked git to move to branch master
. To move from one branch to another, git must replace the contents of some files in your work-tree. Which files?.idea/workspace.xml
that (1) are stored on the most recent commit in the current branch; (2) are in the new branch's tip commit as well; and (3) the contents of that file in the new branch are different from the contents of that file in the current commit.master
, in this case) tip commit version. But these files in your work-tree don't match the current commit. We saw that in the original git checkout -b
when it ran git status
.git stash
to commit them (the difference is that git stash
commits them on no branch, rather than on the current branch).OK, so you finally committed them
89. The-Dorfchester:gordo.dev ajh$ git commit -am "idk"
90. [trouble 820decb] idk
91. 5 files changed, 39 insertions(+), 93 deletions(-)
trouble
. It then moved the branch to point to the new commit, whose 40-character SHA-1 starts with 820decb
.92. The-Dorfchester:gordo.dev ajh$ git push master
master
. There isn't one, and you get the same error as earlier. All of these also spit out that enormous annoying "set your push.default
" message, which gets us to line 119, and also 125:119. The-Dorfchester:gordo.dev ajh$ git pull master
...
125. The-Dorfchester:gordo.dev ajh$ git push --set-upstream master trouble
master
is in the slot for a remote name, but isn't a valid remote.131. The-Dorfchester:gordo.dev ajh$ git push --set-upstream staging trouble
staging
is in the slot for a remote, and trouble
is in the slot for a "refspec", and both of those work. (The --set-upstream
tells git push
that once the push succeeds, it should record staging
's trouble
as the "upstream branch" for your local staging
. For a lot of words on what this all means, see this answer.)154. The-Dorfchester:gordo.dev ajh$ git checkout master
155. Switched to branch 'master'
156. Your branch is behind 'staging/master' by 16 commits, and can be fast-forwarded.
157. (use "git pull" to update your local branch)
git push
, though: it succeeds this time because you finally committed on your trouble
branch. That got the modified files safely stored inside the repository, as that new commit whose 40-character "true name" SHA-1 ID starts with 820decb
.git checkout master
. You also pushed your trouble
to your remote named "staging", giving it the name trouble
there as well, but that's not important for the git checkout master
step.git status
, telling you that your master
is behind its upstream (which your git calls staging/master
) by 16 commits—there are 16 commits they had that you didn't—and is not "ahead of" its upstream. Again, see my other answer (already linked above) for more on this.git pull
, which is really just git fetch
followed by git merge
(it's meant as a convenience wrapper for these two steps, but it turns out the second is the wrong step for most people, so it's configurable). The git merge
did a "fast forward" merge, which means you had no new commits, and they had new commits, so your git was able to just "slide the branch forward" to the new branch-tip, adding their new DAGlet to your existing DAG without any fuss at all.388. The-Dorfchester:gordo.dev ajh$ git commit -am "pull from staging/master to master, idk"
389. On branch master
390. Your branch is up-to-date with 'staging/master'.
391. nothing to commit, working directory clean
git commit
command found nothing to commit, and did not make any new commits. Your branch master
has no new commits added and the branch tip is the same as it was before.392. The-Dorfchester:gordo.dev ajh$ git push master
git push
wants the name of a remote, first. The big spew about push.default
gets us all the way to:419. The-Dorfchester:gordo.dev ajh$ git push staging master
git commit
earlier added no new commits. So your git calls up the git on staging
and finds there's nothing to do:420. Everything up-to-date
push.default
is omitted here because you gave git push
both a remote and a refspec. The push.default
setting is what push should do if you don't give a refspec, i.e., if you give it only a remote, or give it nothing at all. If you give git push
nothing at all, it will figure out the remote to use based on the current branch's upstream setting.)