Скасування "git push"


591

Ось що я зробив у своїй передбачуваній стійкій галузі ...

% git rebase master
First, rewinding head to replay your work on top of it...
Fast-forwarded alpha-0.3.0 to master.
% git status
# On branch alpha-0.3.0
# Your branch is ahead of 'origin/alpha-0.3.0' by 53 commits.
#
nothing to commit (working directory clean)
% git push
Fetching remote heads...
  refs/
  refs/heads/
  refs/tags/
  refs/remotes/
'refs/heads/master': up-to-date
updating 'refs/heads/alpha-0.3.0'
  from cc4b63bebb6e6dd04407f8788938244b78c50285
  to   83c9191dea88d146400853af5eb7555f252001b0
    done
'refs/heads/unstable': up-to-date
Updating remote server info

Це все було помилкою, як я згодом зрозумів. Я хотів би скасувати весь цей процес і повернути гілку альфа-0,3.0 назад до того, що він був.

Що я повинен зробити?


можливо, цей пост stackoverflow? stackoverflow.com/questions/134882/undoing-a-git-rebase
Стін

4
Насправді це не та сама ситуація, скасування ребаза - це локальний сценарій сховища, а скасування git push включає віддалене сховище і може бути складніше, залежно від доступу, який ви маєте.
CB Bailey

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

Швидке уточнення - я здогадуюсь, якщо ви посилаєтесь на git-комітку за частковим хеш-значенням, git припустить, що ви говорите про фікс, чий хеш починається з цього рядка?
Гершом

Відповіді:


943

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

Тоді вам потрібно «примусити» просунути стару посилання.

git push -f origin last_known_good_commit:branch_name

або у вашому випадку

git push -f origin cc4b63bebb6:alpha-0.3.0

Можливо, ви receive.denyNonFastForwardsвстановили у віддаленому сховищі. Якщо це так, то ви отримаєте помилку, яка включає фразу [remote rejected].

У цьому сценарії вам доведеться видалити та відтворити гілку.

git push origin :alpha-0.3.0
git push origin cc4b63bebb6:refs/heads/alpha-0.3.0

Якщо це не працює - можливо, тому, що ви receive.denyDeletesвстановили, вам доведеться мати прямий доступ до сховища. У віддаленому сховищі вам доведеться виконати щось на зразок наступної сантехнічної команди.

git update-ref refs/heads/alpha-0.3.0 cc4b63bebb6 83c9191dea8

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

139
Для швидкої довідки, перший рядок тутgit push -f origin last_known_good_commit:branch_name
philfreo

5
git push -f походження cc4b63bebb6: alpha-0.3.0 => цей мені допоміг, Примітка альфа-0.3.0 - це назва гілки, а cc4b63bebb6 - ідентифікатор фіксації, до якого ми хочемо повернутись. тож після виконання цієї команди ми будемо в cc4b63bebb6 фіксувати ідентифікатор.
кумар

22
Це рішення є дуже небезпечним, якщо ви працюєте в спільному репо. Як найкраща практика, всі комісії, що надсилаються на віддалений репо, який поділяється спільним, слід вважати "незмінним". Використовуйте замість 'git revert': kernel.org/pub/software/scm/git/docs/…
Saboosh

1
jww - порівняно з усім іншим, git - це найпотужніший та найефективніший інструмент управління джерелами. Кожна команда використовує її по-різному. Варто провести вихідні, погравши зі свіжим сховищем та переглянувши всі загальні сценарії. Коли ви витратили деякий час на роботу з цим, розвиток стає набагато менш стресовим.
користувач1491819

165

Я вважаю, що ви також можете це зробити:

git checkout alpha-0.3.0
git reset --hard cc4b63bebb6
git push origin +alpha-0.3.0

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


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

3
+1 за цю відповідь, яка мені справді допомогла. Я також хотів додати (і уточнити), що ідентифікатор фіксації (який настає після параметра " --hard") повинен бути ідентифікатором будь-якої комісії, на яку ви хочете скинути свою філію.
Майкл Даутерманн

1
Чудово переписав історію ... будь-хто, хто міг перетягнути зміни, я просто переконався, що вони це зробили, git reset --hard [commit_id]щоб ми не возилися з континуумом простору та часу.
Форма чужорідного життя

9
Що означає "для" у "git push origin + alpha-0.3.0"?
jpierson

1
@jpierson +змушує здійснити поштовх, подібно до -f(але дещо інший: stackoverflow.com/a/25937833/1757149 ). Без нього, якщо ви намагаєтеся git push origin alpha-0.3.0штовхає зазнає невдачі: Updates were rejected because the tip of your current branch is behind.
грудня

106

git revert менш небезпечний, ніж деякі запропоновані тут підходи:

prompt> git revert 35f6af6f77f116ef922e3d75bc80a4a466f92650
[master 71738a9] Revert "Issue #482 - Fixed bug."
 4 files changed, 30 insertions(+), 42 deletions(-)
