Як повернути сховище Git до попереднього комітету?


7630

Як повернутися з мого поточного стану до знімка, зробленого на певному виконанні?

Якщо я це роблю git log, то отримую такий результат:

$ git log
commit a867b4af366350be2e7c21b8de9cc6504678a61b`
Author: Me <me@me.com>
Date:   Thu Nov 4 18:59:41 2010 -0400

blah blah blah...

commit 25eee4caef46ae64aa08e8ab3f988bc917ee1ce4
Author: Me <me@me.com>
Date:   Thu Nov 4 05:13:39 2010 -0400

more blah blah blah...

commit 0766c053c0ea2035e90f504928f8df3c9363b8bd
Author: Me <me@me.com>
Date:   Thu Nov 4 00:55:06 2010 -0400

And yet more blah blah...

commit 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Author: Me <me@me.com>
Date:   Wed Nov 3 23:56:08 2010 -0400

Yep, more blah blah.

Як повернутись до зобов’язання з 3 листопада, тобто здійснити 0d1d7fc?



116
Ось дуже чіткий і ретельний пост про скасування речей у git, прямо від Github.
Nobita

3
Пов'язане: Відкат до старого Git-комітету у публічному репо . Зауважте, що це запитання додає обмеження, що РЕПО є загальнодоступним.

58
Я люблю git, але той факт, що є 35 відповідей на щось, що повинно бути неймовірно простим, розкриває величезну проблему з git. Або це документи?
The Muffin Man

2
Як мова "пастка" у використанні слова для повернення як розмовного значення для скидання тут навіть не звертається ??? 6594 відкликає досі, а не редагувати таким чином, щоб підкреслити різницю? Не було б більш заплутаним посилання на "збереження файлу" тут з виразом "вчинення" ...
RomainValeri

Відповіді:


9721

Це багато що залежить від того, що ви маєте на увазі під "поверненням".

Тимчасово перейдіть на інший комітет

Якщо ви хочете тимчасово повернутися до цього, обдуріть, а потім поверніться туди, де ви є, все, що вам потрібно зробити, - це перевірити бажану комісію:

# This will detach your HEAD, that is, leave you with no branch checked out:
git checkout 0d1d7fc32

Або якщо ви хочете робити зобов’язання, поки ви там, продовжуйте і робіть нову гілку, поки ви на ній:

git checkout -b old-state 0d1d7fc32

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

Неопубліковані комітети видаляються важко

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

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.

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

Скасувати публікації комітетів за допомогою нових комітетів

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

# This will create three separate revert commits:
git revert a867b4af 25eee4ca 0766c053

# It also takes ranges. This will revert the last two commits:
git revert HEAD~2..HEAD

#Similarly, you can revert a range of commits using commit hashes:
git revert a867b4af..0766c053 

# Reverting a merge commit
git revert -m 1 <merge_commit_sha>

# To get just one, you could use `rebase -i` to squash them afterwards
# Or, you could do it manually (be sure to do this at top level of the repo)
# get your index and work tree into the desired state, without changing HEAD:
git checkout 0d1d7fc32 .

# Then commit. Be sure and write a good message describing what you just did
git commit

git-revertСторінка керівництва фактично охоплює багато з цього в його описі. Ще одне корисне посилання - це розділ git-scm.com, де обговорюється повернення git .

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

Також ця відповідь може бути корисною в цьому випадку:
Як повернути HEAD назад до попереднього місця? (Окрема голова)


118
@ Коментар Рода на git revert HEAD~3як кращий ват , щоб повернутися 3фиксациями є важливим вранці умовності.
Нова Олександрія

19
Не могли б ви написати цілий номер? як:git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Spoeken

16
@MathiasMadsenStav Так, ви, звичайно, можете вказати комісії за допомогою повного SHA1. Я використовував скорочені хеші, щоб зробити відповідь більш читаною, і ви також схильні використовувати їх, якщо ви вводите текст. Якщо ви копіюєте та вставляєте, використовуйте повний хеш. Див. Розділ " Визначення редакцій" у програмі man git rev-parse для повного опису того, як можна називати коміти.
Каскабель

59
Ви можете скористатися git revert --no-commit hash1 hash2 ...і після цього просто здійснити кожне повернення за один git commit -m "Message"
комітет

6
Що означає "публікація" в цьому контексті?
Howiecamp

1849

Тут багато складних і небезпечних відповідей, але насправді це просто:

git revert --no-commit 0766c053..HEAD
git commit

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

( --no-commitПрапор дозволяє git повернути всі зобов’язання одночасно; інакше вам буде запропоновано повідомлення про кожну комісію в діапазоні, заповнивши вашу історію непотрібними новими комісіями.)

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


23
Якщо ви дійсно хочете мати індивідуальні коміти (замість того, щоб повертати все за допомогою однієї великої комісії), ви можете перейти --no-editзамість цього --no-commit, щоб вам не довелося редагувати повідомлення про фіксацію для кожного реверсії.

87
Якщо одна з комірок між 0766c053..HEAD є злиттям, виникла помилка (що не вказано -m). Це може допомогти тим , що зустрічаючи: stackoverflow.com/questions/5970889 / ...
timhc22

7
Щоб побачити відмінності перед використанням git diff --cached.
Джон Ерк

21
$ git revert --no-commit 53742ae..HEADповерненняfatal: empty commit set passed
Алекс Г

10
@AlexG тому, що вам потрібно ввести хеш до того, до якого ви хочете повернутися. У моєму випадку хеші були на кшталт: 81bcc9e HEAD{0}; e475924 HEAD{1}, ...(від git reflog), і я хотів скасувати те, що робив 81bcc9e, тоді мені довелося це зробитиgit revert e475924..HEAD
EpicPandaForce

1611

Негідний кодер?

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

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

Повернення робочої копії до останнього комітету

Щоб повернутися до попереднього комітету, ігноруючи будь-які зміни:

git reset --hard HEAD

де HEAD - це остання комісія у вашій поточній галузі

Повернення робочої копії до більш старої комісії

Щоб повернутися до комітету, який є старшим за останнє:

# Resets index to former commit; replace '56e05fced' with your commit code
git reset 56e05fced 

# Moves pointer back to previous HEAD
git reset --soft HEAD@{1}

git commit -m "Revert to 56e05fced"

# Updates working copy to reflect the new commit
git reset --hard

Кредити надходять на аналогічне запитання щодо переповнення стека. Повернутись до комісії з допомогою хеша SHA в Git? .


33
Я це зробив, але потім мені не вдалося здійснити та перейти до віддаленого сховища. Я хочу, щоб конкретні старші зобов'язання стали ГОЛОВОМ ...
Леннон

7
Це означає, що ви вже підняли на себе зобов'язання, які хочете повернути. Це може створити багато проблем людям, які перевірили ваш код і працюють над ним. Оскільки вони не можуть плавно застосовувати ваше зобов’язання над своїм. У такому випадку краще виконувати відміни git. Якщо ви єдиний, хто використовує репо. Зробіть git push -f (Але подумайте, перш ніж це зробити)
vinothkr

6
Я як раз і хочу зазначити, що в якості альтернативи для м'якого рішення скидання, замість того , щоб робити змішаний скидання першим і жорсткий скидання останнім, ви можете зробити жорсткий скидання першим, таким чином : git reset --hard 56e05fc; git reset --soft HEAD@{1}; git commit.

5
@nuton linus принижуючи себе, творця git, розкритикував його за занадто складний. Він записує, що "шокований" git став таким популярним, враховуючи його складність
boulder_ruby

5
@boulder_ruby Я думаю, ти мав на увазі, що Лінус Торвальдс був творцем git. Але я думаю, що Лінус Полінг, мабуть, погодиться, що git є складним.
Suncat2000

215

Найкращий варіант для мене та, ймовірно, інших - це варіант скидання Git:

git reset --hard <commidId> && git clean -f

Це був найкращий варіант для мене! Це просто, швидко і ефективно!


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

Також з коментарів, якщо ви хотіли менш "бальний" метод, ви можете використовувати

git clean -i

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

7
Я друге попередження @ Cupcake ... будьте в курсі наслідків. Однак зауважте, що якщо вам справді потрібно змусити ці зобов’язання зникнути з історії назавжди, цей метод скидання + чистий це зробить, і вам потрібно буде силою відсунути змінені гілки назад на будь-які та всі віддалені.
ашназг

5
git clean -f НЕБЕЗПЕЧНО ОПАСНОСТЬ
Tisch

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

2
@Ade .. Ви можете використовувати git push -fпрапор .. Але будьте обережні, він перекриє пульт дистанційного керування .. Будьте впевнені, що знаєте, що хочете зробити ...
Погріндіс

176

Перш ніж відповісти, давайте додамо деяку інформацію, пояснивши, що це HEADтаке.

First of all what is HEAD?

HEADце просто посилання на поточний комітет (останній) у поточній галузі. У HEADбудь-який момент може бути лише одинарний (виключаючи git worktree).

Вміст HEADзберігається всередині .git/HEAD, і він містить 40 байт SHA-1 поточної комісії.


detached HEAD

Якщо ви не перебуваєте на останньому комітеті - це означає, що HEADвказує на попереднє вчинення в історії, воно називається detached HEAD.

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

У командному рядку це буде виглядати приблизно так - SHA-1 замість назви гілки, оскільки the HEADне вказує на кінчик поточної гілки:

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


Кілька варіантів того, як відновитись із відокремленої ГЛАВИ:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

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

У цей момент ви можете створити відділення і почати працювати з цього моменту:

# Checkout a given commit.
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# Create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Ви завжди можете використовувати reflogтакож. git reflogвідобразиться будь-яка зміна, яка оновила, HEADі перевірка потрібного запису відмикання HEADповернеться до цього зобов'язання.

Кожен раз, коли зміниться HEAD, буде новий запис у reflog

git reflog
git checkout HEAD@{...}

Це поверне вас до бажаного завдання

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


git reset HEAD --hard <commit_id>

"Перемістіть" голову назад до потрібної фіксації.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.
  • Примітка: ( Так як Git 2.7 ) ви також можете використовувати git rebase --no-autostashтакож.

Ця схема ілюструє, яка команда робить що. Як ви бачите, там можна reset && checkoutзмінити HEAD.

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


6
Відмінний натяк git reflog, саме це мені і потрібно
smac89

4
Ой! Це все здається жахливо складним ... чи не існує простої команди, яка просто відведе крок назад у процесі? Як переходити від версії 1.1 у вашому проекті, повернутися до версії 1.0? Я б очікував чогось типу: git stepback_one_commit або щось таке ....
Кокодоко

є: git reset HEAD^--hard`
CodeWizard

