Errore Git Push: rifiuto di aggiornare il ramo ritirato

Ho risolto alcuni conflitti di fusione, ho eseguito il commit e poi ho provato a inviare le mie modifiche e ho ricevuto il seguente errore:

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' 

Qualcuno sa che cosa potrebbe causare questo errore?

Esistono due tipi di repository: bare e non-bare

I repository bare non hanno una copia funzionante e puoi inviarli a loro. Questi sono i tipi di repository che ottieni in Github! Se si desidera creare un repository nudo, è ansible utilizzare

 git init --bare 

Quindi, in breve, non è ansible inviare a un repository non nudo (Modifica: non è ansible eseguire il push al ramo attualmente estratto di un repository.Per un repository nullo, è ansible eseguire il push su qualsiasi ramo poiché nessuno è stato estratto. Anche se ansible, il push su repository non bare non è comune) . Quello che puoi fare è recuperare e unire dall’altro repository. Ecco come funziona la pull request che puoi vedere in Github. Chiedete loro di strapparvi e non forzate a spingerli dentro.


Aggiornamento : Grazie a VonC per averlo indicato, nelle ultime versioni di Git (attualmente 2.3.0), è ansible passare al ramo estratto di un repository non nudo . Tuttavia, non si può ancora spingere su un albero di lavoro sporco , che comunque non è un’operazione sicura.

Ho risolto questo problema verificando innanzitutto che il telecomando non avesse eseguito il check out (in realtà non era previsto), quindi lo ha reso disponibile con:

 $ git config --bool core.bare true 

Dopo che la spinta del git ha funzionato bene.

Sommario

Non è ansible eseguire il push su un ramo estratto di un repository perché ciò significherebbe compromettere l’utente di quel repository in un modo che probabilmente si concluderà con la perdita di dati e cronologia . Ma puoi inviare a qualsiasi altro ramo dello stesso repository.

Poiché i repository nudi non hanno mai controllato alcun ramo, puoi sempre passare a qualsiasi ramo di un repository nudo.

Autopsia del problema

Quando viene estratto un ramo, il commit aggiunge un nuovo commit con la testa del ramo corrente come genitore e sposta la testa del ramo come nuovo commit.

Così

 A ← B ↑ [HEAD,branch1] 

diventa

 A ← B ← C ↑ [HEAD,branch1] 

Ma se qualcuno potesse spingere in quel ramo tra di loro, l’utente si metterebbe in quello che git chiama modalità di testa distaccata :

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

Ora l’utente non è più in branch1, senza aver chiesto esplicitamente di controllare un altro ramo. Peggio ancora, l’utente è ora fuori da ogni ramo e ogni nuovo commit penzolerà :

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

Ipoteticamente, se a questo punto, l’utente controlla un altro ramo, allora questo impegno penzolante diventa un gioco equo per il garbage collector di Git.

cd nella directory repo / che stai inserendo nel computer remoto e inserisci

 $ git config core.bare true 

Poiché esiste già un repository esistente, in esecuzione

 git config --bool core.bare true 

sul repository remoto dovrebbe essere sufficiente

Dalla documentazione core.bare

Se true (bare = true), si presume che il repository sia privo di directory di lavoro. Se questo è il caso, verrà disabilitato un numero di comandi che richiedono una directory di lavoro, come git-add o git-merge (ma sarete in grado di inviarlo).

Questa impostazione viene automaticamente indovinata da git-clone o git-init quando viene creato il repository. Per impostazione predefinita, un repository che termina in “/.git” non è considerato nudo (bare = false), mentre tutti gli altri repository sono considerati nudi (bare = true).

Per me, il seguente ha fatto il trucco:

git config --global receive.denyCurrentBranch updateInstead

Ho configurato l’unità F:, quasi interamente, per sincronizzare tra il mio desktop Windows 10 e il mio laptop Windows 10, utilizzando Git. Ho finito per eseguire il comando sopra su entrambe le macchine.

Per prima cosa ho condiviso l’unità F del desktop sulla rete. Poi sono stato in grado di clonarlo sul mio portatile eseguendo:

F: git clone 'file://///DESKTOP-PC/f'

Sfortunatamente, tutti i file finivano sotto “F: \ f \” sul mio portatile, non sotto F: \ direttamente. Ma sono stato in grado di tagliarli e incollarli manualmente. Git ha ancora lavorato dalla nuova posizione in seguito.

Poi ho provato a fare alcune modifiche ai file sul laptop, a commetterli e a rimandarli sul desktop. Questo non ha funzionato fino a quando non ho eseguito il comando git config menzionato sopra.

Nota che ho eseguito tutti questi comandi da Windows PowerShell, su entrambe le macchine.

AGGIORNAMENTO: In alcuni casi, ho ancora riscontrato problemi con i cambiamenti. Alla fine ho appena iniziato a tirare le modifiche, invece, eseguendo quanto segue sul computer che voglio tirare l’ultima commit (s) a:

git pull --all --prune

TLDR

  1. Tirare e spingere di nuovo: git pull &&& git push .
  2. Ancora un problema? Spingiti in un altro ramo: git push origin master:foo e uniscilo sul repository remoto.
  3. In alternativa, forzare la spinta aggiungendo -f ( denyCurrentBranch deve essere ignorato).

Fondamentalmente l’errore indica che il tuo repository non è aggiornato con il codice remoto (il suo indice e la sua struttura di lavoro non sono coerenti con ciò che hai spinto).

Normalmente devi prima pull le ultime modifiche e push nuovo.

Se non ti aiuta, prova a spingere in un ramo diverso, ad esempio:

 git push origin master:foo 

quindi unire questo ramo sul repository remoto con il master.

Se hai cambiato intenzionalmente un commit passato tramite git rebase e vuoi sovrascrivere il repository con le tue modifiche, probabilmente vuoi forzare il push aggiungendo il parametro -f / --force (non consigliato se non hai fatto rebase ). Se ancora non funziona, devi impostare receive.denyCurrentBranch per ignore su remoto come suggerito da un messaggio git tramite:

 git config receive.denyCurrentBranch ignore 

Forse il tuo repo remoto è nel ramo che vuoi spingere. Puoi provare a eseguire il checkout di un altro ramo nel tuo computer remoto. Ho fatto questo, che questi errori sono scomparsi, e ho spinto il successo al mio repository remoto. Si noti che io uso ssh per connettere il mio server al posto di github.com.

Ho questo errore perché il repository git è stato (accidentalmente) inizializzato due volte nella stessa posizione: prima come un repo non nudo e poco dopo come un semplice repo. Poiché la cartella .git rimane, git presuppone che il repository sia non-nudo. La rimozione della cartella .git e dei dati della directory di lavoro ha risolto il problema.