Как отменить последний коммит и удалить его из истории? - PullRequest
47 голосов
/ 18 января 2012

Я сделал коммит и вернулся с

git revert HEAD^

просто git log

➜  git:(master) git log
commit 45a0b1371e4705c4f875141232d7a97351f0ed8b
Author: Daniel Palacio <danpal@gmail.com>
Date:   Tue Jan 17 16:32:15 2012 -0800

    Production explanation

Но если я сделаю git log - он все равно будет отображаться.Мне нужно удалить его из истории, поскольку он содержит конфиденциальную информацию

git log --all
commit 5d44355080500ee6518f157c084f519da47b9391
Author: Daniel Palacio
Date:   Tue Jan 17 16:40:48 2012 -0800

    This commit has to be reset

commit 45a0b1371e4705c4f875141232d7a97351f0ed8b
Author: Daniel Palacio 
Date:   Tue Jan 17 16:32:15 2012 -0800

    Production explanation

Как мне также удалить коммит 5d44355080500ee6518f157c084f519da47b9391 из истории?

Ответы [ 5 ]

53 голосов
/ 18 января 2012

Прежде всего, git revert здесь неправильная команда.Это создает новый коммит, который возвращает старый.Это не то, что вы просите.Во-вторых, похоже, что вы хотите вернуть HEAD вместо HEAD^.

Если вы нигде не нажимали это, вы можете использовать git reset --hard HEAD^, чтобы выбросить последний коммит (это также отбрасываетлюбые незафиксированные изменения, поэтому убедитесь, что у вас нет того, что вы хотите сохранить).Предполагая, что вы в порядке с конфиденциальной информацией, присутствующей в вашей копии , и ни с кем другим, все готово.Вы можете продолжать работать, и последующее git push не будет подталкивать ваш плохой коммит.

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

git reflog expire --expire=now --expire-unreachable=now --all
git gc --prune=now

, хотя это следует делать только в том случае, если вам действительно необходимо это сделать.


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

35 голосов
/ 18 января 2012

Если вы не заботитесь о коммите, просто выполните:

git reset --hard HEAD~

, чтобы удалить коммит.

Если вы хотите, чтобы изменения были в рабочем каталоге, выполните:

git reset HEAD~

В зависимости от того, что вы сделали с git revert, вам может потребоваться изменить вышеуказанные команды.Revert создает новый коммит, который отменяет коммит, который вы хотели вернуть.Так что будет два коммита.Возможно, вам придется сделать HEAD~2, чтобы удалить их обоих.

Обратите внимание, что обычно возврат является более безопасным способом возврата изменений.Но здесь, поскольку вы хотите удалить конфиденциальные данные, наилучшим подходом является сброс.

8 голосов
/ 22 января 2016

Есть хорошее решение здесь . Чтобы удалить последний (верхний) коммит вы можете сделать

git push [remote] +[bad_commit]^:[branch]

где [bad_commit] - коммит, на который в данный момент указывает [ветвь], или если [ветвь] извлечена локально, вы также можете сделать

git reset HEAD^ --hard
git push [remote] -f
6 голосов
/ 18 января 2012

Если вы еще не выдвинули коммит, вы можете просто:

сбросить git --hard HEAD ~ 2

(HEAD ~ 2, чтобы удалить ваш первоначальный коммит и ваш "возврат")commit).

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

1 голос
/ 26 июля 2018

Вот простое рабочее решение, которое удаляет последний коммит из удаленного:

  1. клонируйте репо и найдите последний «хороший» коммит (.... c407)
$ git clone git@host:PROJ/myrepo.git 
$ cd myrepo 
$ git log --pretty=oneline

234987fed789de97232ababababcef3234958723 bad_commit
e4a2ec4a80ef63e1e2e694051d9eb3951b14c407 v4.3
2f116449144dbe46e7260d5dac2304803751b5c2 v4.2
  1. извлечение последнего хорошего коммита в новую временную ветку
$ git checkout e4a2ec4a80ef63e1e2e694051d9eb3951b14c407
$ git checkout -b temp_branch
  1. заменить удаленную ветвь (удалив и нажав временную)
git push origin --delete dev_branch
git push origin temp_branch:dev_branch
...