3
@Kokodoko Так, це жахливо складно ... і прекрасний приклад того, як мало уваги знають експерти для людей, які тільки починають. Будь ласка, зверніться до моєї відповіді тут, а також до книги, яку я рекомендую. Git НЕ є тим, що ви можете просто зрозуміти інтуїтивно. І я можу бути абсолютно впевненим, що CodeWizard цього не зробив.
мійський гризун

145

Якщо ви хочете "відключити", стерти останнє повідомлення про фіксацію та повернути змінені файли назад у постановку, ви використовуєте команду:

git reset --soft HEAD~1
  • --softвказує на те, що незапущені файли слід зберігати як робочі файли, на відміну від --hardяких вони б відкидали.
  • HEAD~1є останнім комітом. Якщо ви хочете відкатати 3 коміти, які ви можете використати HEAD~3. Якщо ви хочете відкатати на певний номер редакції, ви також можете зробити це, використовуючи його хеш SHA.

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

Джерело: http://nakkaya.com/2009/09/24/git-delete-last-commit/


3
Це м'яко і м’яко: без ризику, якщо ви не підштовхували свою роботу
nilsM

124

Це можна зробити за допомогою наступних двох команд:

git reset --hard [previous Commit SHA id here]
git push origin [branch Name] -f

Це видалить ваш попередній комітет Git.