prompt> git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)
prompt>

Замініть 35f6af6f77f116ef922e3d75bc80a4a466f92650 своїм власним комітетом.


2
Як мені придумати ідентифікатор 35f6af6f77f116ef922e3d75bc80a4a466f92650? Ця відповідь буде краще, якби ви могли це пояснити.
Воломіке

2
@Volomike (і Googling Devs майбутнього), це питання описує багато способів його отримання: контроль версій та хеш-питання на SO
Jaime

Це правильна відповідь, тому що при "скиданні git" ви не зможете натиснути (оновлення було відхилено, оскільки кінчик поточної гілки знаходиться за віддаленим аналогом) або вам потрібно змусити тягнути, що насправді не є чистим.
Томас Деко

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

Я вибрав цей підхід кілька разів, але також використовую git rebase -i <id-before-last-good-commit>, щоб зробити інтерактивну базу даних та очистити історію, як тут пропонується, stackoverflow.com/questions/5189560/… .
Ернесто Аллі

35

Прийняте рішення (від @charles bailey) є дуже небезпечним, якщо ви працюєте в спільному репо.

Як найкраща практика, всі комісії, що надсилаються на віддалений репо, який поділяється спільним, слід вважати "незмінним". Використовуйте замість 'git revert': http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#fixing-mistakes

https://git-scm.com/book/be/v2/Git-Basics-Undoing-Things


Які саме інструкції ви виписуєте? У вас, здається, є старі посилання.
jww

32

Спосіб зробити це, не втрачаючи потрібних змін:

git reset cc4b63b 
git stash
git push -f origin alpha-0.3.0
git stash pop

Тоді ви можете вибрати файли, які ви хотіли натиснути


19

Ще один спосіб зробити це:

  1. створити іншу гілку
  2. оформити попередній комітет у цій гілці за допомогою "git checkout"
  3. висунути нову гілку.
  4. видалити стару гілку та натиснути на видалення (використання git push origin --delete <branch_name>)
  5. перейменуйте нову гілку в стару
  6. знову натиснути.

2
Це виглядає як справжнє рішення, коли ви вже помилилися з репортажами
Ілларіон Ковальчук

17
git push origin +7f6d03:master

Це поверне ваше репо до вказаного номера комісії


2
Це найпростіша відповідь вперед. Ви живий застав.
Ekundayo Blessing Funminiyi

2
Пам’ятайте, що локальні файли не скидаються.
K-Gun

11

Скасувати скидання декількох команд git --hard 0ad5a7a6 (Просто введіть хеш SHA1)

Скасувати останню комісію

git reset - тверда HEAD ~ 1 (зміни до останньої комісії будуть видалені) git reset --soft HEAD ~ 1 (зміни до останнього комітету будуть доступні як немітизовані локальні модифікації)


9

Сценарій 1 : Якщо ви хочете скасувати останню команду, скажімо, 8123b7e04b3, нижче наведена команда (це працювало для мене):

git push origin +8123b7e04b3^:<branch_name>

Результат виглядає нижче:

Total 0 (delta 0), reused 0 (delta 0)
To https://testlocation/code.git
 + 8123b7e...92bc500 8123b7e04b3^ -> master (forced update)

Додаткова інформація: Сценарій 2 : У деяких випадках ви можете повернути назад те, що ви скасували (в основному скасувати скасування) за допомогою попередньої команди, а потім скористайтеся командою нижче:

git reset --hard 8123b7e04b3

Вихід:

HEAD is now at cc6206c Comment_that_was_entered_for_commit

Більше інформації тут: https://github.com/blog/2019-how-to-undo-almost-anything-with-git


Сценарій 1 повинен бути прийнятою відповіддю, оскільки в питанні не вказано, яку комісію видалити. Прийнята відповідь видаляє лише останнє зобов’язання. Ця відповідь видаляє будь-яку комісію.
Домінік

0

Існуючі відповіді хороші і правильні, але що робити, якщо вам потрібно скасувати, pushале:

  1. Ви хочете зберігати комісії на місцевому рівні або хочете зберегти незапрошені зміни
  2. Ви не знаєте, скільки комітетів ви щойно натиснули

Використовуйте цю команду, щоб повернути зміни до списку:

git push -f origin refs/remotes/origin/<branch>@{1}:<branch>

-2

Якщо ви хочете ігнорувати останню команду, яку ви щойно натиснули у віддаленій гілці: це не видалить команду, а просто ігнорує її, перемістивши вказівник git на фіксацію раніше, на яку посилається HEAD ^ або HEAD ^ 1

git push origin +HEAD^:branch

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

git revert <SHA-1>
git push origin branch

1
так! це працювало як принадність при роботі з github. Дякую.
cukabeka

Питання про "push", тоді це стосується відділення Remote. Ні, щоб переміщувати HEAD щодо одного коміту, що означає ігнорувати останнє натискання, просто зробіть це: git push origin + HEAD ^: your_branch
mkebri
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.