Как навсегда удалить несколько коммитов из удаленной ветки

Я знаю, что переписывание истории плохой йада-яда.

Но как навсегда удалить несколько коммитов из удаленной ветки?

Ответ 1

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

Этот SO-ответ иллюстрирует опасность такой команды, особенно если люди зависят от удаленной истории для своих локальных репозиториев.
Вы должны быть готовы указать людям на раздел ВОССТАНОВЛЕНИЕ ОТ UPSTREAM REBASE справочной страницы git rebase man page


В Git 2.23 (август 2019 года, девять лет спустя) вы будете использовать новую команду git switch.
То есть: git switch -C mybranch origin/mybranch~n
(замените n номером коммита для удаления)

Это восстановит индекс и рабочее дерево, как git reset --hard.

Ответ 2

Просто обратите внимание на использование last_working_commit_id при возврате нерабочего фиксации

git reset --hard <last_working_commit_id>

Поэтому мы не должны reset к commit_id, который мы не хотим.

Тогда, конечно, мы должны нажать на удаленную ветку:

git push --force

Ответ 3

Важное замечание: Убедитесь, что вы указали, какие ветки в "git push -f", или вы можете случайно изменить другие ветки! [*]

В этом руководстве показано три параметра. В случае разрыва ссылки я оставлю здесь основные шаги.

  1. Отменить полный коммит
  2. Удалить последний коммит
  3. Удалить коммит из списка

1 Вернуть полный коммит

git revert dd61ab23

2 Удалить последний коммит

git push <<remote>> +dd61ab23^:<<BRANCH_NAME_HERE>>

или, если ветка доступна локально

git reset HEAD^ --hard
git push <<remote>> -f

где +dd61... ваш хеш коммита, а git интерпретирует x ^ как родителя x, а + как принудительный не -f астрофизический толчок.

3 Удалить коммит из списка

git rebase -i dd61ab23^

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

git rebase --continue
git push <remote_repo> <remote_branch> -f

Ответ 4

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

Это лучше всего объяснить здесь.

Ответ 5

Упрощение от ответа pctroll, аналогично основанному на этом блоге.

# look up the commit id in git log or on github, e.g. 42480f3, then do
git checkout master
git checkout your_branch
git revert 42480f3
# a text editor will open, close it with ctrl+x (editor dependent)
git push origin your_branch
# or replace origin with your remote

Ответ 6

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

От вашей локальной ветки перехода:

git log

скопируйте хеш фиксации, чтобы вы хотели, чтобы ветка находилась и выходила из журнала git

git checkout theHashYouJustCopied
git checkout -b your_new_awesome_branch

Теперь у вас есть новая ветка, как вы этого хотите.

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

git checkout the_errant_branch
git log

Скопируйте хеш фиксации одного коммита, который вам нужно потянуть в хорошую ветку и выйти из журнала git.

git checkout your_new_awesome_branch
git cherry-pick theHashYouJustCopied

Похлопайте себя по спине.

Ответ 7

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

git reset --hard HEAD~3

Затем выполните следующую команду (на локальном компьютере), чтобы заставить удаленную ветвь переписать свою историю:

git push --force

Поздравляем! Все СДЕЛАНО!

Некоторые заметки:

Вы можете получить нужный идентификатор фиксации, запустив

git log

Затем вы можете заменить HEAD~N на <desired-commit-id> следующим образом:

git reset --hard <desired-commit-id>

Если вы хотите сохранить изменения в файловой системе и просто изменить индекс (историю фиксации), используйте флаг --soft, например git reset --soft HEAD~3. Затем у вас есть возможность проверить последние изменения и сохранить или удалить все или их часть. В последнем случае runnig git status показывает файлы, измененные с <desired-commit-id>. Если вы используете опцию --hard, git status скажет вам, что ваша локальная ветвь точно такая же, как и удаленная. Если вы не используете ни --hard, ни --soft, используется режим по умолчанию --mixed. В этом режиме git help reset говорит:

Сбрасывает индекс, но не рабочее дерево (т.е. измененные файлы сохраняется, но не помечается для фиксации) и сообщает о том, что не было обновлено.

Ответ 8

 git reset --soft commit_id
 git stash save "message"
 git reset --hard commit_id
 git stash apply stash [email protected]{0}
 git push --force