Якщо ви хочете зберегти свої зміни, ви також можете скористатися:

git reset --soft [previous Commit SHA id here]

Тоді це збереже ваші зміни.


2
Я спробував 1/2 дюжини відповідей в цьому дописі, поки не дійшов до цього .. всі ті інші, мій конфігурація git продовжував давати мені помилку при спробі натиснути. Ця відповідь спрацювала. Дякую!
Джин Бо

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

1
Це був єдиний спосіб для мене, щоб скасувати погане злиття, відновлення не спрацювало в такому випадку. Дякую!
Дейв Коул

Найкраща відповідь. Спасибі
Імран Поллоб

Найкраща відповідь, дякую.
user1394

114

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

git add . && git checkout master -f

Короткий опис:

  • Він НЕ створюватиме жодних комітетів, як git revertце робиться.
  • Він НЕ від'єднує вашу голову, як git checkout <commithashcode>це робить.
  • Він перекриє всі ваші локальні зміни та видалить усі додані файли з моменту останнього вчинення у філії.
  • Він працює лише з іменами гілок, тому ви можете повернутись лише до останньої фіксації у цій гілці.

Я знайшов набагато більш зручний і простий спосіб досягти результатів вище:

git add . && git reset --hard HEAD

де HEAD вказує на останню комісію у вашої поточної галузі.

