Git Reset

In Git, the reset command is used to move the current branch pointer to a previous commit, discarding commits in the process. This can be useful when you want to discard commits that have not been pushed to a shared repository, or when you want to permanently remove commits from the project history.

The reset command has three main options: --mixed, --soft, and --hard. These options determine how the command affects the commit history and the staging area:

  • --mixed (the default option) moves the branch pointer to the specified commit and resets the staging area to match. Any changes that have been made since the specified commit will remain in the working directory and can be staged or committed again.

  • --soft moves the branch pointer to the specified commit, but leaves the staging area and the working directory unchanged. This allows you to commit the changes again in a new commit.

  • --hard moves the branch pointer to the specified commit and discards all changes in the working directory and the staging area. This permanently destroys any changes made since the specified commit.

Here's an example of how to use reset to move the current branch to a previous commit and discard all changes made since that commit:

$ git reset --hard HEAD~1 

This will move the current branch to the commit before the most recent commit and discard any changes made in the most recent commit.

It's important to note that reset is a destructive command and should be used with caution, especially when working with shared repositories. Any commits that are discarded with reset will be permanently lost, and other contributors may have based their work on those commits. If you want to undo commits without destroying them, you can use the revert command instead.

Here are a few additional things to keep in mind when using the reset command:

  • The reset command operates on the current branch, so make sure you are on the correct branch before using it.

  • It's a good idea to create a new branch before using reset, in case you need to switch back to the original commits later. This way, you can easily switch between branches without losing any work.

  • The reset command does not delete commits permanently. Instead, it moves the branch pointer to a previous commit, making the discarded commits unreachable. However, the commits are still stored in the repository and can be retrieved using tools like git reflog.

  • If you have pushed commits to a shared repository, you should be careful when using reset, as other contributors may have based their work on the commits that you are discarding.

  • The reset command can be useful when you want to discard local commits and start fresh from a particular commit. However, if you want to preserve the commit history and just undo changes, you can use the revert command instead.

  • If you have pushed commits to a shared repository and want to discard them, you should use the revert command instead of reset. This will create new commits that undo the changes made in the original commits, preserving the commit history and making it easier for other contributors to understand the changes.

  • If you do need to use reset to discard commits that have been pushed to a shared repository, you should be aware that this will create a "divergent" history. This means that the repository history will diverge from the shared repository, and you will need to use the force push option when pushing your changes.

  • It's important to use caution when force pushing, as it can cause conflicts with other contributors and make it difficult to collaborate on the repository. It's generally a good idea to communicate with your team before force pushing to a shared repository, and to use revert instead whenever possible.

    To force push your changes, use the -f or --force option with the push command:

    $ git push -f origin mybranch 

    This will overwrite the shared repository history with your local repository history, discarding any commits that have been pushed to the shared repository but are not present in your local repository.