Могу ли я удалить фиксацию git, но сохранить изменения

В одной из моих ветвей разработки я внес некоторые изменения в свою кодовую базу. Прежде чем я смог завершить функции, над которыми я работал, мне пришлось переключить текущую ветвь на мастер-диск, чтобы продемонстрировать некоторые функции. Но только с помощью мастера "git checkout" сохранились изменения, которые я также внес в мою ветвь разработки, тем самым нарушив некоторые функции в master. Так что я сделал, это зафиксировать изменения в моей ветке разработки с сообщением фиксации "временная фиксация", а затем мастер проверки для демонстрации.

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

Ответ 1

Это так просто:

git reset HEAD^

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

Обратите внимание, что другой вариант должен выполняться как обычно, а затем в следующей точке фиксации запускаться:

git commit --amend [-m … etc]

который вместо этого отредактирует последнюю фиксацию, имеющую тот же эффект, что и выше.

Обратите внимание, что это (как и почти каждый ответ git) может вызвать проблемы, если вы уже нажали плохую фиксацию на место, где кто-то еще мог ее вытащить. Попытайтесь избежать этого.

Ответ 2

Есть два способа справиться с этим. Что проще, зависит от вашей ситуации

Сброс

Если коммит, от которого вы хотите избавиться, был последним коммитом, и вы не сделали никакой дополнительной работы, вы можете просто использовать git-reset

git reset HEAD^

Возврат вашей ветки к коммиту как раз перед вашим текущим HEAD. Однако на самом деле это не меняет файлы в вашем рабочем дереве. В результате изменения, внесенные в этот коммит, отображаются как измененные - это похоже на команду "uncommit". На самом деле, у меня есть псевдоним, чтобы сделать это.

git config --global alias.uncommit 'reset HEAD^'

Затем вы можете просто использовать git uncommit в будущем для резервного копирования одного коммита.

давя

Раздавить коммит означает объединение двух или более коммитов в один. Я делаю это довольно часто. В вашем случае у вас зафиксирована функция с половинной готовностью, а затем вы завершите ее и снова передадите с правильным, постоянным сообщением о фиксации.

git rebase -i <ref>

Я говорю выше, потому что хочу прояснить, что это может быть любое количество коммитов назад. Запустите git log и найдите коммит, от которого вы хотите избавиться, скопируйте его SHA1 и используйте его вместо <ref>. Git переведет вас в интерактивный режим перебазирования. Он покажет все коммиты между вашим текущим состоянием и тем, что вы положили вместо <ref>. Так что если <ref> 10 коммитов назад, он покажет вам все 10 коммитов.

Перед каждым коммитом у него будет слово pick. Найдите коммит, от которого вы хотите избавиться, и измените его от pick до fixup или squash. Использование fixup просто отбрасывает сообщение, которое фиксирует сообщение, и объединяет изменения с его непосредственным предшественником в списке. Ключевое слово squash делает то же самое, но позволяет вам редактировать сообщение коммита вновь объединенного коммита.

Обратите внимание, что коммиты будут повторно зафиксированы в том порядке, в котором они отображаются в списке при выходе из редактора. Таким образом, если вы сделали временный коммит, затем выполнили другую работу в той же ветке и выполнили функцию в последующем коммите, то использование rebase позволит вам пересортировать коммиты и раздавить их.

ПРЕДУПРЕЖДЕНИЕ:

Перебазирование изменяет историю - НЕ делайте этого с любыми коммитами, которые вы уже поделились с другими разработчиками.

припрятать

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

git stash save 'some message'

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

Вы можете просмотреть свой список тайников с...

git stash list

Это покажет вам все ваши тайники, на каких ветвях они были сделаны, а также сообщение и в начале каждой строки, а также идентификатор этого тайника, который выглядит как этот [email protected]{#} где # - его позиция в массиве тайников,

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

git stash apply [email protected]{#}

Опять же, # это позиция в массиве тайников. Если тайник, который вы хотите восстановить, находится в позиции 0 то есть, если это был последний тайник. Затем вы можете просто запустить команду, не указывая положение stash, git будет предполагать, что вы имеете в виду последнее: git stash apply.

Так, например, если я нахожусь на неправильной ветке - я могу выполнить следующую последовательность команд.

git stash
git checkout <correct_branch>
git stash apply

В вашем случае вы перемещались по веткам немного больше, но та же идея все еще применима.

Надеюсь это поможет.

Ответ 3

Я думаю, что вы ищете это

git reset --soft HEAD~1

Он отменяет самый последний коммит, в то же время сохраняя изменения, внесенные в этот коммит, на стадии подготовки.

Ответ 4

Да, вы можете удалить свою фиксацию без удаления изменений:    git reset @~

Ответ 5

Для тех, кто использует zsh, вам придется использовать следующее:

git reset --soft HEAD\^

Объясняется здесь: https://github.com/robbyrussell/oh-my-zsh/issues/449

В случае, если URL становится мертвым, важная часть:

Побег ^ в вашей команде

Вы также можете использовать HEAD ~, чтобы вам не приходилось каждый раз избегать его.

Ответ 6

В моем случае я уже нажал на репо. Ой!

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

git revert -n <sha>

Таким образом, я смог сохранить изменения, которые мне были нужны, и отключить фиксацию, которая уже была нажата.

Ответ 7

Используя git 2.9 (точно 2.9.2.windows.1) git reset HEAD^ запрашивает больше; не уверен, что ожидается здесь. См. Ниже скриншот

введите описание изображения здесь

Нашел другое решение git reset HEAD~#numberOfCommits, в котором мы можем выбрать количество локальных коммитов, которые вы хотите использовать reset, сохранив ваши изменения. Следовательно, мы получаем возможность выбросить все локальные коммиты, а также ограниченное количество локальных коммитов.

Ниже приведены скриншоты, показывающие git reset HEAD~1 в действии: введите описание изображения здесь

введите описание изображения здесь

Ответ 8

Еще один способ сделать это.

Добавьте фиксацию вверху временной фиксации, а затем выполните:

git rebase -i

Слить две коммиты в одну (команда откроет текстовый файл с явными инструкциями, отредактирует его).

Ответ 9

git reset  HEAD^

HEAD - это ваш идентификатор фиксации

Ответ 10

Я использовал рабочий стол github и использовал пункт меню refvert last commit.. работал как шарм.

Ответ 11

Вы ищете либо git reset HEAD^ --soft либо git reset HEAD^ --mixed.

Есть три режима для команды сброса, как указано в документации:

git reset HEAD^ --soft

отменить git commit. Изменения все еще существуют в рабочем дереве (папка проекта) + индекс (--cached)

git reset HEAD^ --mixed

отменить git commit + git add. Изменения все еще существуют в рабочем дереве

git reset HEAD^ --hard

Как будто вы никогда не вносили эти изменения в кодовую базу. Изменения ушли из рабочего дерева.