Це той самий код коду, що і boulder_ruby, який я запропонував, але я додав git add .раніше, git reset --hard HEADщоб стерти всі нові файли, створені з моменту останньої фіксації, оскільки саме так, як очікують більшість людей, я переконаний, повертаючись до останньої фіксації.


83

Добре, повернутися до попереднього комітету в Git досить просто ...

Поверніться назад, не зберігаючи зміни:

git reset --hard <commit>

Поверніться назад, зберігаючи зміни:

git reset --soft <commit>

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

Але як ви бачите різницю в тому, щоб використовувати два прапори --softі --hard, за замовчуванням, git resetвикористовувати --softпрапор, але це хороша практика завжди використовувати прапор, я пояснюю кожен прапор:


--soft

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


- твердий

Будьте обережні з цим прапором. Він скидає робоче дерево і всі зміни відслідковуваних файлів, і все пропаде!


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

Git скидається до коміту



70

Якщо припустити, що ви говорите про майстра та про цю відповідну гілку (це могло бути будь-якою робочою гілкою, про яку ви маєте справу):

# Reset local master branch to November 3rd commit ID
git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50

# Reset remote master branch to November 3rd commit ID
git push -f origin 0d1d7fc32e5a947fbd92ee598033d85bfc445a50:master

Я знайшов відповідь у публікації в блозі (зараз її більше немає)

Зауважте, що це "Скидання та примушування змін до віддаленого", так що якщо інші члени вашої команди вже потягнули, ви створите для них проблеми. Ви знищуєте історію змін, що є важливою причиною, чому люди використовують git в першу чергу.

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


6
Чим ця відповідь відрізняється від безлічі інших?
Matsmath

Це прикро. Я надіслав по електронній пошті блогеру - сподіваюся, у нього все ще є!
markreyes


2
Синтаксис натискання відсутній у більшості інших пропозицій, як це виправити. Працювали чудово.
jpa57

61

Скажіть, у вас є текстові файли з назвою ~/commits-to-revert.txtgit log --pretty=onelineїх отримував)

