Errore Git Push: rifiuto di aggiornare il ramo estratto


197

Ho risolto alcuni conflitti di unione, impegnato, quindi 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 cosa potrebbe causare questo errore?



6
In realtà ora avete un modo sicuro per spingere ad un repo non nudo con Git 2.3.0 (febbraio 2015) e git config receive.denyCurrentBranch=updateInstead: stackoverflow.com/a/28262104/6309
VonC

Risposte:


229

Motivo: si sta spingendo in un repository non nudo

Esistono due tipi di repository: nudo e non nudo

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

git init --bare

Quindi, in breve, non è possibile passare a un repository non nudo(Modifica: bene, non è possibile eseguire il push sul ramo attualmente estratto di un repository. Con un repository nudo, è possibile eseguire il push su qualsiasi ramo poiché non ne è stato eseguito il checkout. Per quanto possibile, il push su repository non bare non è comune) . Quello che puoi fare è recuperare e unire dall'altro repository. Ecco come funziona pull requestquello che puoi vedere in Github. Chiedete loro di staccarsi da voi e non vi spingete con forza.


Aggiornamento : grazie a VonC per averlo sottolineato, nelle ultime versioni di git (attualmente 2.3.0), è possibile spingere sul ramo estratto di un repository non bare . Tuttavia, non è ancora possibile spingere su un albero di lavoro sporco , che non è comunque un'operazione sicura.


1
Sì! Questo è corretto grazie! Dato che ho circa un milione di cose da fare, ho clonato accidentalmente la directory di lavoro .... doh!
Funky,

25
In realtà, è possibile eseguire il push su un repository non bare bene, non è possibile eseguire il push sull'unico ramo attualmente estratto .
Nessun uomo,

1
Ci sono dozzine di altri scenari, in realtà. Ad esempio, alcuni dei miei repository sono solo sulla mia workstation e sul mio laptop (non codice, ma note che prendo). Su ciascuna ho due rami, "workstation" e "laptop". Sulla workstation, controllo solo "workstation" e spingo solo sul ramo "workstation" sul laptop (e viceversa).
nessun posto amico

8
In realtà ora hai un modo sicuro per passare a un repository non bare con Git 2.3.0 (febbraio 2015) e git config receive.denyCurrentBranch=updateInstead: stackoverflow.com/a/28262104/6309
VonC

1
@skelly Il tuo clone non è nudo, mentre la copia su github. Quindi, mentre entrambi i cloni hanno tutta la cronologia, la copia su github non ha alcun commit estratto, ma la tua copia lo fa, per permetterti di lavorare!
Shahbaz,

115

Ho risolto questo problema verificando prima che il telecomando non avesse verificato nulla (in realtà non si supponeva), e poi l'ho messo a nudo con:

$ git config --bool core.bare true

Dopo quella git push ha funzionato bene.


3
Questa è la correzione one-liner che stavo cercando .. ma forse spiega i repository nudi non nudi come la risposta di
@shahbaz

Ciò consentirà di inviare la cronologia delle modifiche, ma tali modifiche non si rifletteranno nel repository non nudo.
jhill515,

git config core.bare falsee tu git reset --hard ?
aereo il

1
Come accennato in precedenza, il telecomando non verrà modificato quando si preme su di esso.
user1097111

46

Sommario

Non è possibile eseguire il push verso il ramo estratto di un repository perché rovinerebbe l'utente di quel repository in un modo che molto probabilmente finirà con la perdita di dati e cronologia . Ma puoi spingere in qualsiasi altro ramo dello stesso repository.

Dato che i repository nudi non hanno mai verificato alcun ramo, è sempre possibile eseguire il push in qualsiasi ramo di un repository nudo.

Autopsia del problema

Quando un ramo viene estratto, il commit aggiungerà un nuovo commit con la testa del ramo corrente come suo genitore e sposta la testa del ramo in quel nuovo commit.

Così

A ← B
    ↑
[HEAD,branch1]

diventa

A ← B ← C
        ↑
    [HEAD,branch1]

Ma se qualcuno potesse spingere verso quel ramo tra di loro, l'utente si metterebbe in quella che git chiama modalità testa staccata :

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

Ora l'utente non è più in branch1, senza aver esplicitamente chiesto di estrarre un altro branch. Peggio ancora, l'utente è ora fuori da qualsiasi ramo e ogni nuovo commit sarà semplicemente sospeso :

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

