Коротко: случайный коммит в master легко исправить: переносим его на новую ветку через cherry-pick, а из master убираем через reset --hard.

Если вы случайно закоммитили и запушили в master, а работа должна была идти в отдельной ветке, — это легко исправить: переносим коммит на новую ветку через cherry-pick, а из master убираем его через reset --hard. Разберём по шагам.

Допустим, находясь на ветке master, мы уже сделали ненужный коммит:

Терминал: git commit и git push нового коммита в master, история git log до удаления

Что происходит на скриншоте:

  1. находясь на master, выполняем git status — проверяем, что изменений нет.

Чтобы пользоваться удобной командой git lg, заведите алиас:

git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --"
  1. вызываем git lg, чтобы просмотреть коммиты текущей ветки;
  2. видим, что на master всего 1 коммит;
  3. создаём файл 12.txt и коммитим его в master, воспроизводя кейс «случайно закоммитился в master»;
  4. снова вызываем git lg и видим уже 2 коммита — исходный плюс только что сделанный.

Теперь переносим коммит 0286b6f на другую ветку. Для этого:

  1. переключаемся на коммит, от которого хотим создать новую ветку (eace0c2 — тот, что шёл перед переносимым): git checkout eace0c2;
  2. создаём от него новую ветку develop: git checkout -b develop.

Терминал: git checkout в detached HEAD, создание ветки develop и git cherry-pick коммита

  1. находясь на develop, выполняем git cherry-pick 0286b6f — указав номер переносимого коммита;
  2. через git lg проверяем, что на develop теперь 2 коммита: базовый и подтянутый через cherry-pick;
  3. выполняем git push --set-upstream origin develop, чтобы запушить новую ветку;
  4. переключаемся на master: git checkout master;
  5. на master выполняем git reset --hard HEAD~1, стирая лишний коммит;
  6. git push -f — отправляем изменения в удалённый master.

Готово. Теперь коммит находится на ветке develop, а в master его нет.