Come forzare il push di un ripristino nel repository remoto?


94

Il nostro ramo principale remoto in qualche modo è stato incasinato. Il codice di sviluppo corrente si trova sul ramo master insieme agli ultimi commit. Ovviamente, il codice di sviluppo non è pronto per il ramo master.

Così il mio repository locale, ho fatto un reset per l'ultima etichetta, git reset --hard (Tag). Il ramo master è ora corretto nel mio repository locale. Ora quando provo a inviare le modifiche al repository remoto git push origin master, ottengo un errore:

To (REMOTE GIT REPOSITORY LOCATION)
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to '(REMOTE GIT REPOSITORY LOCATION)'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

Quindi dopo essermi guardato intorno ho scoperto l' --forceopzione. Quindi ho forzato il repository remoto git push --force origin mastere ho ancora ricevuto un errore:

Total 0 (delta 0), reused 0 (delta 0)
remote: error: denying non-fast-forward refs/heads/master (you should pull first)
To (REMOTE GIT REPOSITORY LOCATION)
 ! [remote rejected] master -> master (non-fast-forward)
error: failed to push some refs to '(REMOTE GIT REPOSITORY LOCATION)'

Non posso eseguire un pull sul master, perché contiene codice di sviluppo che non può essere sul master.


3
Penso che il messaggio significhi che non hai i diritti per eseguire una spinta non rapida in avanti.
svick

3
Avevi ragione, grazie. Nel file di configurazione per il repository in remoto, denyNonFastforwards = true. L'ho cambiato in falso, ho inviato le mie modifiche e poi l'ho cambiato di nuovo in vero. Grazie ancora a tutti, per l'aiuto.
samwell

2
@samwell, per favore contrassegna la risposta di svick come accettata
hultqvist

@samwell la risposta di svick ha funzionato per te o no?
Songo,

Per coloro che hanno bisogno di dettagli su come disabilitare denyNonFastForwards come ha fatto Samwell, ulteriori istruzioni possono essere trovate qui:
stackoverflow.com/a/43721579/2073804

Risposte:


152

Il messaggio significa che non sei autorizzato a eseguire il push senza avanzamento rapido.

Il tuo repository remoto ha molto probabilmente denyNonFastforwards = truenella sua configurazione. Se lo cambi, git push --forcedovrebbe funzionare.

Per modificare l'impostazione, è necessario accedere alla macchina con il repository remoto. Da lì, fallo git config receive.denynonfastforwards false.


1
Puoi fare una git configper un server? O forse lo stavi usando metaforicamente. Per giocare con queste idee ho creato un repository di prova in /opt/git(il mio spazio server git) e poi ho modificato questa impostazione in /opt/git/the_repo/the_repo.git/config. Ma una volta fatto il lavoro git push --force origin SHA:branchcome richiesto.
HankCa

4
Il messaggio di errore avrà una riga che inizia con "errore: impossibile inviare alcuni riferimenti a <il tuo repository>" dove <il tuo repository> è il percorso che termina con .git che è una directory contenente un file chiamato "config". Questo file "config" è dove puoi impostare denyNonFastforwards = false
emery

1
Il commento di @emery è prezioso. A volte la cartella sul server avrà la sua origine impostata su qualcosa come /srv/git/repo.git. Questa è la configurazione che ha impostato denyNonFastForwards, non la cartella dell'applicazione.
Elijah Lynn

1
@hsalimi Se non hai accesso al server, devi contattare l'amministratore del server e chiedergli di spegnerlo temporaneamente in modo da poter forzare il push e quindi riaccenderlo. Tuttavia, è improbabile che la maggior parte sia in grado di farlo. Potrebbe essere più comune in un ambiente interno con il tuo team di hosting.
Elijah Lynn

1
Questo inizialmente è frustrante, ma il bello è: il telecomando è totalmente protetto per impostazione predefinita e se tu come sviluppatore stai intenzionalmente e correttamente facendo rebase, puoi sovrascrivere questa configurazione per consentire il comportamento pericoloso. Il rebase è qualcosa che ogni utente git dovrebbe sapere come fare e sapere quando non farlo. doc1 doc2
moodboom

15

Il telecomando non consente avanzamenti non rapidi.

La tua migliore opzione è per git reverttutti i commit che non dovrebbero esserci e stai più attento in futuro.

git revert [commit]creerà un nuovo commit che annulla tutto ciò che è stato [commit]fatto.


Sono state alcune impostazioni del repository remoto a bloccare tutte le modifiche non rapide.
samwell

Se lo fai e devi riapplicare i commit, la cronologia non viene rimossa in un ripristino solo delle modifiche al codice e non sarai in grado di selezionare i commit o l'unione
mtpultz

12

