Як правильно натиснути натискання Git?


1272

Я встановив віддалений не голий "основний" репо і клонував його до свого комп'ютера. Я вніс декілька локальних змін, оновив своє місцеве сховище та перемістив зміни назад до віддаленого репорту. До цього моменту все було добре.

Тепер мені довелося щось змінити у віддаленому репо. Потім я щось змінив у своєму місцевому репо. Я зрозумів, що зміни на віддалений репо не потрібні. Тож я спробував перейти git pushз місцевого репо до мого віддаленого репо, але у мене виникла помилка на зразок:

Щоб не втратити історію, відхилені нешвидкісні оновлення назад Об’єднайте віддалені зміни, перш ніж натиснути знову. git push --helpДеталі див. У розділі "Примітка про швидку перемотку" .

Я думав, що, ймовірно, a

git push --force

змусить мою локальну копію натиснути зміни на віддалений і зробити їх такими ж. Це примушує оновлення , але коли я повертаюся до віддаленого репо і приймаю зобов’язання, я помічаю, що файли містять застарілі зміни (ті, які раніше мали головне віддалене репо).

Як я вже згадував у коментарях до однієї з відповідей :

[Я] спробував примусити, але, повертаючись на головний сервер, щоб зберегти зміни, я отримую застарілі постановки. Таким чином, коли я здійснюю сховища, то схожі. І коли я знову намагаюся використовувати git push, я отримую ту ж помилку.

Як я можу виправити це питання?


4
Ви незабаром (git1.8.5, Q4 2013) зможете зробити git push -forceбільш ретельно .
VonC


6
Як я детально розповідаю у своїй власній відповіді , git push --forceце дійсно ще один вірний спосіб примусити натиснути, і він буде натискати гілки так само, як git push origin master --forceі за замовчуванням Git push.default config settings, хоча які гілки спеціально натиснуті відрізняються між версіями Git до 2.0 проти 2.0.

2
git push --forceпрацює чудово в ці дні, FWIW ...
rogerdpack

git push --force-with-leaseпрацює навіть краще :), він відмовиться оновлювати філію, якщо це не такий стан, якого ви очікуєте. (див. developer.atlassian.com/blog/2015/04/force-with-lease )
spoorcc

Відповіді:


2305

Просто зробіть:

git push origin <your_branch_name> --force

або якщо у вас є конкретне репо:

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

Це видалить ваші попередні зобов'язання та підштовхне ваше поточне.

Це може бути не правильно, але якщо хтось натрапить на цю сторінку, подумав, що може захотіти простого рішення ...

Короткий прапор

Також зауважте, що -fце коротко --force, тому

git push origin <your_branch_name> -f

також буде працювати.


58
Ви можете використовувати git push origin +masterнатомість, які дозволяють натиснути кілька рефлексив, не примушуючи їх усіх.
nickgrim

5
Будьте в курсі, що, якщо ви випадково зробите це просто git push --force, ви можете в кінцевому рахунку зіпсувати вас майстер гілки (залежно від вашої поведінки за замовчуванням) .. Що може смоктати .. трохи ..: D
Jeewes

9
@Jeewes, починаючи з версії Git 2.0, поведінка за замовчуванням в git push --forceосновному полягає в тому, щоб змусити натиснути гілку, яку ви перевірили в даний момент, на її віддалену частину, так що якщо ви перевірили головну гілку, то вона ідентична git push origin master --force. Це буде інакше, якщо ви використовуєте matchingналаштування для push.default, яке є типовим для версій Git до 2.0. matchingпідштовхує всі гілки місцевих жителів до віддалених, що мають однакову назву, тому примусовий натискання тоді напевно може бути не тим, що ви хочете робити ...

@Jeewes Але з Git 2.0 за замовчуванням безпечніше, або принаймні це не небезпечніше, ніж git push origin master --forceє.

2
push -f - це добре, але не рекомендується для майстра, оскільки у більшості корпоративних репозиторіїв -f вимкнено для master. тоmerge -s oursпрацював для мене
Mihai

247

І якщо push --forceце не працює, ви можете зробити push --delete. Подивіться на 2 - й лінії на цьому прикладі:

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

Але будьте обережні ...

Ніколи не повертайтеся до публічної історії git!

Іншими словами:

  • Ніколи не forceнатискайте на загальнодоступне сховище.
  • Не робіть цього чи нічого, що може зламати когось pull.
  • Ніколи reset або rewriteісторія в репо хто - то , можливо, вже тягнув.

Звичайно, є виключно рідкісні винятки навіть із цього правила, але в більшості випадків цього не потрібно, і це створюватиме проблеми всім іншим.

Зробіть замість цього відновлення.

І завжди будьте уважні до того, що ви підштовхуєте до публічного репо . Повернення:

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

По суті, обидва джерела головки (від повернення та злого скидання) ) будуть містити однакові файли.


редагуйте, щоб додати оновлену інформацію та більше аргументів push --force

Розгляньте силу натискання з орендою замість натискання, але все ж віддайте перевагу відновленню

Ще одна проблема push --forceможе виникнути, коли хтось щось штовхне, перш ніж ти зробиш, але після того, як ти вже зібрався. Якщо ви натиснете на свою базовану версію, ви заміните роботу іншим .

git push --force-with-leaseВведений в git 1.8.5 ( завдяки коментарю @VonC до цього питання) намагається вирішити цю конкретну проблему. В основному, це призведе до помилки, а не натисне, якщо пульт змінено з останнього завантаження.

Це добре, якщо ви справді впевнені push --force, що потрібне, але все ж хочете запобігти більшим проблемам. Я б сказав, що це має бути push --forceповедінка за замовчуванням . Але це ще далеко не привід змусити а push. Люди, які зібралися перед вашою базою даних , все ще матимуть багато проблем, яких можна легко уникнути, якщо ви замість цього повернули .

