Programming

Git reset --hard and push to remote repository

25 September 2026 · 7 min read

Git reset --hard and push to remote repository

Version control is the backbone of modern software development, and Git stands as the undisputed king. Mastering Git commands empowers developers to collaborate seamlessly and manage their code efficiently. Among the many powerful tools Git offers, git reset –hard stands out for its ability to revert changes, often acting as a lifesaver in tricky situations. However, its power comes with a caveat: pushing changes after a hard reset requires careful consideration and a thorough understanding of its implications, especially when working with remote repositories.

Understanding Git Reset –hard

The git reset –hard command is a powerful tool that allows you to reset your local repository to a specific commit. It discards all uncommitted changes and resets the staging area and working directory to match the specified commit. Unlike a soft reset, which keeps changes in the staging area, or a mixed reset, which moves changes to the working directory, a hard reset completely removes them. Think of it as a “scorched earth” approach to reverting changes.

This command is invaluable when you need to completely undo local changes, such as after a failed experiment or when you’ve accidentally introduced bugs. It allows you to return to a known good state quickly and efficiently. However, it’s crucial to understand that any changes discarded by a hard reset are lost forever. Therefore, always double-check before executing this command.

For instance, imagine you’ve made significant changes to your project, but they’ve led to unexpected errors. Instead of painstakingly undoing each modification, you can use git reset –hard HEAD to revert to the last committed state, effectively wiping the slate clean.

The Dangers of Pushing After a Hard Reset

While git reset –hard is a useful tool, pushing to a remote repository after using it can be dangerous. This is because you’re essentially rewriting history, which can cause conflicts and confusion for collaborators if they’ve based their work on the commits you’ve discarded. Imagine your colleagues have already pulled the commits you’re about to erase – forcing a push after a hard reset will overwrite their local history, potentially leading to lost work and frustration.

In a collaborative environment, altering the shared history is generally frowned upon. It breaks the linear flow of development and makes it difficult to track changes effectively. If other developers have pulled those commits, pushing after a hard reset can create significant issues for them.

Consider a scenario where a team is working on a feature branch. One developer uses git reset –hard and then force-pushes. This action could overwrite the work of other developers who have already pulled from that branch, creating a chaotic situation.

Pushing Changes Safely After a Hard Reset

If you absolutely must push after a hard reset, proceed with extreme caution. The safest approach is to use git push –force-with-lease. This command will only push if the remote branch hasn’t been updated since your last fetch. It provides a safety net, preventing you from accidentally overwriting someone else’s work.

git push –force should be used as a last resort and only when you’re absolutely certain that no other developers have based their work on the commits you’re about to overwrite. It’s best to communicate with your team before using this command to avoid potential conflicts. Transparency and communication are key when dealing with potentially disruptive actions like force-pushing.

For example, if you’re working on a personal project or a private branch, using git push –force might be acceptable. However, in a shared environment, always prioritize git push –force-with-lease or coordinate with your team to avoid unintended consequences.

Alternatives to Hard Reset and Force Push

Often, there are better alternatives to using git reset –hard and force pushing. For instance, git revert creates a new commit that undoes the changes introduced by a specific commit, preserving the history and avoiding potential conflicts. This is generally a safer and more collaborative approach to reverting changes.

Another option is to create a new branch from the desired point in history and continue working from there. This preserves the original branch and its history, allowing you to experiment without affecting the main development line. This approach is particularly useful when you want to explore different solutions without disrupting the existing codebase.

For example, if you’ve made a series of commits that you want to undo, using git revert for each commit is a safer approach than git reset –hard followed by a force push. It keeps the history intact, making it easier for others to understand the evolution of the code.

  • Avoid using git reset –hard in shared branches.
  • Prefer git revert for undoing changes collaboratively.
  1. Commit your current changes before using git reset –hard.
  2. Identify the commit hash you want to reset to.
  3. Execute git reset –hard <commit_hash>.

“Every line of code is like a liability. The more code you have, the more you have to maintain. Clean and efficient version control is essential for managing this liability.” - Unknown

Featured Snippet: git reset –hard is a powerful but potentially destructive command. Use it cautiously, especially when working with remote repositories. Prefer safer alternatives like git revert when possible.

Learn More About GitGit Reset Documentation

Atlassian Git Tutorial

GitHub Blog: Undoing Changes with Git

[Infographic Placeholder]

Frequently Asked Questions

Q: What happens if I push after a hard reset and someone else has pulled the discarded commits?

A: This can create significant problems for your collaborators. Their local history will be out of sync with the remote repository, and they may lose work if they’re not careful. It’s best to avoid this situation entirely by using safer alternatives or communicating with your team.

Understanding the power and potential pitfalls of git reset –hard is crucial for any developer. By using this command responsibly and exploring safer alternatives, you can enhance your workflow and avoid disrupting your team’s progress. Prioritize communication and collaboration to ensure a smooth and efficient development process. Explore more advanced Git concepts to further refine your version control skills and contribute effectively to your projects. Consider investing in further training or exploring online resources to deepen your Git expertise. Mastering version control is an ongoing journey, and continuous learning is essential for staying ahead in the ever-evolving world of software development.

  • Git Rebase
  • Git Cherry-Pick

Question & Answer :
I had a repository that had some bad commits on it (D, E and F for this example).

A-B-C-D-E-F master and origin/master

I’ve modified the local repository specifically with a git reset --hard. I took a branch before the reset so now I have a repo that looks like:

A-B-C master \ D-E-F old_master A-B-C-D-E-F origin/master 

Now I needed some parts of those bad commits so I cherry picked the bits I needed and made some new commits so now I have the following locally:

A-B-C-G-H master \ D-E-F old_master 

Now I want to push this state of affairs to the remote repo. However, when I try to do a git push Git politely gives me the brush off:

$ git push origin +master:master --force Total 0 (delta 0), reused 0 (delta 0) error: denying non-fast forward refs/heads/master (you should pull first) To <a class="__cf_email__" data-cfemail="b8dfd1ccf8dfd1cc96ddc0d9d5c8d4dd96dbd7d5" href="/cdn-cgi/l/email-protection">[email protected]</a>:myrepo.git ! [remote rejected] master -> master (non-fast forward) error: failed to push some refs to '<a class="__cf_email__" data-cfemail="b1d6d8c5f1d6d8c59fd4c9d0dcc1ddd49fd2dedc" href="/cdn-cgi/l/email-protection">[email protected]</a>:myrepo.git' 

How do I get the remote repo to take the current state of the local repo?

If forcing a push doesn’t help (git push --force origin or git push --force origin master should be enough), it might mean that the remote server is refusing non fast-forward pushes, via either receive.denyNonFastForwards config variable (see git config manpage for description), or via an update/pre-receive hook.

With older Git you can work around that restriction by deleting git push origin :master (note the : before branch name) and then re-creating git push origin master given branch.

If you can’t change this, then the only solution would be instead of rewriting history to create a commit reverting changes in D-E-F:

A-B-C-D-E-F-[(D-E-F)^-1] master A-B-C-D-E-F origin/master