Git - Скасувати поштовхи виконує


609

У мене є проект у віддаленому сховищі, синхронізованому з локальним сховищем (розробка) та сервером (prod). Я вносив деякі внесені зміни, які вже відсунув на віддалений та витягнутий із сервера. Тепер я хочу скасувати ці зміни. Тож я міг би просто git checkoutздійснити зобов’язання перед змінами та здійснити нові зміни, але я здогадуюсь, що виникнуть проблеми, щоб їх знову натиснути на віддалений. Будь-яка пропозиція щодо того, як мені діяти?


Відповіді:


735

Ви можете скасувати окремі зобов’язання за допомогою:

git revert <commit_hash>

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

git revert <oldest_commit_hash>..<latest_commit_hash>

Він повертає коміти між і включаючи зазначені коміти.

Перегляньте сторінку " git-revert man" для отримання додаткової інформації про git revertкоманду. Також перегляньте цю відповідь для отримання додаткової інформації про повернення комітетів.


22
Іншими словами, вона повертається до <oldest_commit_hash>;)
Девід

7
@mr_jigsaw Usegit log
gitaarik

2
У документації git йдеться про те, що команда повернення скасовує коміти між першим і останнім комітетами (включені як перший, так і останній). Дивіться Документацію
Онур Демір

4
@aod правильна, цю відповідь потрібно оновити. поточний API git для відновлення <oldest_commit_hash>включений до списку
ревертованих

4
з git 2.17.2 revert <old> .. <new> не включає старі, але включає <new>
chingis

353

Рішення, яке не залишає слідів "скасування".

ПРИМІТКА: не робіть цього, якщо хтось уже притягнув вашу зміну (я використовував би це лише на особистому репо)

робити:

git reset <previous label or sha1>

це здійснить повторну перевірку всіх оновлень на локальному рівні (таким чином, статус git перелічить усі оновлені файли)

тоді ви "виконуєте свою роботу" і повторно здійснюєте свої зміни (Примітка: цей крок не є обов'язковим)

git commit -am "blabla"

У цей момент ваше місцеве дерево відрізняється від віддаленого

git push -f <remote-name> <branch-name>

буде натискати та примушувати дистанційне розглянути цей натиск і видалити попередній (вказати віддалене ім’я та ім'я гілки не є обов'язковим, але рекомендується уникати оновлення всіх гілок прапором оновлення).

!! стежте за тим, щоб деякі теги все ще вказували на видалені фіксатори !! як-видалити-віддалений-тег


4
-всім відслідковуються файли будуть скоєні -m повідомлення про фіксацію слід
jo_

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

1
Яку "попередню мітку або sha1" я повинен використовувати ?. Чи слід вводити останній "правильний" той чи інший до цього і робити всі зміни, зроблені останнім правильним?
elysch

3
той, що знаходиться перед еротичним скоєнням
jo_

1
Саме те, що мені потрібно. Я помилково підштовхнув гілку до майстра. І як результат, у мене було багато сміття протягом усієї історії комітетів. Я щойно зробив git push -fдля останньої правильної фіксації та віддаленої історії очищення! Дякую!
Антон Рибалко

193

Що я роблю в цих випадках:

  • На сервері перемістіть курсор назад до останнього відомого доброго коміту:

    git push -f origin <last_known_good_commit>:<branch_name>
    
  • Місцево зробіть те ж саме:

    git reset --hard <last_known_good_commit>
    #         ^^^^^^
    #         optional
    



Дивіться повний приклад гілки, my_new_branchяку я створив для цього:

$ git branch
my_new_branch

Це недавня історія після додавання деяких матеріалів до myfile.py:

$ git log
commit 80143bcaaca77963a47c211a9cbe664d5448d546
Author: me
Date:   Wed Mar 23 12:48:03 2016 +0100

    Adding new stuff in myfile.py

commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date:   Tue Mar 18 12:46:59 2016 +0100

    Initial commit

Я хочу позбутися останньої комісії, яка вже була натиснута, тому я запускаю:

$ git push -f origin b4zad078237fa48746a4feb6517fa409f6bf238e:my_new_branch
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:me/myrepo.git
 + 80143bc...b4zad07 b4zad078237fa48746a4feb6517fa409f6bf238e -> my_new_branch (forced update)

Приємно! Тепер я бачу, що файл, який було змінено на цей комітет ( myfile.py), відображається в "не ставиться для здійснення"

$ git status
On branch my_new_branch
Your branch is up-to-date with 'origin/my_new_branch'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   myfile.py

no changes added to commit (use "git add" and/or "git commit -a")

Оскільки я не хочу цих змін, я також просто переміщу курсор назад локально:

$ git reset --hard b4zad078237fa48746a4feb6517fa409f6bf238e
HEAD is now at b4zad07 Initial commit

Тож тепер HEAD знаходиться в попередньому комітеті, як у локальному, так і віддаленому:

$ git log
commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date:   Tue Mar 18 12:46:59 2016 +0100

    Initial commit

10
Це правильна відповідь! це саме те, що потрібно робити в моєму випадку, завдяки чому сьогодні дізнався щось нове :)
Еглі Бесерра

