Cum fac în mod corespunzător forța un Git push?

Am'am înființat-o la distanță non-goale "principal" repo și l-a clonat pe calculatorul meu. Mi-am făcut niște modificări locale, actualizată mea depozit local, și a împins modificările înapoi la telecomanda mea repo. Lucrurile au mers bine până în acel moment.

Acum, am avut de a schimba ceva în repo la distanță. Apoi am schimbat ceva în repo locală. Mi-am dat seama că schimbarea de la distanță repo nu a fost nevoie. Așa că am încercat să git push din repo locală a mea de la distanță repo, dar am primit o eroare de genul:

Pentru a preveni pierderea de istorie, non-fast-forward actualizări au fost a respins Merge telecomanda modificări înainte de a împinge din nou. Vezi 'Notă despre fast-forward' secțiunea de git push --help pentru detalii.

M-am gândit că, probabil, o

git push --force

ar forța mea copie locală a împinge modificări la distanță una și aceeași. Nu forța actualizarea, dar când mă întorc de la distanță repo și de a face un comis-o, am observat că fișierele conțin depășite modificări (cele care principala de la distanță repo avut anterior).

După cum am menționat în comentarii la una dintre answers:

[I] a încercat forțarea, dar atunci când merge înapoi la serverul master pentru a salva modificările, am depășit de intermediere. Astfel, atunci când am comis centrale de tranzacții nu sunt la fel. Și când m-am încercați să utilizați git push din nou, primesc aceeasi eroare.

Cum pot rezolva această problemă?

Comentarii la întrebare (5)
Soluția

Doar să faceți:

git push origin  --force

sau, dacă aveți un anumit repo:

git push https://git.... --force

Acest lucru va șterge comiterea precedentă(s) și împingeți-un curent.

Acesta nu poate fi corectă, dar dacă cineva se împiedică pe aceasta pagina, gândit ca ar vrea o soluție simplă...

Scurt pavilion

De asemenea, rețineți că -f este prescurtarea de la --force, deci

git push origin  -f

va lucra, de asemenea.

Comentarii (12)

Și dacă push --force nu't locul de muncă, puteți face push --delete. Uita-te la 2nd linie la acest exemplu:

git reset --hard HEAD~3  # reset current branch to 3 commits ago
git push origin master --delete  # do a very very bad bad thing
git push origin master  # regular push

Dar feriți-vă...

Niciodată să nu te întorci pe un public git istorie!

Cu alte cuvinte:

  • Don't vreodată forță împinge pe un registru public.
  • Don't face acest lucru sau orice altceva care poate rupe cineva's "pull".
  • Don't vreodată "reset" sau `rescrie istoria într-un repo cineva ar fi tras deja.

Desigur, sunt extrem de rare excepții, chiar și de la această regulă, dar în cele mai multe cazuri's nu este nevoie pentru a face și va genera probleme pentru toată lumea.

Fac o revenire în loc.

Și să fie mereu atent cu ce te împinge să o publice repo. Revenirea:

git revert -n HEAD~3..HEAD  # prepare a new commit reverting last 3 commits
git commit -m "sorry - revert last 3 commits because I was not careful"
git push origin master  # regular push

În efect, ambele Capete de origine (de la revin si de răul de resetare) va conține aceleași fișiere.


de editare pentru a adăuga informații actualizate și mai multe argumente în jurul împinge-force

Ia în considerare forța de împingere cu contract de leasing în loc de a împinge, dar încă preferă reveni

O altă problemă push --force poate aduce este atunci când cineva împinge nimic înainte de a face, dar după te'am deja preluat. Dacă forța de apăsare ta indexat versiune acum va înlocuiți de lucru de la alții.

git push --force-cu-leasing a introdus în git 1.8.5 (datorită @VonC comentariu la întrebarea) încearcă să abordeze această problemă specifică. Practic, aceasta va aduce o eroare și nu împinge dacă telecomanda a fost modificat de la ultima ta aduce.

Acest lucru este bun daca're într-adevăr sigur că o împinge --forceeste necesar, dar încă mai doresc pentru a preveni mai multe probleme. Am'd merge atât de departe să spun că ar trebui să fie implicitîmpinge-forța comportamentului. Dar's încă departe de a fi o scuză pentru a forța un "push". Oamenii care preluat înainte rebazare va avea încă o mulțime de probleme, care ar putea fi evitate cu ușurință dacă ați avut revenit loc.

Și când ne-am're vorbesc despre git --push cazuri...

De ce ar vrea cineva să-forța de împingere?

@linquize - a adus o bună forță de apăsare exemplu pe comentarii: date sensibile. Te'am greșit scurgeri de date care ar trebui't fi împins. Daca're destul de repede, ai "repara"* forțând-o apăsare pe partea de sus.

* La date va fi în continuare pe partea de la distanță, cu excepția cazului te face, de asemenea, un gunoi colecta, sau - l curat cumva. Există, de asemenea, evident potențialul de a se răspândi cu alții care'd preluat o deja, dar ai prins ideea.

Comentarii (10)

Mai întâi de toate, nu aș face orice modificări direct în "principal" repo. Dacă doriți cu adevărat să aibă un "principal" repo, atunci ar trebui să apăsați doar să-l, nu-l schimba direct.

În ceea ce privește eroare pe care le primiți, ai încercat git pull din local repo, și apoi git push la principalele repo? Ce se face în prezent (dacă am înțeles eu bine) este forțând împinge și apoi pierde modificările în "principal" repo. Tu ar trebui să îmbinați modificările la nivel local în primul rând.

Comentarii (4)

Dacă am'm pe filiala locală A, și vreau să-forța de împingere filiala locală B la origine sucursala C I poate folosi următoarea sintaxă:

git push --force origin B:C
Comentarii (1)

Mi-ar foarte recomanda pentru:

  • împinge doar la principalele repo

  • asigurați-vă că principalul repo este un goale repo, în scopul de a nu avea nici o problema cu principalele repo de lucru pom a nu fi în sincronizare cu ei.git` de bază. A se vedea "Cum pentru a împinge un local git repository-ul la un alt calculator?"

  • Dacă aveți de a face modificarea în principal (goale) repo, clona (pe serverul principal), faci modificarea și împinge înapoi de la ea

Cu alte cuvinte, ține un gol repo accesibil atât de pe serverul principal și computerul local, în scopul de a avea un singur amonte repo de la/la care pentru a trage/scoate.

Comentarii (1)

utilizați această următoarea comandă:

git push -f origin master
Comentarii (3)

Aceasta a fost soluția noastră pentru înlocuirea master pe un corporate depozit gitHub menținând în același timp istorie.

push-f să stăpânească pe corporative depozite este de multe ori cu handicap pentru a menține ramură istorie. Această soluție a lucrat pentru noi.

git fetch desiredOrigin
git checkout -b master desiredOrigin/master // get origin master
git checkout currentBranch  // move to target branch
git merge -s ours master  // merge using ours over master
// vim will open for the commit message
git checkout master  // move to master
git merge currentBranch  // merge resolved changes into master

împinge ramură a desiredOrigin și de a crea un PR

Comentarii (0)

Am avut aceeași întrebare, dar și-a dat seama în cele din urmă. Ceea ce cel mai probabil trebuie să faceți este să rulați următoarele două git comenzi (înlocuirea hash cu git commit numărul de revizie):

git checkout <hash> git push-f CAP:master

Comentarii (0)