fe60adeba6436ed8f4cc5f5c0b20df7ac9d93219
0c27ecfdab3cbb08a448659aa61764ad80533a1b
f85007f35a23a7f29fa14b3b47c8b2ef3803d542
e9ec660ba9c06317888f901e3a5ad833d4963283
6a80768d44ccc2107ce410c4e28c7147b382cd8f
9cf6c21f5adfac3732c76c1194bbe6a330fb83e3
fff2336bf8690fbfb2b4890a96549dc58bf548a5
1f7082f3f52880cb49bc37c40531fc478823b4f5
e9b317d36a9d1db88bd34831a32de327244df36a
f6ea0e7208cf22fba17952fb162a01afb26de806
137a681351037a2204f088a8d8f0db6e1f9179ca

Створіть сценарій оболонки Bash, щоб відновити кожен з них:

#!/bin/bash
cd /path/to/working/copy
for i in `cat ~/commits-to-revert.txt`
do
    git revert $i --no-commit
done

Це повертає все до попереднього стану, включаючи створення файлів і каталогів, і видалення, прив'язує їх до своєї філії, і ви зберігаєте історію, але ви повертаєте її назад до тієї ж файлової структури. Чому Git не має, git revert --to <hash>це поза мене.


41
Ви можете скористатись git revert HEAD~3видаленням останніх 3 зобов’язань
Пд

25
@Rod - Ні, це неправильно. Ця команда поверне команду, яка є третьою бабусею та дідусем із HEAD (не три останні коміти).
kflorence

1
@kflorence Добре дякую за інформацію. Було б git revert -n master~3..master~1працювати? (Як видно з kernel.org/pub/software/scm/git/docs/git-revert.html )
стрижень

3
@Rod - Це звучить правильно, звичайно, чи некрасивий синтаксис, чи не так? Я завжди знаходив перевірку комісії, до якої хочу "повернути", а потім здійснюю інтуїтивніше.
kflorence

7
Є набагато простіший спосіб зробити це зараз, ніж із подібним сценарієм, просто використовувати git revert --no-commit <start>..<end>, тому що git revertприймає діапазон фіксації в нових (або всіх?) Версіях Git. Зауважте, що старт діапазону не включається до відновлення.

58

Додаткові альтернативи рішенням Джефромі

Рішення Jefromi, безумовно, найкращі, і ви їх обов'язково повинні використовувати. Однак заради повноти я також хотів показати ці інші альтернативні рішення, які також можуть бути використані для скасування комісії (у тому сенсі, що ви створюєте нове зобов’язання, яке скасовує зміни попереднього комітету , як і те, що git revertробить).

Для того, щоб бути ясно, ці альтернативи не кращий спосіб повернути фіксації , рішення Jefromi є , але я просто хочу , щоб вказати на те , що ви також можете використовувати ці інші методи , щоб досягти того ж , як git revert.

Альтернатива 1: жорсткі та м'які скидання

Це дуже дещо модифікована версія рішення Чарльза Бейлі про повернення до комітету хеша SHA в Git? :

# Reset the index to the desired commit
git reset --hard <commit>

# Move the branch pointer back to the previous HEAD
git reset --soft HEAD@{1}

# Commit the changes
git commit -m "Revert to <commit>"

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

Альтернатива 2: Видаліть поточне дерево та замініть новим

Це рішення походить від рішення svick для Checkout старої фіксації та зробити її новою фіксацією :

git rm -r .
git checkout <commit> .
git commit

Подібно до альтернативи №1, це відтворює стан <commit>поточної робочої копії. Слід зробити це git rmспочатку, оскільки git checkoutне буде видалено файли, додані з тих пір <commit>.


Про альтернативу 1, одне швидке запитання: тим самим ми не втрачаємо між комісіями, чи не так?
Богач

2
@Bogac - точки вказують шлях до файлу, в цьому випадку поточний каталог, тому передбачається, що ви запускаєте його з кореня робочої копії.
Том

Попередження повторюється у відповідь кілька разів, але чи може хтось додати, чому це не найкращий спосіб - порівняно, із чимось на зразок git revert HEAD~2..HEADрішення, пов'язаного із @ Каскабелем (@ Jefromi). Я не бачу проблеми.
Джошуа Голдберг

