push教學 - git remote remove




Git推送錯誤:拒絕更新簽出分支 (6)

概要

您不能推送到存儲庫的一個已簽出分支,因為它會以最可能以數據和歷史丟失而告終的方式混淆該存儲庫的用戶。 但是您可以推送到同一個存儲庫的任何其他分支。

由於裸存儲庫永遠不會檢出任何分支,因此可以始終將其推送到裸存儲庫的任何分支。

對問題進行驗屍

當一個分支被簽出時,提交將添加一個新的提交,並且將當前分支的頭部作為它的父對象,並將該分支的頭移到該新提交。

所以

A ← B
    ↑
[HEAD,branch1]

A ← B ← C
        ↑
    [HEAD,branch1]

但如果有人可以推送到這個分支之間,用戶會自己進入git 分離的頭部模式:

A ← B ← X
    ↑   ↑
[HEAD] [branch1]

現在用戶不再處於branch1中,沒有明確要求檢出另一個分支。 更糟糕的是,用戶現在處於任何分支之外 ,任何新的提交只會是懸而未決的

      [HEAD]
        ↓
        C
      ↙
A ← B ← X
        ↑
       [branch1]

假設,如果在這一點上,用戶檢出另一個分支,那麼這個懸而未決的提交就變成了Git的垃圾收集器的公平遊戲。

我解決了一些合併衝突,然後嘗試推送我的更改並收到以下錯誤:

c:\Program Files (x86)\Git\bin\git.exe push --recurse-submodules=check "origin" master:master
Done
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To C:/Development/GIT_Repo/Project
 ! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to 'C:/Development/GIT_Repo/Project'

有誰知道什麼可能導致這個錯誤?


TLDR

  1. 再次推拉: git pull &&& git push
  2. 仍然是一個問題? 推入不同的分支: git push origin master:foo並將其合併到遠程repo上。
  3. 或者通過添加-f (需要忽略denyCurrentBranch來強制推送。

基本上這個錯誤意味著你的版本庫沒有與遠程代​​碼保持一致(它的索引和工作樹與你推送的版本不一致)。

通常情況下,您應該首先獲取最近的更改並再次push

如果沒有幫助,請嘗試推入不同的分支,例如:

git push origin master:foo

然後將該遠程存儲庫上的分支與主服務器合併。

如果你通過git rebase有意地改變了一些以前的提交,並且你想用你的改變覆蓋repo,你可能想通過添加-f / --force參數來強制推送(如果你沒有進行rebase不建議)。 如果仍然無法正常工作,您需要通過以下方式將receive.denyCurrentBranch設置為在git消息中建議的遠程ignore

git config receive.denyCurrentBranch ignore

也許你的遠程倉庫在你想推的分支中。 您可以嘗試在遠程計算機上簽出另一個分支。 我做到了,比這些錯誤消失了,我把成功推向了我的遠程倉庫。 請注意,我使用ssh連接我自己的服務器而不是github.com。


存儲庫有兩種類型: 裸露和非裸露

裸倉庫沒有工作副本,您可以推送給他們。 這些是你在Github中獲得的倉庫類型! 如果你想創建一個裸倉庫,你可以使用

git init --bare

因此,簡而言之, 您無法推送到非裸倉庫 (編輯:那麼,你不能推送到存儲庫的當前簽出分支,只有裸倉庫,你可以推送到任何分支,因為沒有簽出。儘管可能,推送到非裸倉庫並不常見) 。 你可以做的是從另一個存儲庫獲取並合併。 這就是你在Github中看到的pull request工作原理。 你要求他們從你身上拉開,而你不會強迫他們進入。

更新 :感謝VonC指出了這一點,在最新的git版本(目前是2.3.0)中, 推送到非裸存儲庫的檢出分支是可能的 。 儘管如此,你仍然無法推到一棵骯髒的工作樹,無論如何這不是一個安全的操作。


我有這個錯誤,因為git倉庫在同一個位置(偶然)被初始化了兩次:第一次是非裸回購,第二次是裸回購。 因為.git文件夾仍然存在,所以git假定存儲庫不是裸露的。 刪除.git文件夾和工作目錄數據解決了問題。


我通過首先驗證遠程沒有檢出任何東西(它實際上不應該)來解決此問題,然後通過以下方法將其裸露:

$ git config --bool core.bare true

之後,git push正常工作。





git-push