Domanda

Quando ho lavorato un po 'con il mio codice sorgente, ho fatto il mio solito impegno e poi ho spinto in un repository remoto. Ma poi ho notato che ho dimenticato di organizzare le mie importazioni nel codice sorgente. Quindi eseguo il comando di modifica per sostituire il commit precedente:

> git commit --amend

Sfortunatamente il commit non può essere rinviato al repository. Viene rifiutato in questo modo:

> git push origin
To //my.remote.repo.com/stuff.git/
 ! [rejected]        master -> master (non-fast forward)
error: failed to push some refs to '//my.remote.repo.com/stuff.git/'

Cosa devo fare? (Posso accedere al repository remoto.)

È stato utile?

Soluzione

In realtà una volta ho spinto con --force e .git repository e sono stato sgridato da Linus BIG TIME . In generale, ciò creerà molti problemi per altre persone. Una semplice risposta è & Quot; Non farlo & Quot ;.

Vedo che gli altri hanno dato la ricetta per farlo comunque, quindi non li ripeterò qui. Ma ecco un suggerimento per riprendersi dalla situazione dopo che hai eliminato il commit modificato con --force (o + master).

  1. Usa git reflog per trovare il vecchio commit che hai modificato (chiamalo old e chiameremo il nuovo commit che hai creato modificando new).
  2. Crea un'unione tra git checkout new && git merge -s ours old e git merge master, registrando l'albero di git push . HEAD:master, come <=>.
  3. Uniscilo al tuo master con <=>
  4. Aggiorna il tuo master con il risultato con <=>
  5. Sposta il risultato.

Quindi le persone che sono state abbastanza sfortunate da aver basato il loro lavoro sull'impegno che hai annullato modificando e forzando una spinta vedranno che la fusione risultante vedrà che preferisci <=> rispetto a <=>. Le loro successive fusioni non vedranno i conflitti tra <=> e <=> risultanti dalla tua modifica, quindi non devono soffrire.

Altri suggerimenti

Stai vedendo una funzione di sicurezza Git. Git rifiuta di aggiornare il ramo remoto con il tuo ramo, perché il commit capo del tuo ramo non è un diretto discendente dell'attuale head commit del ramo che stai spingendo.

Se così non fosse, allora due persone che spingono nello stesso repository nello stesso momento non saprebbero che ci sarebbe stato un nuovo commit in arrivo nello stesso momento e chiunque avesse spinto per ultimo avrebbe perso il lavoro dello spingitore precedente senza che nessuno di loro se ne accorga.

Se sai che sei l'unica persona che spinge e vuoi spingere un commit modificato o spingere un commit che riavvolge il ramo, puoi 'forzare' Git ad aggiornare il ramo remoto usando l'opzione -f.

git push -f origin master

Anche questo potrebbe non funzionare poiché Git consente ai repository remoti di rifiutare spinte non veloci dall'altra parte usando la variabile di configurazione receive.denynonfastforwards. In tal caso, il motivo del rifiuto sarà simile al seguente (notare la parte "rifiutata a distanza"):

 ! [remote rejected] master -> master (non-fast forward)

Per ovviare a questo, è necessario modificare la configurazione del repository remoto o come hack sporco è possibile eliminare e ricreare il ramo in questo modo:

git push origin :master
git push origin master

In generale l'ultimo parametro su git push utilizza il formato <local_ref>:<remote_ref>, dove local_ref è il nome del ramo sul repository locale e remote_ref è il nome del ramo sul repository remoto. Questa coppia di comandi utilizza due shorthands. :master ha un valore local_ref nullo, il che significa che spinge un ramo null sul lato remoto master, ovvero elimina il ramo remoto. Un nome di filiale senza : indica che il ramo locale con il nome specificato viene inviato al ramo remoto con lo stesso nome. master:master in questa situazione è l'abbreviazione di <=>.

Quick rant: il fatto che nessuno abbia pubblicato qui la semplice risposta dimostra l'ostilità disperata dell'utente mostrata dalla CLI di Git.