55

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

git reset HEAD~1

Отже, не потрібно вводити ідентифікатори тощо! :)


не працював, потяг git після цього приводить до помилки: помилка: Ваші локальні зміни до наступних файлів будуть перезаписані злиттям:
malhal

1
@malhal Це тому, що у вас були невмілі зміни. Заховайте / скиньте їх, і тоді воно буде працювати без цієї помилки.
Пол Вальчевський

39

Існує команда (не частина core Git, але вона є в пакеті git-extras ) спеціально для повернення та постановки старих комітетів:

git back

На сторінці man , він також може бути використаний як такий:

# Remove the latest three commits
git back 3

38

Найкращий спосіб:

git reset --hard <commidId> && git push --force

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

Будьте обережні, якщо --forceпрапор видаляє всі наступні зобов’язання після вибраного фіксації, без можливості їх відновлення.


3
працював як шарм!
Гаурав Гупта

Я спростував, тому що я не бачу, як ваша відповідь надає будь-яку нову інформацію, яка вже не надана, наприклад, stackoverflow.com/a/37145089/1723886 , stackoverflow.com/a/27438379/1723886 або stackoverflow.com/a/48756719/1723886 . Насправді більшість комісій вже згадують про скидання git --hard, а багато інших згадують використання --force або -f для натискання.
Алекс Телон

Він виконує роботу лише з однією командою, зрозумілою та простою. Ви можете вільно відхилити мою відповідь, якщо вона вам не подобається.
david.t_92

1
Ще одним варіантом, який слід розглянути на майбутнє, є запропонувати редагування попередньої відповіді або додавання коментаря, в якому сказано, що "це також можна зробити в одному рядку, використовуючи &&", наприклад. Таким чином, кожен зможе побачити вдосконалену відповідь в одному місці.
Алекс Телон

36

Після всіх змін, коли ви натискаєте всі ці команди, можливо, вам доведеться використовувати:

git push -f ...

І не тільки git push.


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

3
Іноді це те, чого ти хочеш. Приклад: здійснив і натиснув кілька комітів на неправильну гілку (гілку А). Після вибору вишні до гілки B я хочу, щоб ці комісії були вилучені з гілки А. Я не хотів би повертатися, оскільки пізніше відновлення буде застосовано, коли гілки A і B об'єднані разом. Здійснення скидання - твердий <commitId> у гілці А з подальшим силовим натисканням видаляє ці комірки з гілки, зберігаючи їх у гілці B. Я можу відійти від цього, тому що я знаю, що ніхто більше не розвивається на гілці А.
Дуг R

Дякую! Я не міг зрозуміти, як змусити віддалену гілку відповідати моїй місцевій гілці, просто потрібно було натиснути.
Mido

32

Ви можете виконати всі ці початкові кроки самостійно і повернутися до сховища Git.

  1. Виконайте останню версію вашого сховища з Bitbucket за допомогою git pull --allкоманди.

  2. Запустіть команду Git log з -n 4вашого терміналу. Число після -nвизначає кількість комісій у журналі, починаючи з останньої комісії у вашій місцевій історії.

    $ git log -n 4
    
  3. Скиньте заголовок історії вашого сховища, використовуючи, git reset --hard HEAD~Nде N - кількість комісій, які ви хочете повернути. У наступному прикладі заголовок буде повернутий один фіксатор до останнього комітету в історії сховища:

  4. Натисніть на зміну до сховища Git, використовуючи git push --forceпримусити натиснути зміну.

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

git pull --all
git reset --hard HEAD~1
git push --force


28

Виберіть потрібну комісію та перевірте її

git show HEAD
git show HEAD~1
git show HEAD~2 

поки ви не отримаєте необхідні зобов'язання. Щоб HEAD вказував на це, зробіть

git reset --hard HEAD~1