2
Це правильна відповідь! Це щодо штовхнутих (!) Чинів!
powtac

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

1
Ідеальна відповідь. Працювали добре, як і очікувалося!
RafiAlhamd

2
Хтось купить цій людині пиво!
Джей Небвані

72

Ви можете ПОВЕРНУТИСЯ (або можете також назвати її ВІДКЛЮЧИТИ ) Git Commit BOTH локально та віддалено, якщо виконувати дії, наведені нижче, за допомогою командного рядка git.

Виконайте наступну команду, щоб побачити ідентифікатор фіксації, який потрібно відновити

git log --oneline --decorate --graph

У вас вийде такий скріншот введіть тут опис зображення

Якщо ви також перевірите віддалений (через веб-інтерфейс), то ви можете бачити, що це було б так, як показано нижче

введіть тут опис зображення

Згідно скриншоту в даний час ви при фіксуванні ID e110322 однак ви хочете повернутися до 030bbf6 ОБИДВА і дистанційно .

Виконайте наступні кроки для ВИДАЛЕННЯ / РЕВЕРТАЦІЇ Здійснення локально + віддалено


Перше місцеве повернення для введення id 030bbf6

git reset --hard 030bbf6

слідом за ним

git clean -f -d

Ці дві команди чисті сили скидаються, щоб здійснити етап 030bbf6, як показано нижче на знімку

введіть тут опис зображення

Тепер, якщо ви запускаєте статус git, то ви побачите, що ви ДВА КОМІТИ ПІД ЧАС З віддаленої гілки, як показано нижче введіть тут опис зображення

Виконайте наступне, щоб оновити свої індекси (якщо є оновлення). Рекомендується попросити всіх розробників не приймати будь-які запити на виклик на головній віддаленій гілці.

git fetch --all

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

введіть тут опис зображення Код

git push -u origin +master

Тепер, якщо ви бачите веб-інтерфейс віддаленого, тоді фіксація також повинна бути повернена.

введіть тут опис зображення


61

Це видалить ваші натиснуті коміти

git reset --hard 'xxxxx'

git clean -f -d

git push -f

7
Цей спосіб правильно переписує історію, щоб видалити комітку. Дивовижний
Джессі Реза Хорасані

2
ця відповідь - el magnifeco!
truthadjustr

3
Люблю відповідь, дякую :)
Dzenis H.

1
Просто, щоб було зрозуміло (я не був впевнений): Фіксація буде поточною фіксацією після операції. Не останню, яку потрібно видалити.
Maik639

21
git revert HEAD -m 1

У наведеному вище рядку коду. "Останній аргумент представляє"

  • 1 - повертається одна фіксація.

  • 2 - повертає останні два коміти.

  • n - повертає останні n команд.

Вам потрібно натиснути на цю команду, щоб мати ефект на віддаленому. У вас є інші варіанти, такі як визначення діапазону комісій для відновлення. Це один із варіантів.


Пізніше використовувати git commit -am "COMMIT_MESSAGE" тоді git pushабоgit push -f


8
Це неправда - параметр -m вказує кількість батьків, до яких потрібно повернути (як правило, 1, якщо ви хочете повернути вхідні, "їхні", зміни, на відміну від 2 для змін, об'єднаних у зміни, "наші" - для об'єднання 2 здійснює). Це не має нічого спільного з кількістю скасованих комісій - якщо ви хочете скасувати діапазон комісій, скористайтесяgit revert ref1..ref2
Null Reference

1
Не мав бажаного ефекту
Сем Тюк

2

2020 Простий спосіб:

git reset <commit_hash>

(Хеш останніх зобов'язань, які ви хочете зберегти).

Ви не зможете зберегти зміни, які зараз не надходять.

Якщо ви хочете натиснути знову, вам потрібно зробити:

git push -f

0

Ось мій шлях:

Скажімо, назва філії develop.

# Create a new temp branch based on one history commit
git checkout <last_known_good_commit_hash>
git checkout -b develop-temp

# Delete the original develop branch and 
# create a new branch with the same name based on the develop-temp branch
git branch -D develop
git checkout -b develop

# Force update this new branch
git push -f origin develop

# Remove the temp branch
git branch -D develop-temp

0

Можна зробити щось на кшталт

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