Passaggi per abilitare in modo permanente la spinta forzata nel seguente stile

git push -f myrepo my-branch

Modifica il file denominato "config" nella cartella che termina con ".git" sul tuo repository remoto

Nell'output della riga di comando di git dal push non riuscito, cerca la riga che dice qualcosa come:

error: failed to push some refs to 'ssh://user@some-remote-server.mycompany.com/srv/git/myrepo.git

poi

ssh user@some-remote-server.mycompany.com
cd /srv/git/myrepo.git
vi config

Imposta "denyNonFastforwards" su false

In "config", imposta

[receive]
        denyNonFastforwards = false

Ora puoi eseguire il push dalla tua macchina locale con -f

git push -f myrepo my-branch

Come farlo senza accedere a SSH per il repository git nudo?
Vladimir Vukanac

Forse usare il comando git revert come suggerisce richo? Se esegui prima il backup dello stato corrente del repository, puoi comunque unire il codice per andare avanti.
smerigliato

git revertè un po 'complicato quando si hanno fusioni. Per essere più complicato, il mio caso ha 3 merge, di cui uno con commit ~ 20 molto vecchio divergente dallo sviluppo, il 2 ° è una specie di fusione dal master - brutto come l'inferno.
Vladimir Vukanac

1
Forse la soluzione è ripristinare lo stato desiderato, eseguire il backup (stash), eseguire nuovamente il pull e applicare il backup (stash).
Vladimir Vukanac

1
mrW puoi ancora unire la base di codice che desideri su una base di codice ripristinata / estratta
emery

11

Prova a usare il -fflag e a metterlo dopo il nome del ramo remoto.

git push origin master -f


1
No, neanche quello ha funzionato. Ho anche provato git push -f origin mastere stesso risultato. Entrambe le volte che l'ho provato ho ricevuto la seconda versione del messaggio di errore.
samwell

2

Non ti è permesso fare git push che non sia fast-forward.

  1. Se il telecomando è GitHub, vai a https://github.com/$USER/$REPO/settings/branchese rimuovi la protezione dal ramo in questione.

    inserisci qui la descrizione dell'immagine

    Devi essere amministratore del repo per farlo.

  2. Se il telecomando è il tuo server git, esegui git config receive.denynonfastforwards falselì.


Tieni presente che per le istanze Git Hub Enterprise, i push al ramo predefinito (di solito "master") possono essere disabilitati a livello di istanza. Ciò significa che anche se "master" non è protetto, e anche se sei un amministratore del sito, non sarai in grado di eseguire push forzati al ramo predefinito. Supponendo che tu abbia i permessi, puoi aggirare temporaneamente questo problema cambiando il ramo predefinito in qualcos'altro, eseguendo il push forzato e quindi tornando indietro.
Christopher Hunter

2

Il modo migliore per aggirare questo è eliminare il ramo remoto e inviarlo nuovamente:

git push origin master --delete
git push origin master

0

Il problema si verifica poiché il ramo corrente non è configurato correttamente per il PULL . Per prima cosa controlla se il ramo a monte è configurato correttamente per il pull usando - git remote show origin. Lo si può trovare nella sezione - rami locali configurati per 'tirare git': . In caso contrario, configuralo utilizzando:

git config branch.MYBRANCH.merge refs/heads/MYBRANCH

Assegnare il nome del ramo appropriato per il segnaposto - MYBRANCH


0

Sto usando questo gruppo di comandi per ripristinare il mio repository remoto, questo reinizializzerà il repository locale e ricollegherà con il repository remoto, quindi forzerà il push degli aggiornamenti.

Penso che in questo modo non funzionerà nel tuo caso, ma potrebbe essere utile per qualcun altro

vai alla cartella di origine quindi esegui i comandi: nota che https://github.com/*.gitè il collegamento del repository remoto

git init
git remote add origin https://github.com/*.git
git add .
git commit -m "initial commit"
git push origin master -f
git push --set-upstream origin master

**Note: this will clear all your git history on your master branch**


0

Per me, il suggerimento di @svick puntava nella giusta direzione. Dato che il server git che volevo modificare è in realtà la mia macchina, ho effettuato l'accesso e ho git config --global receive.denynonfastforwards falsemodificato tutti i repository per accettare un push non-ff forzato. Non ha funzionato fuori dagli schemi. Quello che ho scoperto è che nella configurazione era già receive.denynonfastforwards=trueimpostato e non è stato possibile cancellarlo con git config --global --unset receive.denynonfastforwards. vi configTuttavia, la modifica manuale nel repository ( ) ha funzionato.


0

Ho risolto rimuovendo il ramo principale dalle regole del ramo protetto e anche predefinito che è appena sopra le regole del ramo protetto nell'impostazione di un repository.

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.