або git reset --hard HEAD~2чи що завгодно.


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

2
Також, щоб бути зрозумілим, git show HEADеквівалентно просто використанню git log HEAD -1.

25

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


ШВИДКО І БУДНО : залежно від обставин, швидке та брудне може насправді бути дуже ДОБРИМ. Моє рішення тут - НЕ безповоротно замінювати файли, що є у вашій робочій директорії, файлами, витягнутими / витягнутими з глибини сховища git, що ховаються під вашим. багато. ВИ НЕ МОЖЕТЕ РОБИТИ ТАКЕ ГЛИБОТНІ МОРСІ, ЩО ВІДКРИТИ, що може виявитися катастрофічною ситуацією, і спроба зробити це без достатнього досвіду може виявитися фатальним .


  1. Скопіюйте весь каталог і назвіть його чимось іншим, наприклад "мій проект - копіюйте". Якщо припустити, що ваші файли сховища git ("repo") знаходяться в каталозі "мій проект" (місце за замовчуванням для них, в каталозі під назвою ".git"), тепер ви скопіювали як робочі файли, так і файли репо.

  2. Зробіть це в каталозі "мій проект":

    .../my project $ git reset --hard [first-4-letters&numbers-of-commit's-SHA]
    

Це поверне стан репо в "моєму проекті" до того, яким він був, коли ви здійснили виконання ("фіксація" означає зйомку робочих файлів). Усі зобов’язання з тих пір назавжди будуть втрачені в розділі "мій проект", АЛЕ ... вони все одно будуть присутні в репо в розділі "мій проект - копія", оскільки ви скопіювали всі ці файли - включаючи файли під ... /. Git /.

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

Очевидна річ, якщо ви хочете продовжувати стан проекту, не фактично відкидаючи роботу, оскільки ця вилучена фіксація - це перейменування вашого каталогу знову: Видаліть проект, що містить отриману комісію (або дайте їй тимчасову назву) та перейменуйте свій " мій проект - скопіюйте "каталог назад у" мій проект ". Тоді, можливо, спробуйте зрозуміти деякі інші відповіді тут, і, ймовірно, зробіть ще один вчинок досить скоро.

Git - це геніальне творіння, але абсолютно ніхто не в змозі просто "забрати його на льоту": також люди, які намагаються пояснити це занадто часто припускають попередні знання інших VCS [Системи управління версіями] і заглиблюються занадто глибоко далеко занадто рано, і вчиняти інші злочини, як-от використання взаємозамінних термінів для "перевірки" - способами, які іноді виглядають майже розрахованими на те, щоб заплутати новачка.

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

Особливо, якщо, наприклад, це відчайдушна ситуація і ти новачок з Git!

PS: Ще одна думка: На даний момент насправді досить просто зберігати Git repo в каталозі, відмінному від того, у якому є робочі файли. Це означає, що вам не доведеться копіювати весь сховище Git, використовуючи вищезгадане швидке та брудне рішення. Дивіться відповідь Фріер, використовуючи --separate-git-dir тут . Однак будьте попереджені : якщо у вас є сховище "окремого каталогу", яке ви не копіюєте, і ви робите жорсткий скидання, всі версії, що послідують після здійснення скидання, будуть втрачені назавжди, якщо у вас немає, як ви абсолютно повинні, регулярно створюйте резервні копії вашого сховища, бажано, в Хмарі (наприклад, Google Drive ) серед інших місць.

З цього приводу "резервного копіювання до хмари" наступним кроком є ​​відкриття рахунку (звичайно безкоштовно) у GitHub або (що краще, на мій погляд), GitLab . Потім ви можете регулярно виконувати git pushкоманду, щоб зробити ваше репортаж у хмарі "належним чином". Але знову ж таки, говорити про це може бути занадто багато занадто рано.


23

Це ще один спосіб прямого відновлення до нещодавньої фіксації

git stash
git stash clear

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

PS: У нього є невелика проблема; він також видаляє всі нещодавно збережені зміни приховування. Яка здогадка в більшості випадків не має значення.


ПРИМІТКА: Нові файли, не додані в індекс, не зберігаються. Ви занадто додали їх або видалили вручну.
andreyro

Чому о, чому очищення приховування? Окрім того, що це не рішення, це насправді шкідливо. Читання самого першого речення питання негайно скасовує приховану розв'язку (що може бути корисним ТІЛЬКО для повернення до ПОСЛІДНОГО зобов'язання).
RomainValeri