Comunque, " ovvio " Il modo per farlo, supponendo che tu non abbia provato a forzare la spinta, è quello di tirare per primo. Ciò estrae la modifica che hai modificato (e quindi non è più presente) in modo da averla nuovamente.

Dopo aver risolto eventuali conflitti, puoi spingere di nuovo.

git pull

Se ricevi errori in pull, forse qualcosa non va nella configurazione del tuo repository locale (ho avuto un riferimento sbagliato nella sezione del ramo .git / config).

E dopo

git push

Forse otterrai un ulteriore impegno con il soggetto che parla di un " Unione trivial " ;.

Risposta breve: non inviare commit modificati in un repository pubblico.

Risposta lunga: alcuni comandi Git, come git commit --amend e git rebase, in realtà riscrivono il grafico cronologico. Questo va bene fino a quando non hai pubblicato le modifiche, ma una volta fatto, non dovresti davvero andare in giro con la cronologia, perché se qualcuno ha già le tue modifiche, quindi quando provano a tirare di nuovo, potrebbe fallire . Invece di modificare un commit, dovresti semplicemente effettuare un nuovo commit con le modifiche.

Tuttavia, se vuoi davvero fare un commit modificato, puoi farlo in questo modo:

$ git push origin +master:master

Il segno + iniziale forzerà la spinta, anche se non si traduce in un " avanzamento veloce " commettere. (Un commit ad avanzamento rapido si verifica quando le modifiche che stai spingendo sono un discendente diretto delle modifiche già presenti nel repository pubblico.)

Ecco un modo molto semplice e pulito per inviare le modifiche dopo aver effettuato un commit --amend:

git reset --soft HEAD^
git stash
git push -f origin master
git stash pop
git commit -a
git push origin master

Che fa quanto segue:

  • Ripristina head branch su commit parent.
  • Blocca questo ultimo commit.
  • Forza la spinta al telecomando. Il telecomando ora non ha l'ultimo commit.
  • Pop la tua scorta.
  • Impegnati in modo pulito.
  • Premi sul telecomando.

Ricorda di cambiare " origin " e " master " se lo si applica a un altro ramo o telecomando.

L'ho risolto scartando il mio commit modificato locale e aggiungendo le nuove modifiche in cima:

# Rewind to commit before conflicting
git reset --soft HEAD~1

# Pull the remote version
git pull

# Add the new commit on top
git add ...
git commit
git push

Ho avuto lo stesso problema.

  • Modifica accidentale dell'ultimo commit che era già stato inviato
  • Sono state apportate molte modifiche a livello locale, eseguite circa cinque volte
  • Ho provato a spingere, ho ricevuto un errore, sono andato nel panico, hanno unito il telecomando, ho ricevuto molti file non personali, ho spinto, fallito, ecc.

Come novizio di Git, ho pensato che fosse completo FUBAR .

Soluzione: in qualche modo come @bara ha suggerito + creato un ramo di backup locale

# Rewind to commit just before the pushed-and-amended one.
# Replace <hash> with the needed hash.
# --soft means: leave all the changes there, so nothing is lost.
git reset --soft <hash>

# Create new branch, just for a backup, still having all changes in it.
# The branch was feature/1234, new one - feature/1234-gone-bad
git checkout -b feature/1234-gone-bad

# Commit all the changes (all the mess) not to lose it & not to carry around
git commit -a -m "feature/1234 backup"

# Switch back to the original branch
git checkout feature/1234

# Pull the from remote (named 'origin'), thus 'repairing' our main problem
git pull origin/feature/1234

# Now you have a clean-and-non-diverged branch and a backup of the local changes.
# Check the needed files from the backup branch
git checkout feature/1234-gone-bad -- the/path/to/file.php

Forse non è una soluzione rapida e pulita e ho perso la mia cronologia (1 commit invece di 5), ma ha salvato un giorno di lavoro.

