Как мога да натисна фиксиран ангажимент към отдалечено хранилище на Git?

Когато направих някаква работа по изходния код, направих обичайното си нещо и после щракнах върху отдалеченото хранилище. Но тогава забелязах, че забравих да организирам вноса в изходния код. Затова правя команда за промяна, която да замени предишния ангажимент:

 > git commit --amend 

За съжаление фиксирането не може да бъде върнато в хранилището. Той се отхвърля, както следва:

 > 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/' 

Какво трябва да направя? (Мога да вляза в отдалеченото хранилище.)

475
31 окт. Spoike set 31 октомври 2008-10-31 13:23 '08 в 1:23 pm 2008-10-31 13:23
@ 13 отговора

Всъщност веднъж щракнах на хранилището --force и .git и получих проклятие от Линус BIG TIME . Като цяло, това ще създаде много проблеми за други хора. Простият отговор е: "Не правете това."

Виждам, че другите дават рецепта за това, така че няма да ги повтарям тук. Но ето намек за възстановяване от ситуацията, след като сте натиснали коригираната фиксация с --force (или + master).

  • Намерете стария ангажимент, който сте допринесли за него (наречете го old , и ние ще изберем новата команда, която сте създали, като промените new ).
  • Създайте сливане между old и new като напишете new дърво, например git checkout new git merge -s ours old .
  • Комбинирайте това с вашия майстор, използвайки git merge master
  • Актуализирайте своя съветник с резултат git push . HEAD:master git push . HEAD:master
  • Отпечатайте резултата.

Тогава хората, които не са били достатъчно успешни, за да базират работата си върху фиксацията, която сте унищожили, коригирали и принудили тласкането (което сте много лошо момче ), ще видите резултата от сливането и ще видите, че използвате new над old . Следващите им сливания няма да видят конфликтите между old и new , които са възникнали в резултат на промените, така че не е необходимо да страдат.

371
11 янв. отговорът е даден от gitster 11 jan. 2009-01-11 10:36 '09 в 10:36 ч. 2009-01-11 10:36

Ще видите функцията за защита Git. Git отказва да обнови отдалечен клон на клон, защото заглавният ви клон не е директен потомък на текущото фиксиране на заглавието на клона, върху който кликнете.

Ако случаят не беше такъв, тогава двама души, които бяха притискали едно и също хранилище по едно и също време, нямаше да знаят, че едно и също време е станало ново завещание, а този, който натисна последния, би загубил работата си. предишен тласкач, без никой от тях да е наясно с това.

Ако знаете, че сте единственият човек, който е натиснал, и искате да натиснете фиксираното решение или натиснете корекцията, която налага вето на клона, можете да "принудите" Git да актуализира отдалечения клон с ключа -f .

 git push -f origin master 

Дори това може да не работи, тъй като Git позволява на отдалечените хранилища да се откажат от бързите кликвания в далечния край, като използват конфигурационната receive.denynonfastforwards . Ако случаят е такъв, причината за отхвърлянето ще изглежда така (обърнете внимание на частта „отдалечен отказ“):

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

За да заобиколите това, трябва или да промените конфигурацията на отдалеченото хранилище, или като мръсен хак, можете да изтриете и пресъздадете клона по следния начин:

 git push origin :master git push origin master 

Като цяло, последният параметър на git push използва формата <local_ref>:<remote_ref> , където local_ref е името на клона в локалното хранилище, а remote_ref е името на клона в отдалеченото хранилище. Тази двойка команди използва две съкращения. :master е null local_ref, което означава налагане на нулев клон на отдалечената страна на master , т.е. изтриването на отдалечен клон. Име на клон без : означава, че локалният клон с посоченото име се пренасочва към отдалечения клон със същото име. master в тази ситуация е кратък за master:master .

218
01 нояб. Отговор, даден от Чарлз Бейли 01 ноември. 2008-11-01 00:58 '08 в 0:58 ч. 2008-11-01 00:58

Бърз раздразнение: фактът, че никой не е написал прост отговор, показва отчаяната враждебност на потребителя, проявена с Git CLI.

Във всеки случай, "очевидният" начин да се направи това, ако приемем, че не сте се опитали да наложите натиск, е първо да го извадите. Това ще доведе до промяната, която сте й направили (и следователно вече не е там), така че да се появи отново.

Веднага щом разрешите конфликти, можете да кликнете отново.

Така че:

 git pull 

Ако получите грешки, може би нещо не е наред с локалната конфигурация на хранилището (имах невалиден реф. В секцията .git / config).

И след това

 git push 

Може да получите допълнителна фиксация с предмета на „Тривиалното сливане“.

184
22 сент. отговор, даден от Tim Band 22 септември 2009-09-22 13:46 '09 в 13:46 2009-09-22 13:46

Краткият отговор е: не натискайте коригираните фиксирания в публичното репо.

Дългият отговор: няколко Git команди, като git commit --amend и git rebase , всъщност пренаписват историята. Това е добре, докато не публикувате промените си, но след като го направите, наистина не трябва да бъдете заблуждавани от историята, защото ако някой вече е получил промените ви, когато се опитват да ги извадят отново, вместо да правят промени При поемане трябва да направите нов ангажимент с промени.

Ако обаче наистина искате да натиснете коригирано съобщение, можете да го направите по следния начин:

 $ git push origin +master:master 

Водещият знак + ще ви принуди да натиснете, дори ако това не доведе до фиксиране на „бързо напред“. (Бързото препращане се случва, когато промените, които кликнете върху, са пряк потомък на промените, които вече са в публичното репо.)

86
31 окт. отговорът е даден от mipadi на 31 октомври 2008-10-31 17:35 '08 в 17:35 2008-10-31 17:35

