Скасуйте певну фіксацію в Git, яку висунули на віддалений репост


788

Який найпростіший спосіб скасувати певний комітет, це:

  • не в голові чи в голові
  • Був висунутий на пульт.

Тому що, якщо це не остання фіксація,

git reset HEAD

не працює. І тому, що його відсунули на пульт,

git rebase -i

і

git rebase --onto

викличе певну проблему в пультах.

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

Іншими словами, що таке еквівалент Git наступних команд svn:

svn merge -r 303:295 http://svn.example.com/repos/calc/trunk

який видаляє всі зміни з 295 до 302 шляхом зворотного об'єднання всіх змін у цих редакціях як новий документ.

svn merge -c -302 ^/trunk

яка скасовує комісію 302, звичайно, додаючи ще один комітет, який зворотно об'єднує зміни з відповідним комітом.

Я подумав, що це повинна бути досить проста операція в Git і досить поширений випадок використання. У чому ще полягає атомний вчинок?

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

Відповіді:


1210

Визначте хеш коміту, використовуючи git log, а потім використовуйте git revert <commit>для створення нового комітету, який видаляє ці зміни. Певним чином, git revertце і зворотне git cherry-pick- остання застосовує патч до гілки, якій його не вистачає, перша видаляє її з гілки, яка має її.


237
І використовуйте перемикач -n, якщо вам потрібен код назад, але він не
вводиться

17
Що робить варіант «m»? Я спробував відновити git 8213f7d, але отримав це замість цього: помилка: Команда 8213f7dad1ed546b434a0d8a64cb783b530a5a30 є об'єднанням, але опція -m не задана. фатально: повернення не вдалося
Малькольм

10
Для відновлення злиття: git revert -m 1 <hash>
brunozrk

31
Попередження для всіх, хто хоче відновити злиття: git revert скасує всі зміни даних (тобто зміни файлів будуть повернені), але злиття все ще залишається в історії. Через це, якщо ви спробуєте об'єднати цю ж гілку ще раз пізніше, вона не буде включати жодних комітетів із гілки, що зливається до поверненого злиття. Це, швидше за все, не те, що ви хочете. Для повного об'єднання гілки знову потрібно буде повернути комітку, де ви повернули початкове злиття. Докладніше тут: kernel.mirrors.pair.com/pub/software/scm/git/docs/howto/…
etreworgy

3
Посилання в коментарі @etreworgy - 404. Я підозрюю, що це актуальна версія посилання: kernel.org/pub/software/scm/git/docs/howto/…
Тім Сміт

368

Мені не подобається, що git revertце робиться автоматично, тому це може бути корисним для деяких.

Якщо ви просто хочете, щоб змінені файли не були автоматичними , ви можете використовувати--no-commit

% git revert --no-commit <commit hash>

що те саме, що і -n

% git revert -n <commit hash>

9
Ви також можете зробити це, git reset HEAD~1 --softякщо ви вже повернулися без-n
Даніель

1
Але git reset HEAD~nце не вирішить скасування будь-яких зобов’язань, не постійно доступних від голови. Запит полягає у відміні будь-якої конкретної комісії.
sangeethkumarp

Я використав це рішення, але потрапив у конфлікт посеред відтворення. Після вирішення конфлікту я зробив так, git revert --continueяк мені наказали. Це спрацювало, але на жаль поклало результати. Можливо, мені потрібно було це зробити git revert --no-commit --continue.
мареофт

1
@sangeethkumarp коментар Даніеля - це додатковий крок, який ви можете зробити після того git revert, як ви забули -n; тому що в цей момент останнім фіксом є реверсія, то м'яке скидання скасує це введення, але не пов'язані з цим зміни коду відновлення
Олівер

@Daniel запропонував рішення, працюючи за коментарями для мене. Дякую. '' Git reset HEAD ~ 1 --soft ''
Md. Abu Sayed

41

Оскільки це вже було висунуто, ви не повинні безпосередньо маніпулювати історією. git revertповерне конкретні зміни з комітету за допомогою нового комітету, щоб не маніпулювати історією комісій.


1

Якщо комісія, яку ви хочете скасувати, - це об'єднана фіксація (вже об'єднана), то слід зробити -m 1або -m 2варіант, як показано нижче. Це дозволить git дізнатися, який батьківський фіксатор об'єднаного зобов'язання використовувати. Детальніше можна ознайомитись ТУТ .

  • git revert <commit> -m 1
  • git revert <commit> -m 2
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.