Se non hai inviato il codice al tuo ramo remoto (GitHub / Bitbucket) puoi modificare il messaggio di commit sulla riga di comando come di seguito.

 git commit --amend -m "Your new message"

Se stai lavorando su un ramo specifico, fai questo:

git commit --amend -m "BRANCH-NAME: new message"

Se hai già inviato il codice con un messaggio sbagliato, devi fare attenzione quando cambi il messaggio. cioè dopo aver modificato il messaggio di commit e provare a spingerlo di nuovo, si verificano problemi. Per renderlo uniforme, seguire i seguenti passaggi.

Si prega di leggere l'intera risposta prima di farlo

git commit --amend -m "BRANCH-NAME : your new message"

git push -f origin BRANCH-NAME                # Not a best practice. Read below why?

Nota importante: quando si utilizza la forza forzata direttamente si potrebbero riscontrare problemi di codice con cui altri sviluppatori stanno lavorando sullo stesso ramo. Quindi, per evitare quei conflitti, devi estrarre il codice dalla tua filiale prima di effettuare la forzatura push :

 git commit --amend -m "BRANCH-NAME : your new message"
 git pull origin BRANCH-NAME
 git push -f origin BRANCH-NAME

Questa è la migliore pratica quando si modifica il messaggio di commit, se è stato già inviato.

Se sai che nessuno ha eseguito il commit non modificato, utilizza l'opzione --force-with-lease di git push.

In TortoiseGit, puoi fare la stessa cosa in " Push ... " opzioni " Force: può scartare " e selezionando " modifiche note " ;.

  

Force (può scartare le modifiche note) consente il repository remoto accettare una spinta più sicura e non veloce. Ciò può causare la perdita di commit del repository remoto; usalo con cura. Ciò può impedire di perdere modifiche sconosciute da altre persone sul telecomando. Verifica se il ramo del server punta allo stesso commit del ramo di tracciamento remoto (modifiche note). Se sì, verrà eseguita una spinta forzata. Altrimenti verrà rifiutato. Poiché git non ha tag di tracciamento remoto, i tag non possono essere sovrascritti usando questa opzione.

Ecco un modo molto semplice e chiaro per inviare le modifiche dopo aver effettuato git add "your files" e git commit --amend:

git push origin master -f

o

git push origin master --force

Questo errore viene visualizzato perché il telecomando Git ha già questi file di commit. Devi forzare a spingere il ramo affinché questo funzioni:

git push -f origin branch_name

Assicurati anche di estrarre il codice dal telecomando poiché qualcun altro nel tuo team potrebbe aver spinto nello stesso ramo.

git pull origin branch_name

Questo è uno dei casi in cui dobbiamo forzare il push del commit su remoto.

Ho dovuto risolvere questo problema estraendo dal repository remoto e gestendo i conflitti di unione che sono sorti, impegnati e quindi inviati. Ma sento che esiste un modo migliore.

Ho continuato a fare ciò che Git mi ha detto di fare. Quindi:

  • Impossibile eseguire il push a causa del commit modificato.
  • Faccio un tiro come suggerito.
  • L'unione ha esito negativo. quindi lo aggiusto manualmente.
  • Crea un nuovo commit (etichettato " unisci ") e spingilo.
  • Sembra funzionare!

Nota: il commit modificato è stato l'ultimo.

Ecco, come ho corretto una modifica in un precedente commit:

  1. Salva il tuo lavoro finora.
  2. Metti da parte le modifiche per ora, se apportate: git stash Ora la tua copia di lavoro è pulita allo stato del tuo ultimo commit.
  3. Apporta le modifiche e le correzioni.
  4. Conferma le modifiche in " modifica " modalità: git commit --all --amend
  5. Il tuo editor verrà richiesto per un messaggio di registro (per impostazione predefinita, il vecchio messaggio di registro). Salva ed esci dall'editor quando ne sei soddisfatto.

    Le nuove modifiche vengono aggiunte al vecchio commit. Guarda tu stesso con git log e git diff HEAD^

  6. Riapplica le modifiche nascoste, se apportate: git stash apply

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top