Как отменить коммит в idea
В чем разница между undo commit, revert commit и reset branch to commit?
Простой 1 комментарий
Там в меню твоей IDE есть ещё несколько методов откатить изменения.
Это же JetBrains? Все способы подробно описаны в справке, например вот как в IntelliJ IDEA
Reset удаляет все коммиты выше выбранного. Там предлагается четыре варианта этой команды. Отличия их в том, как поступить с изменениями в рабочем каталоге и в индексе.
Revert не удаляет коммит, а создаёт новый, который описывает действия необходимые для отмены выбранного коммита.
Undo позволяет отменить последний коммит. Но изменения коммита предлагает сохранить в новый changelist. Файлы в рабочем каталоге не изменятся и можно будет их подправить и заново закоммитить.
Drop — удобная команда для удаления произвольного коммита из середины истории. Под капотом там на самом деле выполняется интерактивный rebase, но в автоматическом режиме.
Revert Selected Changes напоминает Revert, но отменяет изменения отдельного файла, а не всего коммита. Эта команда доступна на Панели изменёных файлов.
Get позволяет вернуть любой файл к состоянию на определённый коммит в истории. Выберем файл любым удобным способом и контекстное меню Git | Show History покажет все коммиты, в которых изменялся данный файл. Кликнув на нужном коммите правой кнопкой увидим команду Get
Git: вернуться к предыдущему коммиту
В этой статье я покажу несколько способов отменить ваши коммиты, в зависимости от вашего варианта использования. Это сложная тема (которая относится ко многим темам Git в целом), поэтому убедитесь, что вы следуете инструкциям, которые лучше всего соответствуют вашим потребностям.
Удалить неопубликованные коммиты
Если вы еще не опубликовали свои коммиты в удаленном репозитории, таком как GitHub, вы можете по существу удалить предыдущие коммиты с помощью команды reset.
Команда reset имеет три различных параметра, два из которых мы опишем здесь:
Используя опцию —hard, все возвращается обратно к указанному коммиту. Это включает в себя ссылки на историю коммитов, промежуточный индекс и ваш рабочий каталог.
Это означает, что с помощью этой команды вы не только вернетесь к предыдущей фиксации, но и потеряете все рабочие изменения в процессе. Чтобы не потерять какие-либо рабочие изменения, вы можете использовать команды stash и stash pop:
Команда stash сохраняет ваши рабочие изменения (без каких-либо комитов или изменений в дереве), а затем stash pop возвращает их обратно.
Удаление опубликованных коммитов
Допустим, вы зафиксировали свой код, а затем отправили его в удаленный репозиторий. На этом этапе настоятельно рекомендуется не использовать что-то вроде git reset, поскольку вы переписываете историю.
Вместо этого рекомендуется использовать команду revert. Эта команда работает, отменяя изменения, которые были внесены в указанный коммит, создавая новый коммит и фактически не удаляя предыдущие коммиты. Это идеально для опубликованных изменений, потому что тогда реальная история репозитория сохраняется. Вот пример:
Допустим, в вашем репозитории есть текстовый файл со следующим содержанием
И вы изменяете его на:
Ваша история коммитов может выглядеть примерно так:
Если мы решили, что нам больше ненужно слово «awesome» в нашем тексте, но мы не хотим удалять коммит 676ec, мы можем использовать revert, чтобы отменить это изменение:
Получив приглашение ввести сообщение о коммите, мы теперь можем видеть в нашей истории коммитов, что фактически существует новый коммит:
В результате этого первый и третий коммиты представляют одно и то же состояние проекта. Коммит был отменен, и история не была потеряна.
Обратите внимание, что есть несколько других способов использовать эту команду, например, если вы хотите вернуть обратно 2 коммита, вы можете использовать:
Или, если вы хотите отменить много непостоянных коммитов, вы указываете их индивидуально:
Временно оформить предыдущий коммит
«Отмена фиксации» означает, что вы временно хотите вернуться к предыдущему состоянию в своем репозитории, но без внесения каких-либо реальных изменений в дерево. В этом случае вы, вероятно, просто захотите проверить фиксацию, что позволит вам вернуться к мастеру или любому другому состоянию, когда вы закончите:
Это изменит ваш рабочий каталог на содержимое этого коммита, а также на местоположение, на которое указывает HEAD, ни одно из которых не является необратимым. Любые изменения, которые вы делаете здесь, могут быть зафиксированы в ветке или сохранены для последующего использования.
Как отменить commit и не облажаться
Возьмем простую ситуацию: разработчик решает реализовать математические функции. Но на половине пути понимает, что данную задачу было бы хорошо декомпозировать, допустим, на две подзадачи:
Проверять будет проще да и тестировать. Но он уже начал ее реализовывать, коммиты уже созданы, и что же делать? Не переписывать же!
git revert
Работа кипит и осталось дело за малым — смерджить мастер с данными ветками.
И что же мы получили? Ни класса Arithmetic, ни класса Numerical!
А все дело в том, что команда git revert создает новый коммит с отменой изменений и не удаляет из истории коммиты. И в нашем случае после слияния веток получается 4 коммита:
То есть вариант с отменой изменений с помощью команды revert вышел нам боком.
git reset
git rebase
Есть еще одно решение — использовать команду git rebase для отмены изменений.
Вернемся к моменту создания двух веток numerical и arithmetic и выполним
Теперь на уровне каждого коммита, который мы хотим отменить заменим pick на drop. И тогда выбранные нами коммиты сбросятся из истории. Например в ветке numerical :
Тогда в истории у нас останутся только нужные нам коммиты.
Теперь при слиянии веток в master получим оба класса.
Данный метод рабочий, только при условии работы в частной ветке, но если эти манипуляции провести в общей ветке, то при публикации ( git push ) git сообщает, что ветка устарела, так как в ней отсутствуют коммиты и отменяет публикацию.
Чтобы не бороться с git, старайтесь декомпозировать задачи заранее, а то можете словить сюрприз. Сталкивались ли вы с такими ситуациям, и если да, то как выходили из них?
IntelliJ IDEA Changelists и Git Staging
Прежде чем мы начнем, важно знать, что как списки изменений IntelliJ IDEA, так и Git staging позволяют закоммитить часть файла, целый файл или несколько файлов в Git. То, как они этого достигают, немного отличается, но конечный результат тот же. Список изменений IntelliJ IDEA работает с понятием диапазона в вашем контенте. Все изменения в этом диапазоне будут частью коммита. Git staging использует стандартное для git понятие staging области (также известное как «index»).
Оба варианта: IntelliJ IDEA Changelists и Git Staging доступны из Commit окна инструментов. Из IntelliJ IDEA 2020.1 вы можете переключиться на использование этого немодального окна Commit с помощью ⌘, в macOS или Ctrl + Alt + S в Windows / Linux, чтобы отобразить Preferences/Settings. Оттуда введите commit и установите флажок «Use non-model commit interface». Вы также можете использовать ⌘⇧A (macOS) или Ctrl + Shift + A (Windows / Linux) для поиска действий и ввести «Commit». Затем вы можете получить к нему доступ, нажав ⌘0 в macOS или Alt+ 0 в Windows и Linux.
Наконец, прежде чем мы начнем сравнение, вы не можете использовать списки изменений IntelliJ IDEA и промежуточную область Git одновременно. Вы можете переключаться между ними, но не можете использовать их одновременно. Начнем с Changelists IntelliJ IDEA.
Что такое «Список изменений IntelliJ IDEA»?
До выпуска 2020.3 списки изменений IntelliJ IDEA были единственным способом закоммитить изменения в вашем репозитории Git.
Списки изменений IntelliJ IDEA предназначены не только для Git, они для любой поддерживаемой системы VCS, но в этом блоге мы сосредоточимся на Git, чтобы мы могли сравнить их с новой функциональностью Git staging.
Коммит всего файла
IntelliJ IDEA всегда предоставляет вам список изменений по умолчанию, и при изменении файла файл будет отображаться в списке изменений по умолчанию с флажком, который не установлен:
Оттуда, если вы хотите выбрать весь файл для коммита, вы можете установить флажок слева от имени файла:
Коммит части файла
В качестве альтернативы, если вы хотите закоммитить часть файла, а не весь, вы можете дважды щелкнуть по имени файла в Default Changelist (списке изменений по умолчанию), чтобы открыть представление diff. Это представление показывает последнюю известную версию Git слева, а вашу локальную копию справа с выделенными синим цветом изменениями, которую вы можете редактировать. Вы можете установить флажки рядом с каждым изменением кода, которое вы внесли справа, чтобы сказать, что вы хотите закоммитить изменения только в этом диапазоне, а не во всем файле.
Обратите внимание, что если вы выбираете только часть файла для коммита, как в этом примере, Default Changelist будет указывать, что файл будет частично закоммитен, с помощью линии внутри чекбокса рядом с именем файла в Default Changelist, как вы можете видеть выше.
Совет: Вы также можете использовать ⌘D или Ctrl + D, чтобы открыть представление diff из окна инструмента commit.
Отмена изменений
В представлении diff вы также можете отменить изменения индивидуально, используя стрелку >> на файле слева, чтобы отменить изменения в вашем локальном файле. В этом случае правая часть обновится, чтобы отразить ваши изменения. Если вы допустили ошибку, вы можете отменить изменение или использовать локальную историю, чтобы вернуть свои изменения.
Вы также можете откатить весь файл, щелкнув его правой кнопкой мыши и выбрав Rollback.
Несколько Changelists
Чтобы создать несколько списков изменений, вы можете щелкнуть правой кнопкой мыши на Default Changelist и выбрать «New Changelist»:
Перемещение изменений между списками изменений
Вы также можете перемещать файлы между списками изменений (Changelists). Вы можете переместить весь файл в новый список изменений и создать этот новый список изменений, если он еще не существует в рамках этого действия. Для этого вы можете щелкнуть правой кнопкой мыши файл в списке изменений в окне Commit и выбрать «Move to Another Changelist». Вам будет предложено выбрать список изменений, если он существует, или создать список изменений, если его нет. Когда вы создаете новый список изменений, вы можете дополнительно установить для него значение «Active». Это означает, что все будущие изменения будут назначены этому Changelist.
В этом примере все будущие изменения будут теперь назначены нашему списку изменений DateFormat, потому что мы установили его как «Активный» при его создании.
В диалоговом окне «New Changelist» есть флажок, который называется «Track context». Если вы работаете с задачами и контекстами и подключили IntelliJ IDEA к соответствующему стороннему приложению, вы можете использовать этот флажок, чтобы заставить IntelliJ IDEA управлять контекстом задачи.
Помимо перемещения целых файлов между списками изменений, вы также можете перемещать отдельные изменения в файле между списками изменений. Это особенно полезно, если вы работаете над изменениями, которые влияют на один файл, но вы хотите разделить коммиты по причинам, о которых мы говорили ранее. Для того, чтобы присвоить некоторые, но не все изменения в файле на другую группу изменений, щелкните правой кнопкой мыши на изменение в представлении diff в Your version на правой стороне. Затем вы можете выбрать «Move to another changelist». Вы также можете использовать клавиши ⇧⌘M в macOS или Alt + Shift + M в Windows и Linux.
Вы также можете перемещать изменения между списками изменений, используя цветные полосы в gutter:
Как сделать Changelist активным
Наконец, мы уже показали вам, как сделать новый список изменений активным, но стоит упомянуть, что IntelliJ IDEA необходимо знать, какой список изменений использовать для новых изменений; вам всегда нужен один активный список изменений. Вы можете выбрать, какой список изменений является активным, если у вас их несколько, щелкнув правой кнопкой мыши список изменений и выбрав «Set Active Changelist». Если вы не видите эту опцию, это потому, что выбранный вами Changelist уже является активным Changelist.
Когда вы коммитите какие-либо новые изменения, они по умолчанию будут помещены в ваш активный список изменений IntelliJ IDEA Changelist.
Коммит ваших изменений в Git
Теперь, когда у вас есть списки изменений IntelliJ IDEA и ваши изменения разделены так, как вы хотите, вы готовы закоммитить их в Git. Вы можете увидеть, что будет закоммитено в Git, в окне «Commit».
Когда вас это устраивает, вы можете использовать ⌘K в macOS или Ctrl + K в Windows и Linux, чтобы открыть окно Commit. Перед тем, как нажать «Commit», вам необходимо ввести комментарий к коммиту. После того, как вы это сделаете и нажмете Commit, чтобы закоммитить их в истории Git локально, IntelliJ IDEA выполнит две команды git:
git add
git commit
Это добавляет файлы и закоммитит их за один шаг в вашей локальной истории Git. Затем вы можете продолжить и отправить изменения в удаленный репозиторий, если хотите.
Что такое Git Staging?
Затем вы можете включить его:
Вы также можете включить Git staging из диалогового окна Settings/Preferences с помощью команд ⌘ в macOS или Ctrl + Alt + S, а затем введя git staging.
Папки Staged и Unstaged
С Git Staging вы увидите две папки, а не одну как в IntelliJ IDEA Changelist в окне Commit. Каждое изменение, которое вы вносите в свой файл, представляет собой разницу между вашим локальным файлом и HEAD. Папка Unstaged, где все ваши изменения будут появляться на начальном этапе. Чтобы включить изменения в следующий коммит, вам необходимо переместить его из Unstaged папки в Staged папки. Это означает, что IntelliJ IDEA выполняет команду git add для всех изменений в файле.
Git add изменяет содержимое файла в индексе (поэтапное содержимое). Если вы впоследствии измените контент внутри того же диапазона, он не будет закоммитен, пока не будет помещен в папку Staged. Вы можете использовать Staged область, чтобы изменить то, что будет закоммитено, независимо от любых изменений в локальных файлах. С помощью IntelliJ Changelists любое изменение внутри того же диапазона будет закоммитено.
Кроме того, вы можете добавить часть файла, дважды щелкнув файл в папке Unstaged и используя стрелки <> на Staged области слева:
Вы также можете откатить весь файл, выбрав его в области Unstaged и выбрав «Rollback» (или «Revert» до версии 2021.1»). Это откат файла до состояния в индексе, а не в HEAD.
Давайте посмотрим на эту функциональность в Staged области. Изменения в Staged области означают, что IntelliJ IDEA выполнила операцию git add для изменения файла.
Вы можете передумать и решить, что хотите отменить изменения (Unstage) файла целиком. Как при выполнении Staging для файла, вы можете перетащить его из Staged папки в Unstaged папку, нажав значок * — ** в дереве, или правой кнопкой мыши и выбрав «Unstage»:
Когда вы Unstage файл или часть файла, IntelliJ IDEA запускает команду git reset для изменения файла.
Вы также можете отменить изменение в файле, если вам нужно. Чтобы сделать это, вам нужно открыть в представлении diff файл, который содержит изменения, которые вы хотите убрать из папки Staged. Затем вы можете использовать стрелки >> в staged части слева, чтобы отменить изменение (Unstage). Это приведет к отмене этого конкретного изменения, и снова IntelliJ IDEA запустит команду Git, чтобы отразить изменение. Вы также можете ввести текст в редакторе, если хотите.
Staging и Unstaging отдельных изменений с помощью значков в Gutter
Вы также можете использовать значки Gutter в IntelliJ IDEA для внесения отдельных изменений.
Когда вы кликните на сплошную цветную панель, вы можете выбрать внесение изменений (Staging), панель изменит вид после добавления изменений. Нажав на панель в gutter, вы сможете отменить эти изменения.
Коммит изменений
Если Git Staging включен, ваша коммит будет состоять из изменений (различий), которые есть в вашей Staging папке. Если вас они устраивают, вы можете использовать команду ⌘K (macOS) или Ctrl + K (Windows / Linux) для открытия окна Commit. Затем вы можете ввести комментарий к коммиту и нажать Commit, чтобы закоммитить выбранные вами изменения в Git. Кроме того, вы можете использовать команду ⌘⏎ (macOS) или Ctrl + Enter (Windows / Linux), чтобы закоммитить изменения. После чего IntelliJ IDEA выполнит необходимые команды Git для выбранных вами изменений.
Затем вы можете продолжить и выполнить push изменений в удаленный репозиторий, если хотите.
Резюме
Вам решать, какой подход вы предпочитаете. Оба они позволяют достичь одного и того же результата немного по-разному.
Changelists фокусируется на диапазонах в вашем контенте, то есть любые изменения в этом диапазоне в вашем файле включаются в коммит.
Git Staging фокусируется на создании коммита моментального снимка staging области. Staged контент эффективно блокируется. Вы можете приступить к редактированию файла, даже если он был помещен в папку Staged; Staged контент не изменится. Это позволяет вам готовить коммиты поэтапно.
Undo changes in Git repository
Revert uncommitted changes
You can always undo the changes you’ve made locally before you commit them:
Unstage files
By default, IntelliJ IDEA uses the changelists concept where modified files are staged automatically.
If a file is already under version control and you do not want to commit it, you can:
Remove it from the commit: do not select it in the Changes area of the Commit tool window.
Also, by default IntelliJ IDEA suggests adding each newly created file under version control. You can change this behavior in Settings/Preferences | Version Control | Confirmation using When files are created and When files are deleted settings respectively.
Undo the last commit
IntelliJ IDEA allows you to undo the last commit in the current branch.
Open the Git tool window Alt+9 and switch to the Log tab.
Select the last commit in the current branch and choose Undo Commit from the context menu.
In the dialog that opens, select a changelist where the changes you are going to discard will be moved. You can either select an existing changelist from the Name list, or specify the name of a new changelist (the commit message is used by default).
Select the Set active option if you want to make the changelist with the changes you are about to discard the active changelist.
Select the Track context option if you want IntelliJ IDEA to remember your context and reload currently opened files in the editor when this changelist becomes active.
Revert a pushed commit
If you notice an error in a specific commit that has already been pushed, you can revert that commit. This operation results in a new commit that reverses the effect of the commit you want to undo. Thus, project history is preserved, as the original commit remains intact.
If you apply this action to multiple commits selected in the Log view, a separate commit will be created to revert each of them.
If the selected commit contains several files, and you only need to revert some of them, deselect the files you do not want to touch.
Click Commit to commit a changeset that reverts the changes to the selected files in this particular commit.
Revert selected changes
IntelliJ IDEA lets you undo selected changes from a pushed commit if this commit contains multiple files and you only need to revert some of them.
In the Log view select the commit containing the changes you want to discard.
In the Changed Files pane, right-click the file that you want to revert and select Revert Selected Changes from the context menu.
This results in a new commit that reverses the changes you want to undo.
Drop a commit
Unlike reverting a commit, which is reflected in the branch history, you can discard a pushed commit in the current branch without leaving any traces of the operation.
Select a commit you want to discard in the Log view and choose Drop Commit from the context menu.
Reset a branch to a specific commit
If you notice an error in a set of recent commits and want to redo that part, you can roll back your repository to a specific state. This is done by resetting the current branch HEAD to a specified commit (and optionally resetting the index and working tree if you prefer not to reflect the undo in the history).
Open the Version Control tool window Alt+9 and switch to the Log tab.
Select the commit that you want to move HEAD onto and select Reset Current Branch to Here from the context menu.
In the Git Reset dialog that opens, select how you want your working tree and the index to be updated and click Reset :
Soft : all changes from commits that were made after the selected commit will be staged (that means they will be moved to the Local Changes view so that you can review them and commit later if necessary).
Mixed : changes made after the selected commit will be preserved but will not be staged for commit.
Hard : all changes made after the selected commit will be discarded (both staged and committed).
Keep : committed changes made after the selected commit will be discarded, but local changes will be kept intact.
Get a previous revision of a file
If you need to revert a single file instead of discarding a whole commit that includes changes to several files, you can return to a particular version of that file:
Select the required file in any view (in the Project tool window, in the editor, in the Local Changes view, and so on).
Select Git | Show History from the main VCS menu or from the context menu of the selection. The History tab is added to the Git tool window showing the history for the selected file and allowing you to review and compare its revisions.
When you’ve identified the revision you want to roll back to, select it in the list and choose Get from the context menu.

