Я знаю, что переписывание истории плохой йада-яда.
Но как навсегда удалить несколько коммитов из удаленной ветки?
Я знаю, что переписывание истории плохой йада-яда.
Но как навсегда удалить несколько коммитов из удаленной ветки?
Вы 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
.
Просто обратите внимание на использование last_working_commit_id
при возврате нерабочего фиксации
git reset --hard <last_working_commit_id>
Поэтому мы не должны reset к commit_id
, который мы не хотим.
Тогда, конечно, мы должны нажать на удаленную ветку:
git push --force
В этом руководстве показано три параметра. В случае разрыва ссылки я оставлю здесь основные шаги.
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
Это может быть слишком поздно и слишком поздно, но что мне помогло, так это круто звучащий "ядерный" вариант. В основном с помощью команды filter-branch
вы можете удалять файлы или изменять что-либо в большом количестве файлов на протяжении всей вашей истории git.
Это лучше всего объяснить здесь.
Упрощение от ответа 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
Иногда самый простой способ исправить эту проблему - создать новую ветку с того места, где вы знаете, что код хорош. Тогда вы можете оставить историю перелетных ветвей в одиночку, если вам понадобится вишня - выберите другие коммиты из нее позже. Это также гарантирует, что вы не потеряли историю фиксации.
От вашей локальной ветки перехода:
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
Похлопайте себя по спине.
Если вы хотите удалить, например, последний 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
говорит:
Сбрасывает индекс, но не рабочее дерево (т.е. измененные файлы сохраняется, но не помечается для фиксации) и сообщает о том, что не было обновлено.
git reset --soft commit_id
git stash save "message"
git reset --hard commit_id
git stash apply stash [email protected]{0}
git push --force