А оскільки ми говоримо про git --pushвипадки ...

Чому хтось хоче змусити натискати?

@linquize привів гарний приклад сили коментарів: конфіденційні дані . Ви неправильно просочилися дані, які не слід висувати. Якщо ви досить швидкі, ви можете "виправити"* це, натиснувши на поштовх.

*Дані будуть по- , як і раніше перебувати на пульті дистанційного управління , якщо ви не робите сміття збирати , або очистити його яким - то чином . Існує також очевидний потенціал для того, щоб його поширювали інші, хто вже отримав це, але ви отримуєте ідею.


1
Проблема, @rogerdpack, не в тому, якщо це можливо. Це є. Але це може призвести до великої катастрофи. Чим більше хтось робить це (натискання) і чим рідше ви оновлюєте (витягуєте) з громадського репо, тим більша катастрофа. Він може розібрати світ, як ви його знаєте !!! 111 Принаймні світ, що складається саме з цього сховища.
Крегокс

3
Якщо у вас є конфіденційні дані, натисніть на них
зв’яжіть

3
@Cawas: Я думаю, що він означає, що якщо ви намагаєтесь видалити конфіденційні дані з сховища, то ви хочете переписати історію. Якщо ви повернетесь назад, конфіденційні дані все ще є в попередньому доступі. Це означає, що якщо хтось уже вийшов із сховища, то історія перезапису не допоможе вам запобігти доступу до конфіденційних даних - у цей момент вже пізно.
Стюарт Голодець

3
git push origin master --delete # do a very very bad bad thing git push origin master # regular pushце фактично вирішило мою проблему на відмінно (на репо, тільки зі мною та моїм другом). можливо, це неправильно для публічних репостів, але для приватних це рятування життя.
Може Пойразоглу

1
це відбувається автоматично з деякими менеджерами РЕПО, він же авто-сквош тощо. Сила натискання після закінчення гілки функцій для зменшення комісій є загальним і очікуваним.
FlavorScape

18

Перш за все, я не вносив би жодних змін безпосередньо в "головне" репо. Якщо ви дійсно хочете мати "головне" репо, тоді вам слід лише натиснути на нього, ніколи не змінювати його безпосередньо.

Щодо помилки, яку ви отримуєте, ви спробували git pullвід місцевого репо, а потім git pushдо головного репо? Те, що ви зараз робите (якщо я це добре зрозумів) - змушує натиснути, а потім втратити свої зміни в "головному" репо. Спершу слід змінити місцеві зміни.


так, я спробував витягнути, але я втрачаю втрачені дані через це потяг. Я хочу зробити основні репости такими, якими є мої локальні, без попереднього оновлення від основного.
Spyros

1
У такому випадку використовуйте git push -f, але тоді, якщо ви знову поміняєте основне репо, вам доведеться повернутися до місцевого репо і git pull, щоб він синхронізувався з останніми змінами. Тоді ви можете зробити свою роботу і знову натиснути. Якщо дотримуватися цього робочого процесу "push-pull", ви не отримаєте помилки, на яку ви скаржилися.
ubik

так, я розумію, що в цьому була моя вина: / Я спробую це і повернуся через деякий час подяку
Spyros

1
спробував примусити, але, повертаючись на головний сервер, щоб зберегти зміни, я отримую застарілі постановки. Таким чином, коли я здійснюю сховища, то схожі. І коли я знову намагаюся використовувати git push, я отримую ту ж помилку.
Spyros

17

Якщо я перебуваю на своїй локальній гілці A і хочу примусити натиснути локальну гілку B на початкову гілку CI, можна використовувати такий синтаксис:

git push --force origin B:C

2
Я дізнався, що навіть я перебуваю на своєму місцевому відділенні В, мені все одно потрібно це робити git push --force origin B:C. У моєму випадку, здається, що git push --force origin Cлише від локального ведучого до віддаленої гілки С вийде, незалежно від того, на якій гілці я зараз перебуваю. git version 2.3.8 (Apple Git-58)
Weishi Zeng

12

використовувати цю наступну команду:

git push -f origin master

1
Можливо, дайте трохи більше пояснень, чому ця відповідь є кращою для інших, і чим вона відрізняється.
Адам

о, вибачте за незручності, у мене була така ж проблема, і ця команда вирішила її, я подумав, що я повинен їй поділитися.
Мустафа Ельсаєд

12
Це точно так само, як і інші, ви просто змінили положення -fпрапора ...
svelandiag

11

Я б дуже рекомендував:

  • натисніть лише на основний репо

  • переконайтеся, що main repo - це голе репо , щоб ніколи не виникало проблем з тим, щоб основне дерево робочого репо не синхронізувалося з його .gitбазою. Див. " Як перенести локальний сховище git на інший комп'ютер? "

  • Якщо вам доведеться вносити модифікації в основний (голий) репо, клонуйте його (на головному сервері), зробіть свою модифікацію та натисніть на неї

Іншими словами, тримайте голий репо доступний як з основного сервера, так і з локального комп'ютера, щоб мати єдине репо вгору за течією, з / до якого потрібно тягнути / тягнути.


5

Це було нашим рішенням щодо заміни майстра у корпоративному сховищі gitHub при збереженні історії.

push -fосвоєння корпоративних сховищ часто відключено для підтримки історії філій. Це рішення працювало на нас.

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

підштовхніть свою філію до desiredOriginта створіть PR


3

У мене було те саме питання, але я вирішив його нарешті. Що, швидше за все, вам потрібно зробити, це виконати наступні дві команди git (замінити хеш на номер редакції git commit):

git checkout <hash>
git push -f HEAD:master
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.