为什么我必须运行这个git命令?

时间:2016-08-02 18:02:37

标签: linux git

在某个时候检查了同事的分支 我push无法pullremote。 每次我运行git pushgit push origin branch_name或那些变体时,即使我提交了更改,我也总是得到everything up to date。最终,诀窍是git push -f origin HEAD:origin/branch_name。所以我的问题是,为什么我必须运行它?我到底做了什么?

我得到的致命错误是: fatal: You are not currently on a branch.To push history leading to current (detached HEAD) state now, use: git push origin HEAD:<name-of-remote-branch>

2 个答案:

答案 0 :(得分:3)

当前状态:您的头部未附加到分支,因此您使用其历史记录与遥控器相同的分支进行推送。你正在使用一个独立的头部,所以当你推动头部而不是分支时,它起作用了。

如果您使用show:

进行git status
  

HEAD在XXXXXXX分离

修复它: 既然您的遥控器已经进行了更改,您可以签出branch_name并从远程拉出您的更改。您的branch_name应该已经在跟踪该远程分支。

为什么你必须这样做:你以某种方式脱离了头脑。如果不知道您使用的命令,我们将无法告诉您为什么必须这样做。

如何做到这一点的一个例子:

#Don't do this, because force pulling will make you lose your work.
git checkout --detach
git pull --all -f #Don't do this.

答案 1 :(得分:2)

