Як я магу націснуць выпраўленую фіксацыю на выдалены рэпазітар 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 31 каст. 2008-10-31 13:23 '08 у 13:23 2008-10-31 13:23
@ 13 адказаў

Я на самой справе аднойчы націснуў рэпазітар --force і .git і атрымаў лаянку ад Linus 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 студз. 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 нояб. адказ дадзены Charles Bailey 01 лістапада. 2008-11-01 00:58 '08 у 0:58 2008-11-01 00:58

Хуткі размовы: той факт, што ніхто не апублікаваў просты адказ, дэманструе адчайную варожасць карыстальніка, праяўленую з дапамогай Git CLI.

У любым выпадку, "відавочны" спосаб зрабіць гэта, мяркуючы, што вы не спрабавалі прымусіць штуршок, - гэта выцягнуць першым. Гэта прывядзе да змены, якое вы ўнеслі ў яго (і, такім чынам, яго больш няма), каб ён зноў з'явіўся.

Як толькі вы дазволіце якія-небудзь канфлікты, вы можаце націснуць яшчэ раз.

Такім чынам:

 git pull 

Калі вы атрымліваеце памылкі ў pull, магчыма, нешта не так у вашай канфігурацыі лакальнага рэпазітара (у мяне быў няправільны ref ў раздзеле .git / config).

І пасля

 git push 

Магчыма, вы атрымаеце дадатковую фіксацыю з прадметам, якія распавядаюць аб "Trivial merge".

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 

Вядучы знак + прымусіць націснуць, нават калі гэта не прывядзе да фіксацыі "хуткай перамоткі наперад". (Хуткая пераадрасацыя адбываецца, калі змены, якія вы націскаеце, з'яўляюцца прамым нашчадкам змяненняў, якiя ўжо знаходзяцца ў публічным РЭПО.)

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 

Што робіць наступнае:

  • Reset адгалінаванне галінкі галоўкі на бацькоўскі.
  • Націсніце апошняе комм.
  • Прымусовае націск на пульце дыстанцыйнага кіравання. Цяпер выдалены кампутар не мае апошняга фіксацыі.
  • Трапіць у свой кашалёк.
  • Чытай чыста.
  • Націсніце на пульце дыстанцыйнага кіравання.

Не забудзьцеся змяніць "origin" і "master", калі ўжыць гэта да іншай галінцы або выдаленага прыладзе.

20
21 июня '15 в 17:41 2015-06-21 17:41 адказ дадзены Faiza 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 у 18: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 changes # 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 commit замест 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: May discard" і праверка "вядомых змен".

Force (можа адхіліць вядомыя змены) дазваляе выдаленага рэпазітара прымаць больш бяспечны, ня хуткі пераход. Гэта можа прывесці да таго, што аддалены рэпазітар страціць фіксацыі; выкарыстоўвайце яго з асцярогай. Гэта можа перашкодзіць страціць невядомыя змены ад іншых людзей на пульце дыстанцыйнага кіравання. Ён правярае, паказвае Ці галіна сервера на тую ж фіксацыю, што і галіна аддаленага адсочвання (вядомыя змены). Калі так, то будзе націснутая сіла. У адваротным выпадку ён будзе адхілены. Паколькі git не мае тэгаў з выдаленым адсочваннем, тэгі не могуць быць перазапісаны з дапамогай гэтай опцыі.

3
07 июня '16 в 3:03 2016-06-07 03:03 адказ дадзены ShawnFeatherly 07 чэрвеня '16 у 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 янв. адказ дадзены Marwen Bkh 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? 

Важнае заўвага:. Калі вы карыстаецеся прымусовае націск, вы можаце сутыкнуцца з праблемамі кода, якія іншыя распрацоўшчыкі працуюць над адной галіной. Таму, каб пазбегнуць гэтых канфліктаў, вам трэба выцягнуць код з сваёй галіны, перш чым націскаць force:

  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 remote ўжо ёсць гэтыя файлы фіксацыі. Вы павінны прымусова націснуць на галінку, каб гэта працавала:

 git push -f origin branch_name 

Таксама пераканайцеся, што вы выцягвае код з аддаленага, так як хто-небудзь з вашай каманды мог перамясціцца ў адну галіну.

 git pull origin branch_name 

Гэта адзін з выпадкаў, калі нам трэба прымусова націснуць фіксацыю на выдалены.

1
21 янв. адказ дадзены Praveen Dhawan 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

Я проста працягваў рабіць тое, што сказаў мне Git. Такім чынам:

  • Немагчыма націснуць з-за выпраўлення.
  • Я раблю спробу, як меркавалася.
  • Памылка зліцця. таму я выпраўляю яго ўручную.
  • Стварыце новую фіксацыю (пазначаную "merge") і націсніце яго.
  • Здаецца, што гэта працуе!

Заўвага. Змененая фіксацыя была апошняй.

1
02 дек. адказ дадзены Rolf 02 снеж. 2016-12-02 19:29 '16 у 19:29 2016/12/02 19:29

Іншыя пытанні па пазнаках або Задайце пытанне