Как закончить возвращать коммит и как вернуть много коммитов
Это должно быть просто, но я не могу найти его в git-scm
,
Я делал много небольших коммитов на публичный проект, и вся моя работа плохая. Я хочу удалить все, что я сделал. Некоторые из них я только что совершил локально, некоторые из них подтолкнули к "Мастеру происхождения".
Первый коммит (неделю назад) bdbad86
... с самым последним существом e82401b
...
Я хочу просто убрать все это. Я пытался отменить один.
git status
# On branch master
# You are currently reverting commit e82401b.
# (all conflicts fixed: run "git revert --continue")
# (use "git revert --abort" to cancel the revert operation)
- Я не могу понять, как закончить это возвращение.
- Я не хочу делать каждый коммит в отдельности, я хочу уничтожить их все.
4 ответа
Здесь я предполагаю, что никто не вставлял коммиты между вашими работами, и что ваши плохие коммиты образуют непрерывный диапазон в истории репо. В противном случае вам придется усложниться. Давайте предположим, что ваша история выглядит так:
e82401b - (master, HEAD) My most recent private commit
...
bc2da37 - My first private commit
cf3a183 - (origin/master) My most recent bad public commit
...
292acf1 - My first bad public commit
82edb2a - The last good public commit
Первое, что мы хотим сделать, это сдуть коммиты, которые вы еще не обнародовали. Вы можете сделать это с помощью следующей команды (обратите внимание, что ваши изменения будут потеряны и должны рассматриваться как невосстановимые):
git reset --hard cf3a183
Эквивалентно (и более читабельно):
git reset--hard origin/master
Теперь ваша точка зрения на хранилище совпадает с точкой зрения в origin/master
, Теперь вы хотите отменить свои плохие публичные изменения и опубликовать их как отмененный коммит. Эти инструкции предназначены для создания отдельного возврата.
Ты можешь использовать git revert --no-commit a..b
отменить все коммиты, начиная с коммита после a
(обратите внимание!) и заканчивая, в том числе, коммитом b
, Возврат будет организован для вас, чтобы совершить. Итак, здесь мы бы сделали:
git revert --no-commit 82edb2a..HEAD
Или, что эквивалентно:
git revert --no-commit 292acf1^..HEAD
Вспоминая это HEAD
теперь указывает на то же место, что и origin/master
,
После запуска revert
Теперь у вас есть готовые изменения, готовые к фиксации, так что просто запустите git commit -m "Reverting those bad changes I accidentally pushed and made public"
,
Вместо бега
git revert --continue
Просто беги
git commit -m "commit message here"
Если это не сработает, убедитесь, что вы подготовили все файлы, участвующие в откате. Даже файлы, которые вы вернули, а затем отбросили, изменяются.
На этот вопрос уже дан правильный ответ, но я просто хочу обратиться к первому пункту вопроса оператора - я не могу понять, как закончить это возвращение . если вы тоже застряли в состоянии возврата, как и я, и пришли сюда в поисках ответа.
это может быть просто как
git revert --continue
. но только если вы отменяете некоторые изменения внутри файла. если вы застряли в состоянии возврата, это, скорее всего, потому, что вы пытаетесь отменить фиксацию, которая создала файл, и этот файл был изменен в любой из последующих коммитов.
взять пример:
1c40cd3 added fileB
4e06828 added fileA
faf29dd (origin/main, origin/HEAD, main) Merged in feature5 (pull request #13)
6e735e3 (origin/feature5, feature5) updated file.txt
fb51fca added file.txt
744ba74 Initial commit
теперь, если вы пытаетесь вернуться
fb51fca (added file.txt)
, он покажет вам что-то вроде:
$ git revert fb51fca
CONFLICT (modify/delete): file.txt deleted in parent of fb51fca (added file.txt) and modified in HEAD. Version HEAD of file.txt left in tree.
error: could not revert fb51fca... added file.txt
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git revert --continue".
hint: You can instead skip this commit with "git revert --skip".
hint: To abort and get back to the state before "git revert",
hint: run "git revert --abort".
$ git status
On branch feature6
You are currently reverting commit fb51fca.
(fix conflicts and run "git revert --continue")
(use "git revert --skip" to skip this patch)
(use "git revert --abort" to cancel the revert operation)
Unmerged paths:
(use "git restore --staged <file>..." to unstage)
(use "git add/rm <file>..." as appropriate to mark resolution)
deleted by them: file.txt
ты можешь ясно видеть
file.txt deleted in fb51fca (added file.txt) and modified in HEAD. Version HEAD of file.txt left in tree.
. теперь вы можете сделать
git add -A
а также
git commit ...
НО
то, что делает revert, возвращается в историю (в указанном коммите), удаляет изменения, которые были сделаны в этом коммите. и делает новый коммит. но проблема в том, что вы создали файл, теперь revert удаляет его. в конце концов, не осталось файла для подготовки, и, как вы знаете, git не допускает пустых каталогов или пустых коммитов.
но есть обходной путь для пустых коммитов. как предложил Райан, вы можете
сделатьgit commit -m "empty commit to escape revert" --allow-empty
. git revert, вероятно, не использует это
--allow-empty
флаг, и это, вероятно, причина, по которой он не может выполнить фиксацию, застревает в состоянии возврата.
в любом случае, если вы застряли в состоянии возврата, вы, вероятно, делаете что-то не так. пытаясь вернуть то, что не имеет смысла.
Вы можете установить репо на любой предыдущий коммит и все изменения после этого будут удалены.
git reset --hard
после этого, чтобы отправить его в github, используйте git push --force origin
посещение Как откатить (сбросить) репозиторий Git для определенного коммита?