22

Щоб повністю очистити каталог кодерів від випадкових змін, ми використовували:

git add -A .
git reset --hard HEAD

Просто git reset --hard HEADпозбудуться модифікацій, але "нових" файлів не позбудеться. У їхньому випадку вони випадково перетягли важливу папку десь випадково, і всі ці файли Git трактували як нові, тому reset --hardне виправили. Запустивши git add -A .заздалегідь, він явно відстежив їх усіх git, щоб їх стерти шляхом скидання.


21

Щоб зберегти зміни від попереднього зобов’язання до HEAD та перейти до попереднього виконання, виконайте такі дії:

git reset <SHA>

Якщо зміни не потрібні в попередньому зобов’язанні HEAD і просто відмініть всі зміни, виконайте:

git reset --hard <SHA>

20

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

git reset --hard origin/master

/superuser/273172/how-to-reset-master-to-origin-master


18

Повернути - це команда відкатати коміти.

git revert <commit1> <commit2> 

Зразок:

git revert 2h3h23233

Він здатний зайняти дальність, ніж нижче. Тут 1 говорить "скасувати останню передачу".

git revert HEAD~1..HEAD

а потім робити git push


14

Спробуйте скинути до потрібної фіксації -

git reset <COMMIT_ID>

(щоб перевірити використання COMMIT_ID git log)

Це поверне всі змінені файли до не доданого стану.

Тепер ви можете checkoutвидалити всі файли, не додані

git checkout .

Поставте прапорець, git logщоб підтвердити зміни.

ОНОВЛЕННЯ

Якщо у вас є одне і єдине зобов'язання у вашому репо, спробуйте

git update-ref -d HEAD


13

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

Спочатку потрібно видалити розробку з походження :

git push origin :develop (note the colon)

Тоді вам потрібно розвинутись до потрібного вам статусу, дозвольте припустити, що хеш фіксування є EFGHIJK:

git reset --hard EFGHIJK

Нарешті, натисніть на розвиток знову:

git push origin develop

13

Обережно! Ця команда може призвести до втрати історії комісій, якщо користувач помилково поставив помилку. Завжди у вас є додаткова резервна копія вашої git десь ще, на всякий випадок, якщо ви робите помилки, ніж ви трохи безпечніші. :)

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

Ось як я це зробив:

git reset --hard CommitId && git clean -f

Це повернеться до локального сховища, і тут після використання git push -fоновиться віддалене сховище.

git push -f

13

У GitKraken ви можете зробити це:

  1. Клацніть правою кнопкою миші на комісію, яку ви хочете скинути, виберіть: Скинути цю комісію / Hard :

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

  2. Клацніть правою кнопкою миші знову, виберіть: Поточна назва філії / Push :

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

  3. Клацніть на силовий натиск :

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

Зм. : Вам потрібно бути обережним, оскільки вся історія фіксування після жорсткого скидання втрачається, і ця дія незворотна. Ви повинні бути впевнені, що робите.


11

Якщо ви хочете виправити помилку в останньому фіксації, хорошою альтернативою буде використання git commit --amend . Якщо остання фіксація не вказана жодним посиланням, це зробить трюк, оскільки створить команду з тим же батьків, що і остання. Якщо немає посилання на останнє зобов’язання, воно буде просто відкинуто, і це зобов’язання буде останнім. Це хороший спосіб виправлення комісій без повернення комітетів. Однак це має свої обмеження.

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