файл - git удалить коммит из середины




Как вернуть репозиторий Git в предыдущую фиксацию (20)

Внимание! Эта команда может привести к потере истории фиксации, если пользователь ошибочно допустил ошибку. Всегда имейте дополнительную резервную копию своего git где-то еще на всякий случай, если вы ошибаетесь, чем вам немного безопаснее. :)

У меня была аналогичная проблема, и я хотел вернуться к предыдущему Commit. В моем случае я не был настроен на то, чтобы сохранить более новую фиксацию, поэтому я использовал Hard.

Вот как я это сделал:

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

Это будет возвращено в локальный репозиторий, здесь после использования git push -fбудет обновлять удаленный репозиторий.

git push -f

Как я могу вернуться из текущего состояния в моментальный снимок, сделанный на определенной фиксации?

Если я делаю git log , то я получаю следующий вывод:

$ git log
commit a867b4af366350be2e7c21b8de9cc6504678a61b`
Author: Me <[email protected]>
Date:   Thu Nov 4 18:59:41 2010 -0400

blah blah blah...

commit 25eee4caef46ae64aa08e8ab3f988bc917ee1ce4
Author: Me <[email protected]>
Date:   Thu Nov 4 05:13:39 2010 -0400

more blah blah blah...

commit 0766c053c0ea2035e90f504928f8df3c9363b8bd
Author: Me <[email protected]>
Date:   Thu Nov 4 00:55:06 2010 -0400

And yet more blah blah...

commit 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Author: Me <[email protected]>
Date:   Wed Nov 3 23:56:08 2010 -0400

Yep, more blah blah.

Как вернуться к фиксации с 3 ноября, т.е. зафиксировать 0d1d7fc ?


Дополнительные альтернативы решениям Jefromi

Решения 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 [email protected]{1}

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

Это в основном работает, используя тот факт, что мягкие сбросы оставят состояние предыдущей фиксации, поставленной в области index / staging-area, которую вы затем можете зафиксировать.

Альтернатива 2: Удалить текущее дерево и заменить его новым

Это решение исходит из решения svick для Checkout old commit и делает его новой фиксацией :

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

Аналогично альтернативу # 1, это воспроизводит состояние <commit> в текущей рабочей копии. Необходимо сначала выполнить git rm потому что git checkout не будет удалять файлы, которые были добавлены с <commit> .


Возврат рабочей копии к последней фиксации

Чтобы вернуться к предыдущему фиксации, игнорируя любые изменения:

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 [email protected]{1}

git commit -m "Revert to 56e05fced"

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

Кредиты идут к аналогичному вопросу переполнения стека, возвращаются к фиксации SHA-хешем в Git? ,


Revert - команда отката коммитов.

git revert <commit1> <commit2> 

Образец:

git revert 2h3h23233

Он способен принимать диапазон от HEAD, как показано ниже. Здесь 1 говорит: «Вернуть последнее совершение».

git revert HEAD~1..HEAD

а затем сделать git push


Вот гораздо более простой способ вернуться к предыдущей фиксации (и иметь ее в неуправляемом состоянии, делать с ней все, что вам нравится):

git reset HEAD~1

Итак, нет необходимости в фиксации идентификаторов и т. Д. :)


Вы можете выполнить все эти начальные шаги самостоятельно и вернуться к 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 repo, используя git push --force чтобы принудительно нажать на изменение.

Если вы хотите, чтобы репозиторий git имел предыдущую фиксацию

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

Выберите требуемую фиксацию и проверьте ее

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

пока не получите требуемую фиксацию. Чтобы заставить HEAD указать на это, сделайте

git reset --hard HEAD~1

или git reset --hard HEAD~2 или что угодно.


Если вы хотите «разогнать», стереть последнее сообщение фиксации и поместить измененные файлы в очередь, вы должны использовать команду:

git reset --soft HEAD~1
  • --soft указывает, что незафиксированные файлы должны быть сохранены как рабочие файлы, противоположные --hard которые --hard бы их.
  • HEAD~1 - последняя фиксация. Если вы хотите откат 3 фиксации, вы можете использовать HEAD~3 . Если вы хотите откат к определенному номеру ревизии, вы также можете сделать это, используя свой SHA-хэш.

Это чрезвычайно полезная команда в ситуациях, когда вы совершили неправильную вещь, и хотите отменить это последнее коммит.

Источник: http://nakkaya.com/2009/09/24/git-delete-last-commit/


Лучшим вариантом для меня и, возможно, для других является опция сброса Git:

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

Это был лучший вариант для меня! Это просто, быстро и эффективно!

Примечание. Как упоминалось в комментариях, не делайте этого, если вы делитесь своим филиалом с другими людьми, у которых есть копии старых коммитов

Кроме того, из комментариев, если вы хотите использовать менее «простой» метод, вы можете использовать

git clean -i


Ничто здесь не работало для меня, кроме этой точной комбинации:

git reset --hard <commit_hash>
git push origin <branch_name> --force

Ключ здесь - это принудительное нажатие, никаких дополнительных сообщений о фиксации / фиксации и т. Д.


Предполагая, что вы говорите о хозяине и в соответствующем филиале (это говорит о том, что это может быть любая рабочая ветка, о которой вы беспокоитесь):

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

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

Я нашел ответ из сообщения в блоге. Удалите Git-ретрансляцию Git для конкретной фиксации .


Прежде чем ответить, давайте добавим немного фона, объяснив, что это за HEAD .

First of all what is HEAD?

HEAD - это просто ссылка на текущую фиксацию (последнюю) в текущей ветке. В любой момент времени может быть только один HEAD (исключая git worktree ).

Содержимое HEAD хранится внутри .git/HEAD и содержит 40 байтов SHA-1 текущего фиксации.

detached HEAD

Если вы не используете последнюю фиксацию - это означает, что HEAD указывает на предыдущую фиксацию в истории, она называется detached HEAD .

В командной строке это будет выглядеть так: SHA-1 вместо имени ветки, поскольку 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 к этой фиксации.

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

git reflog
git checkout [email protected]{...}

Это вернет вас к вашей желаемой фиксации

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 .


Существует команда (не часть ядра Git, но она находится в пакете git-extras ) специально для возврата и постановки старых коммитов:

git back

На странице руководства он также может быть использован как таковой:

# Remove the latest three commits
git back 3

Чтобы полностью очистить каталог кодера от некоторых случайных изменений, мы использовали:

git add -A .
git reset --hard HEAD

Просто git reset --hard HEAD избавится от модификаций, но он не избавится от «новых» файлов. В их случае они случайно перетащили важную папку где-нибудь случайную, и все эти файлы были обработаны Git, как новый, поэтому reset --hard не reset --hard ее. git add -A . заблаговременно он явно отслеживал их всех с помощью git, которые были уничтожены сбросом.


Это сильно зависит от того, что вы подразумеваете под «revert».

Временно переключитесь на другую фиксацию

Если вы хотите временно вернуться к нему, обмануть себя, а затем вернуться туда, где вы находитесь, все, что вам нужно сделать, это проверить желаемую фиксацию:

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

git-revert manpage действительно покрывает много этого в описании. Еще одна полезная ссылка - это раздел git-scm.com, в котором обсуждается git-revert .

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

Вы также можете найти этот ответ полезным в этом случае:
Как переместить HEAD обратно в предыдущее место? (Отдельная головка)


Я пробовал много способов отменить локальные изменения в Git, и кажется, что это работает лучше всего, если вы просто хотите вернуться к последнему состоянию фиксации.

git add . && git checkout master -f

Краткое описание:

  • Он не будет создавать никаких коммитов, как git revert .
  • Он НЕ отделяет ваш HEAD, как git checkout <commithashcode> .
  • Он будет отменять все ваши локальные изменения и УДАЛИТЬ все добавленные файлы с момента последнего фиксации в ветке.
  • Он работает только с именами филиалов, поэтому вы можете вернуться только к последнему фиксации в ветке таким образом.

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

git add . && git reset --hard HEAD

где HEAD указывает на последнюю фиксацию в вашей текущей ветке.

Это тот же код, что и boulder_ruby, но я добавил git add . до git reset --hard HEAD чтобы стереть все новые файлы, созданные с момента последнего коммита, так как это то, что большинство людей ожидают, когда вернусь к последней фиксации.


Хорошо, возврат к предыдущей фиксации в git довольно прост ...

Верните назад, не сохраняя изменений:

git reset --hard <commit>

Верните назад с сохранением изменений:

git reset --soft <commit>

Объясните: с помощью сброса git вы можете выполнить сброс до определенного состояния, обычно это используется с хешем фиксации, как вы видите выше.

Но, как вы видите, разница заключается в использовании двух флагов --soft и --hard , по умолчанию git reset с использованием флага --soft , но это хорошая практика, всегда использующая флаг, я объясняю все флаги:

--мягкий

Флаг по умолчанию, как было объяснено, не нужно его предоставлять, не меняет рабочего дерева, а добавляет все файлы изменений, готовые к фиксации, поэтому вы возвращаетесь к статусу фиксации, который изменяется на файлы, не выполняются.

--жесткий

Будьте осторожны с этим флагом, он сбрасывает рабочее дерево и все изменения в отслеживаемые файлы, и все не будет!

Я также создал изображение ниже, которое может произойти в реальной жизни, работающей с git:


Для отката (или возврата):

  1. git revert --no-commit «commit-code-to-remove» HEAD (например, git revert --no-commit d57a39d HEAD)
  2. git commit
  3. git push

Попробуйте выполнить два шага, и если вы обнаружите, что это то, что вы хотите, тогда нажмите git.

Если вы обнаружите, что что-то не так:

git revert --bort


Если вы хотите исправить некоторую ошибку в последнем коммите, хорошей альтернативой будет использование команды git commit -amend . Если последняя фиксация не указана какой-либо ссылкой, это будет делать трюк, поскольку она создает фиксацию с тем же родителем, что и последняя фиксация. Если нет ссылки на последнюю фиксацию, она просто будет отброшена, и эта фиксация будет последней фиксацией. Это хороший способ исправления коммитов, не возвращая фиксации. Однако он имеет свои собственные ограничения.


Если ситуация является срочной , и вы просто хотите сделать то, что задавал вопрос быстро и грязно , если ваш проект находится под каталогом «мой проект»:

  1. Скопируйте весь каталог и назовите его чем-то другим, например «мой проект - копия»

  2. Делать:

    git reset --hard [first-4-letters&numbers-of-commit's-SHA]
    

Затем у вас есть две версии в вашей системе ... вы можете проверять или копировать или изменять файлы, представляющие интерес, или что-то еще, из предыдущего коммита. Вы можете полностью отказаться от файлов в разделе «Мой проект - копия», если вы решили, что новая работа никуда не годится ...

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

Git - это блестящее творение, но вы не можете просто «поднять его на лету»: также люди, которые пытаются объяснить это слишком часто, предполагают предварительное знание других VCS [систем контроля версий] и слишком далеко заходят слишком далеко, и совершать другие преступления, например, использовать взаимозаменяемые термины для «проверки» - способами, которые иногда кажутся почти рассчитанными, чтобы запутать новичка.

Чтобы сэкономить много внимания, вам нужно в значительной степени прочитать книгу о Git - я бы рекомендовал «Контроль версий с Git» . И если вы можете мне доверять (точнее, мои шрамы), когда я говорю «нужно», из этого следует, что вы могли бы также сделать это СЕЙЧАС . Большая часть сложности Git происходит от разветвления, а затем сжигает. Но из вашего вопроса нет причин, по которым люди должны ослеплять вас наукой .

Особенно, если, например, это отчаянная ситуация, и вы новичок в Git!

PS: Еще одна мысль: на самом деле довольно просто сохранить репозиторий Git («repo») в каталоге, отличном от того, в котором работают рабочие файлы. Это означало бы, что вам не пришлось бы копировать весь репозиторий Git, используя вышеупомянутое быстрое и грязное решение. Смотрите ответ на Фрайер с помощью --separate-ГИТ-реж here . Однако будьте осторожны : если у вас есть репозиторий «отдельный каталог», который вы не копируете, и вы выполняете жесткий сброс, все версии, следующие за фиксацией сброса, будут потеряны навсегда, если у вас нет, как вам абсолютно необходимо, регулярно резервирует ваш репозиторий, предпочтительно в облаке (например, на Google Диске ) среди других мест.







git-revert