你应该在你的问题中编辑你的最后两个(呃,现在,三个 - 评论的部分内容,但是现在,我只是在这里引用它们:< / p>

  

我找到了可能在路上的地方。当我检查出我要继续工作的分支时,我收到了这条消息(让我们称之为分支b1

Branch b1 set up to track remote branch b1 from origin.
Switched to a new branch 'b1'.
     

我以这种方式检查了分支:

git checkout b1.
     

然后,当我试图推动时,我做了:

git push --set-upstream origin b1.
Branch b1 set up to track remote branch b1 from origin.
Everything up to date

好的,在那种情况下你很可能。

git checkout

你遇到的问题(好吧,在我看来这是一个问题)是git checkout疯狂三四个(或更多,取决于你如何计算)不同

通常你会使用:

git checkout somebranch

签出(切换到)您当地的分行somebranch。当然,这对于已经拥有的分支机构来说非常棒,但对于在本地尚未拥有的分支机构来说没有任何好处。所以Git将另一个不同的命令引入git checkout:&#34;创建新的分支,然后切换到它&#34;命令。

通常此命令拼写为git checkout -b newbranch-b标志表示&#34;创建新的&#34;。让这个命令与git checkout拼写相同只是一个标志是非常合理的,因为我们正在切换到这个新创建的分支,但如果它是一个单独的分支可能会更清楚命令,例如git create-and-then-switch-to-new-branch

现在,通常情况下,当您创建一个新的本地分支时,您正在使用 intent 来实现这一目标远程跟踪分支,origin/b1或其他。在这种情况下,您最初必须输入:

git checkout -b b1 --track origin/b1

仍然非常明显:创建新分支b1,将其基于远程跟踪分支origin/b1,并使其跟踪(具有上游){{ 1}}。同样,这可能会更加清晰origin/b1,但将它推入git create-and-then-switch-to并不是那么糟糕,加上git checkout要短一些,要打字!

现在,很多年前(早在2013年左右),Git的人们看到这个动作非常普遍,并且决定让Git做到这一点#34;神奇地&#34;在某些情况下 。如果你写:

checkout

您目前没有分支git checkout b1 目前有{{1} } 您没有其他远程跟踪分支,其名称以b1 然后结尾(并且只有这样!),origin/b1使用create-and-then-switch-to-new-branch命令 with b1标志。所以:

git checkout

装置

--track

在这一个特殊(但很常见)的情况下

git checkout b1 表示&#34;设置上游&#34;

每个分支(好吧,每个名为,本地,分支)可以有一个(1)&#34;上游&#34;组。分支的上游有许多用途:git checkout -b b1 --track origin/b1 --trackgit statusgit fetchgit merge都在查看上游。拥有上游集使git rebase显示您在当前分支的上游提前和/或后面提交了多少次提交。并且,它允许您在没有其他参数的情况下运行所有​​其他命令:它们可以使用当前分支的名称及其上游设置来确定从哪里获取,或者要合并或重组什么,或者要推送什么。

默认情况下,分支机构 没有上游,而您创建的新分支也没有。而且,如果它是一个非常新的&#34;例如,在git push上不存在的分支 - 在那里,首先还没有git status作为上游。但是当您从远程跟踪分支创建新分支时,将远程跟踪分支设置为新分支的上游几乎总是正确的。

(注意:上游也会影响origin,因为origin/name只有git pull后跟git pullgit fetch。直到他们非常熟悉Git,我认为大多数人在首先运行git merge,然后git rebasegit fetch秒运行明显更好,具体取决于他们想要哪一个 - 更常见的是,实际上{ {1}}, git rebase的默认值:git merge默认使用git rebase秒。一旦他们熟悉fetch-and-whatever序列,然后人们可以配置git pull来执行他们想要的那个,并使用git pull作为运行这两个命令的快捷方式。但是,有时候仍然要将它们分开。)

完整性

git merge可以做的其他事情,更改当前分支,是:

  • 将文件从索引复制到工作树:git pull,包括特殊git pullgit checkout版本
  • 将指定提交的文件复制到索引,然后复制到工作树:git checkout -- <paths>
  • 将冲突的合并文件恢复到冲突状态:git checkout --ours(与git checkout --theirsgit checkout <tree-ish> -- <paths>一样,这仅适用于冲突合并期间)
  • 以交互方式修补文件:git checkout -m -- <paths>(此变体特别复杂,我不打算进一步解决)

--ours命令也可以&#34;分离HEAD&#34; (见下面的上一个答案)并创建&#34; orphan&#34;分支,但这两者都有效地改变了你目前的分支,所以他们不会陷入这种特殊的“非分支变化”的分支中。 --theirs次操作。

那么第一个git checkout -p

发生了什么

当你跑步时:

checkout

你告诉你的Git要联系checkout上的其他Git,给它你的分支git push指向的提交ID,看它是否需要任何提交和文件(它没有&#39} ; t),然后让它设置分支名称git push --set-upstream origin b1 以指向同一个提交。

现在,您刚刚从origin创建了自己的本地b1b1来自b1,所以你的origin/b1 git fetch已经指向相同的提交(你没有做任何新的提交),因此你的origin给了他们自己的提交哈希回来,他们说& #34;好吧,天啊,这就是我已经拥有的东西!我们都是最新的!&#34;然后他们的Git和你的Git彼此说再见,你的Git执行了你的最后一条指示:b1

这会将您本地分支git push的上游更改为--set-upstream。当然,这是已经你当地分支b1的上游,所以这不是一个很大的改变。 :-)但是你的Git无论如何都做了,然后报告说一切都还是最新的。

早期答案(主要是在您添加第三条评论时完成)

  

...我有一个文件已提交更改。我承诺后origin/b1没有任何回报。

b1应始终打印某些内容,例如(两个实际示例):

git status

或:

git status

在第二种情况下,你处于&#34;分离的HEAD&#34;模式。这种特殊模式意味着你不在一个分支上 - 或者说你在(单个,特殊情况下)匿名分支上,一旦你上任,它就会更准确其他分支。

在分离的HEAD模式下进行的任何提交都非常精细,正常提交 - 除了 没有将使它们永久化的分支名称。 这意味着这些提交一旦你切换到其他分支就可以离开。

  

On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working directory clean 的所有尝试都没有成功。

同样,实际的HEAD detached at 08bb350 nothing to commit, working directory clean 输出可能会有所帮助,因此可以告诉为什么推送失败或什么都不做。如果它抱怨在'#34;分离的HEAD&#34;模式,这将是重要的:我们会知道你处于分离的HEAD模式。

  

push也没有返回任何内容。

(暂且不说:在这里使用git push有点奇怪:该标志几乎从不对人类有用,并且更多用于编写脚本。它只是让你的git fetch -a追加到-a而不是覆盖它。特殊的fetch名称用于脚本使用。)

  

我的最后一步是FETCH_HEAD

这将带你离开你以前的任何分支,并把你带入&#34;分离的HEAD&#34;模式。如果你曾经在&#34;分离的HEAD&#34;模式,它将放弃您之前的匿名分支,并将您置于一个新的,不同的匿名分支。

您在之前的匿名分支上所做的任何提交都是......好吧,而不是丢失,确切地说,但现在很难找到(并且设置为在30天后过期)。

  

当我试图从那里推出时,我收到以下消息:

FETCH_HEAD
     

我做了[git checkout origin/branch_name]并且有效

是的,但是,这没有任何用处,因为您现在位于 fatal: You are not currently on a branch. To push history leading to current (detached HEAD) state now, use: git push origin HEAD:<name-of-remote-branch>. 完全相同的匿名分支上。这最终要求远程创建远程,作为本地分支 - 名称... HEAD:origin/branch_name。这可能不是一个好主意,因为拥有一个名为origin/branch_name的本地分支就像拥有一辆名为&#34; motorcycle&#34;的自行车。如果你还有一辆摩托车,并要求你的朋友给你带来摩托车&#34;他将给你带来一辆名为&#34; motorcycle&#34;或摩托车的自行车?