Ipoteticamente, se a questo punto, l'utente verifica un altro ramo, questo commit penzolante diventa un gioco equo per il garbage collector di Git .



22

Per me, il seguente ha fatto il trucco:

git config --global receive.denyCurrentBranch updateInstead

Ho impostato l'unità F :, quasi nella sua interezza, per la sincronizzazione tra il mio desktop di Windows 10 e il mio laptop di Windows 10, usando Git. Ho finito per eseguire il comando sopra su entrambe le macchine.

Innanzitutto ho condiviso l'unità F del desktop sulla rete. Quindi sono stato in grado di clonarlo sul mio laptop eseguendo:

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

Sfortunatamente, tutti i file sono finiti in "F: \ f \" sul mio laptop, non direttamente in F: \. Ma sono stato in grado di tagliarli e incollarli manualmente. Git ha comunque funzionato dalla nuova posizione in seguito.

Quindi ho provato ad apportare alcune modifiche ai file sul laptop, a commetterli e a riportarli sul desktop. Non ha funzionato fino a quando non ho eseguito il comando git config menzionato sopra.

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

AGGIORNAMENTO: ho ancora avuto problemi con le modifiche, in alcuni casi. Alla fine ho appena iniziato a eseguire il pull delle modifiche, eseguendo quanto segue sul computer in cui desidero eseguire il pull degli ultimi commit:

git pull --all --prune


1
Preferisco questo locale al repository git:git config receive.denyCurrentBranch updateInstead
klor

21

cd nella directory repo / che stai spingendo sul computer remoto e inserisci

$ git config core.bare true

Questo non funziona. Il repository rimane vuoto dopo averlo inserito.
Sören,

come detto sopra jhil515, i file non bare non vengono aggiornati, ma solo i database.
Denis Cousineau,

14

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 nudo senza alcuna directory di lavoro associata. In questo caso un numero di comandi che richiede una directory di lavoro verrà disabilitato, come git-add o git-merge (ma si sarà in grado di eseguire il push).

Questa impostazione viene automaticamente indovinata da git-clone o git-init quando viene creato il repository. Per impostazione predefinita, si presuppone che un repository che termina con "/.git" non sia bare (bare = false), mentre tutti gli altri repository sono considerati bare (bare = true).


12

TLDR

  1. Pull & spingere di nuovo: git pull &&& git push.
  2. Ancora un problema? Inserisci in un altro ramo: git push origin master:fooe uniscilo sul repository remoto.
  3. In alternativa, forzare la spinta aggiungendo -f( denyCurrentBranchdeve essere ignorato).

Fondamentalmente l'errore significa che il tuo repository non è aggiornato con il codice remoto (il suo indice e l'albero di lavoro non sono coerenti con ciò che hai spinto).

Normalmente dovresti pullprima ottenere le modifiche recenti e di pushnuovo.

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

git push origin master:foo

quindi unire nuovamente questo ramo sul repository remoto con master.

Se hai modificato intenzionalmente alcuni commit passati git rebasee desideri sovrascrivere repo con le tue modifiche, probabilmente vuoi forzare la spinta aggiungendo -f/ --forceparametro (non raccomandato se non lo hai fatto rebase). Se ancora non funziona, è necessario impostare receive.denyCurrentBranchper ignoreil telecomando come suggerito da un messaggio via git:

git config receive.denyCurrentBranch ignore

3

Forse il tuo repository remoto è nel ramo che vuoi spingere. Puoi provare a fare il checkout di un altro ramo nel tuo computer remoto. Ho fatto questo, che questi errori sono scomparsi e ho spinto il successo sul mio repository remoto. Nota che uso ssh per connettere il mio server invece di github.com.


1

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


1
Nella mia situazione, questo era il caso. La rimozione della .gitcartella sul telecomando mi ha permesso di inviare il commit iniziale.
tim.rohrer

0

Ho avuto questo errore mentre giocavo mentre leggevo Progit. Ho creato un repository locale, poi l'ho preso in un altro repository sullo stesso file system, ho fatto una modifica e ho provato a inviare. Dopo aver letto la risposta di NowhereMan, una soluzione rapida è stata quella di andare alla directory "remota" e verificare temporaneamente un altro commit, spingere dalla directory in cui ho apportato le modifiche, quindi tornare indietro e rimettere la testa sul master.


0

Funziona per me

  1. git config --global receive.denyCurrentBranch updateInstead

  2. git push origin master

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.