Питання Як повернути сховище Git до попередньої фіксації


Як повернутись із мого поточного стану до знімка, зробленого за певною фіксацією?

Якщо я це зробив 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?


6021
2017-11-06 16:58


походження


Пов'язані Як скасувати останню Git-копію?.
Ось дуже чіткий і ретельний пост про знищення речей в гіт, прямо з Гітуба. - Nobita
Пов'язані: Відкат до старого кодування Git у публічній репо. Зауважте, що це питання додає обмеження, що репо є загальнодоступним.
Я люблю git, але той факт, що є 35 відповідей на те, що повинно бути неймовірно простим, видає величезну проблему з git. Або це документи? - The Muffin Man


Відповіді:


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

Тимчасово переключіться на іншу фіксацію

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

# 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.

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

Скасувати опубліковане зобов'язання з новими зобов'язаннями

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

# 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

The git-revert сторінки насправді багато в чому охоплює його опис. Іншим корисним посиланням є цей розділ git-scm.com обговорює гіт-реверт.

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

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


7841
2017-11-06 17:04



@ Род коментар на git revert HEAD~3 як кращий wat щоб повернутися назад 3 є важливим збором. - New Alexandria
Не могли б ви написати ціле число? люблю: git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50 - Spoeken
@MathiasMadsenStav Так, ви, звичайно, можете вказати повноваження повного SHA1. Я використовував скорочені хеші, щоб зробити відповідь більш читабельною, і ви також схильні використовувати їх, якщо ви набираєте текст. Якщо ви копіюєте та вставляєте, використовуйте повний хеш. Побачити Визначення змін в man-git rev-parse для повного опису того, як ви можете називати себе. - Cascabel
Щоб повернутися до поточної команди, це команда 'git checkout master' - Xavier John
Ви можете використовувати git revert --no-commit hash1 hash2 ... і після цього просто здійснити кожне повернення в одному здійсненні git commit -m "Message" - Mirko Akov


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

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

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?.


1262
2017-08-21 06:19



Я це зробив, але потім я не зміг здійснити і натиснути на віддалений сховище. Я хочу конкретну старшу компанію, щоб стати головою ... - Lennon
Це означає, що ви вже підштовхнули вас до своїх зобов'язань, які ви хочете повернути. Це може створити багато проблем для людей, які перевірили ваш код та працювали над ним. Оскільки вони не можуть застосувати ваш крок гладко над своїми. У такому випадку краще зробити зворотний зв'язок. Якщо ви єдиний, хто використовує репо. Зробіть git push-f (але подумайте двічі, перш ніж це зробити) - vinothkr
Обов'язкове попередження: не важко скинути якщо ви ділитесь своєю філією з іншими людьми, котрі мають копії старих команд, тому що за допомогою жорсткого скидання, як це буде змусити їх повторно синхронізувати свою роботу з новою гілкою скидання. М'який скидання є безпечним, як і останніми рішеннями в ця відповідь.
Я також хотів би зазначити, що для альтернативного рішення для м'якого скидання, а не першого змішаного скидання та жорсткого скидання, можна спочатку зробити жорсткий скидання наступним чином: git reset --hard 56e05fc; git reset --soft HEAD@{1}; git commit.
@nuton linus pauling себе, творець git, критикував його для того, щоб бути надто складним. Він записує, що він "шокований" гіт став настільки популярним, з огляду на його складність - boulder_ruby


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

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

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

(The --no-commit прапор дозволить git повернути всі дії одночасно - інакше вам буде запропоновано повідомлення про кожну фіксацію в діапазоні, засипання вашої історії непотрібними новими зобов'язаннями.)

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


1221
2018-02-12 04:18



Якщо ви дійсно хочете мати індивідуальні зобов'язання (замість того, щоб відновити все з однією великою фіксацією), то ви можете пройти --no-edit замість --no-commit, щоб вам не довелося редагувати повідомлення про порушення для кожної реверсії.
Якщо один з зобов'язань між 0766c053..HEAD є об'єднанням, то з'явиться повідомлення про помилку (для параметра не вказано -m). Це може допомогти тим, хто зіткнувся з цим: stackoverflow.com/questions/5970889/... - timhc22
Щоб побачити розбіжності, перш ніж виконувати використання git diff --cached. - John Erck
$ git revert --no-commit 53742ae..HEAD повертає fatal: empty commit set passed - Alex G
@ AlexG це тому, що вам потрібно ввести хеш один раніше що ти хочеш повернутися до. У моєму випадку хеші виглядали як: 81bcc9e HEAD{0}; e475924 HEAD{1}, ... (від git reflog), і я хотів відмовитися від того, що я зробив 81bcc9e, тоді я повинен був зробити git revert e475924..HEAD - EpicPandaForce


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

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

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


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

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

git clean -i 


153
2017-10-22 11:53



Обов'язкове попередження: не робіть цього якщо ви ділитесь своєю філією з іншими людьми, котрі мають копії старих команд, тому що за допомогою жорсткого скидання, як це буде змусити їх повторно синхронізувати свою роботу з новою гілкою скидання. Для рішення, яке детально пояснює, як безпечно здійснювати зворотний зв'язок, не втрачаючи роботу з жорстким скиданням, див. цю відповідь.
Я вдруге попередження @ Cupcake ... дуже добре знати про наслідки. Зауважте, однак, що якщо ваша потреба дійсно полягає в тому, щоб ці зобов'язання зникли з історії назавжди, цей reset + clean method це зробить, і вам знадобиться сила натискайте модифіковані гілки на будь-які і всі пульти. - ashnazg
пам'ятайте, чистим буде видаляти файли / папки, такі як .idea (phpstorm) або .vagrant (бродяга), які можуть бути використані вашим налаштуванням / IDE! - timhc22
git clean -f ОБЕРЕЖНО ОПАСНОСТІ - Tisch
@Pogrindis - тут багато хороших відповідей, які не видаляють невідслідувані файли. - Tisch


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

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

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

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


103
2018-03-04 17:25



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


Перед тим, як відповісти, давайте додамо деякий фон, пояснивши це HEAD є

First of all what is HEAD?

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

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


detached HEAD

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

Enter image description here

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

Enter image description here


Кілька способів відновлення після від'єднання 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 і, перевіряючи бажаний параметр reflog, встановить HEAD повернутися до цього зобов'язання.

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

git reflog
git checkout HEAD@{...}

Це допоможе вам повернутись до потрібної вам репутації

Enter image description here


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.

Enter image description here


102
2018-02-05 21:56



Відмінний натяк на git reflog, це саме те, що мені потрібно - smac89
Ой! Це все виглядає жахливо складним ... чи немає простої команди, яка просто поверне вас у процесі? Як вернутися з версії 1.1 у ваш проект назад до версії 1.0? Я очікую щось подібне: git stepback_one_commit або щось .... - Kokodoko
існує: git reset HEAD^ --хорошо` - CodeWizard
@Кокодоко Так, це жахливо складно ... і прекрасний приклад того, наскільки мало уваги експерти для тих, хто тільки починає свою діяльність. Будь ласка, зверніться до моєї відповіді тут, а також до книги, яку я рекомендую в цьому. Gіt - НЕ щось, що ви можете просто інтуїтивно підібрати. І я можу бути абсолютно впевненим, CodeWizard цього не зробив. - mike rodent


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

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 щоб стерти всі нові файли, створені з часу останнього вчинення, оскільки це, що більшість людей очікує, я вірю, коли повертаюсь до останньої передачі.


96
2017-07-29 11:01