Ето един лесен и чист начин да направите промените си, след като сте направили commit --amend :

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

Какво прави следното:

  • Нулиране на клоновете клонове към родителя.
  • Кликнете върху последния ангажимент.
  • Принудително натискане на дистанционното управление. Сега отдалеченият компютър не разполага с последното фиксиране.
  • Влез в портфейла си.
  • Прочетете чисто.
  • Кликнете върху дистанционното управление.

Не забравяйте да промените "начало" и "капитан", ако приложите това към друг клон или отдалечено устройство.

20
21 июня '15 в 17:41 2015-06-21 17:41 отговорът е даден Фаиза 21 юни '15 в 17:41 2015-06-21 17:41

Реших това, като отхвърлихме локалното поправка и добавихме нови промени от горната част:

 # 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 
16
24 сент. Отговорът е даден bara септември 24 2012-09-24 18:46 '12 в 6:46 ч. 2012-09-24 18:46

Имах същия проблем.

  • Последното прикрепване, което вече е било натиснато, бе нагласено на случаен принцип.
  • Много промени направени на местно ниво, направени пет пъти
  • Опитах се да кликнете, да получите грешка, да се паникьосвате, да обедините отдалечен достъп, да получите много от не-моите файлове, да сте кликнали, да се провали и т.н.

Като git -newbie, мислех, че е завършен от FUBAR .

Решението. Малко по различен начин, тъй като @bara предложи + създаване на локален бекъп

 # 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 

Може би това не е бързо и чисто решение, а аз загубих историята си (1 заем вместо 5), но той запази дневната си работа.

7
20 февр. Отговорът е даден davisca 20 февруари. 2014-02-20 13:24 '14 в 13:24 2014-02-20 13:24

Ако знаете, че никой не е извадил вашата корекция без промяна, използвайте опцията --force-with-lease git push .

В TortoiseGit можете да направите същото в настройките "Push ..." "Force: Може да отхвърлите" и да проверите за "известни промени".

Force (може да отхвърли известни промени) позволява на отдалеченото хранилище да предприеме по-безопасен, не бърз преход. Това може да доведе до загуба на отдалеченото хранилище; използвайте го с повишено внимание. Това може да ви попречи да загубите неизвестни промени от други хора на дистанционното управление. Той проверява дали клонът на сървъра сочи същата фиксация като клона за отдалечено проследяване (известни промени). Ако е така, захранването ще бъде натиснато. В противен случай тя ще бъде отхвърлена. Тъй като git няма маркери с дистанционно проследяване, маркерите не могат да бъдат презаписани с тази опция.

3
07 июня '16 в 3:03 2016-06-07 03:03 отговорът е даден от ShawnFeatherly на 07.06.2011 в 3:03 2016-06-07 03:03

Ето един лесен и чист начин да направите промени, след като сте направили git add "your files" и git commit --amend :

 git push origin master -f 

или

 git push origin master --force 
2
18 янв. Отговорът е даден от Марвен Бх 18 януари. 2016-01-18 11:29 '16 в 11:29 2016-01-18 11:29

Ако не сте натиснали кода на отдалечения клон (GitHub / Bitbucket), можете да промените съобщението за предаване в командния ред, както е показано по-долу.

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

Ако работите върху определен клон, направете следното:

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

Ако вече сте кликнали върху кода с грешно съобщение, трябва да внимавате, когато променяте съобщението. след като промените съобщението за поемане и опитайте да го натиснете отново, имате проблеми. За да стане гладка, изпълнете следните стъпки.

Моля, прочетете целия отговор, преди да го направите.

 git commit --amend -m "BRANCH-NAME : your new message" git push -f origin BRANCH-NAME # Not a best practice. Read below why? 

Важна забележка:. Когато натиснете бутон, може да срещнете проблеми с кода, върху които работят други разработчици на същия клон. Затова, за да избегнете тези конфликти, трябва да извадите кода от вашия клон, преди да натиснете сила :

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

Това е най-добрата практика при смяна на съобщение за предаване, ако вече е било натиснато.

2
13 янв. Отговор е даден от Packer 13 януари 2015-01-13 10:20 '15 в 10:20 2015-01-13 10:20

Получавате тази грешка, защото Git дистанционното вече има тези файлове. Трябва да кликнете насилствено върху клон, за да работи това:

 git push -f origin branch_name 

Също така се уверете, че изваждате кода от дистанционното управление, тъй като някой от екипа ви може да се премести в един клон.

 git pull origin branch_name 

Това е един от случаите, когато трябва да наложим фиксиране на отдалечено.

1
21 янв. отговорът е даден от Praveen Dhawan Jan 21 2016-01-21 09:35 '16 в 9:35 2016-01-21 09:35

Трябваше да реша този проблем, като издърпах от отдалечено репо и сортирахме конфликтите за сливане, които се появиха, поправихме и щракнахме. Но чувствам, че има по-добър начин.

1
31 окт. отговорът е даден Spoike 31 октомври. 2008-10-31 14:39 '08 в 14:39 ч. 2008-10-31 14:39

Просто продължих да правя това, което ми каза Гит. Така че:

  • Не може да се кликне поради поправка.
  • Опитвам се, както очаквах.
  • Обединяване на грешка така че го поправям ръчно.
  • Създайте нов ангажимент (маркиран като "сливане") и кликнете върху него.
  • Изглежда, че работи!

Забележка. Модифицираната фиксация беше последната.

1
02 дек. Отговорът е даден Rolf 02 Dec. 2016-12-02 19:29 '16 в 19:29 2016-12-02 19:29

Други въпроси относно или задават въпрос