Git Push Force

Learn via video courses
Topics Covered

Overview

The git push command is used to push all the committed code changes from a local repository to a remote server, along with ensuring that the history of git changes on the remote server is not overwritten by any chance. But, there might arise the situation when it is required to overwrite the code changes of the remote history. This is where the concept of git push force comes into the picture. In this article, we will take a closer look at the need for force pushing and the ways to efficiently and safely use the concept of git force push in your daily git workflow.

Pre-requisites

Before moving on to the concept of pushing the committed code changes from the local repo to the remote repo, you should be aware of the concept of committing. A commit is one of the mainly used concepts in git, used to create a snapshot of a state of a repository at any particular point in time. This will help you to track and view the history of your git repository up to the point in time when that particular commit was created.

You can identify a commit with its unique commit id. Also, you can add a message to your commit that should demonstrate the details of that commit code changes. A commit also consists of a lot of additional data like the name of the author, and the timestamp on which the commit was created.

The git push command is used to push or upload the committed code changes from a local repository to the remote server. The command used to push changes is:

The git push command basically works by copying all the commits from your local repo on any specific branch and sending them to the remote branch on your remote server.

What Is Git Push Force?

As you know, the push command does not overwrite the previous code changes made in the history of git on a remote server. This is because git allows you to push the changes only if the history of commits on both the local branch and the remote branch of the repository is the same and up to date. It will not allow you to push if the commits on any end are ahead of another end.

However, there might arise conditions when you actually want to overwrite the commit history of the remote repo with the commit history of your local repo. Then, for this, we use the concept of force pushing. The command used to push is:

If you want to specify the remote name and the branch name, then you can do it with:

This --force option will override the constraint of fast forwarding in git and will align the changes of the local branch with the changes of the remote branch on the remote server. This flag will specifically tell and force git to push the changes anyway.

Note: The git push force command is considered very destructive and its use is highly discouraged by Git.

The following sections of this article explain when you can use the --force command to make the most of the situation.

When to Use the --force?

Despite the potential ramifications, there are still some situations where the use of the git push force command solves the problem and is considered the best option to apply.

Here are some of the common examples of when the need for git push force comes:

  1. After mistakenly pushing the sensitive information on the remote server.
  2. After squashing some of the commits that have been pushed to the remote.
  3. After performing a rebase operation on a branch locally in Git.

You might be thinking that you can even use the git commit --amend, git rebase, or git squash commands to overwrite the commits that have already been pushed, and in this way you can change the commit history on the remote, then why there is the need of this force pushing. The answer to this is that yes these commands can do our work but these commands actually do more than just changing the history of commits. They work by altering all the commits, and by creating new commits. Therefore, to override the constraint of fast forwarding and to align the commit history of the local and the remote branch. You need to enter the --force flag.

Example

Let's suppose two developers are working on the same branch. Now, consider that the first person has completed the work and has pushed the committed changes to the remote branch. Now, after some time when the second person completed the work, he saw that some of the changes have been already pushed by the first person, and to make the commit history clean, he rebased the changes and then force-pushed them. But, this will remove all the work done by the first person and the changes of the first person will be replaced by the changes of the second person.

Here, the mistake of the second person was that he forgot to git pull the changes to local and thus lost the commits of the first person because by using the --force command, forces you to push your changes regardless of the changes already there on the branch.

The --force option has a lesser-known cousin called --force-with-lease that allows you to push --force changes with the guarantee that you won't overwrite someone else's changes.

How a "Force Push" Works?

As mentioned above, Git normally only allows you to push changes if you have previously updated your local branch with the latest commits from your remote. So, you can transfer your own latest code commits to the remote server only if they are up to date.

The --force option of git push can be used to override the commit history on the remote and to forcefully overwrite them with your own commit history of local. This is a very dangerous process and should be only used when actually required.

Options

There are some options for the git push --force command:

  1. --force: The --force flag is added to the git push command and is responsible for overriding the commit history of the remote server with the commit history of the changes on your local.
  2. -u: The "-u" flag works when creating a reference to keep track of all branches that have pushed changes to the remote repository.
  3. origin: The origin option refers to the name of the remote and is used as an alias for the URL of the remote repository. It saves you from writing the entire HTTPS or SSH URL while pushing the changes to the remote repository.

Safety Rules

As we know that the git push --force -u origin command overwrites the commit history of the remote repository, so it's considered a dangerous command and is mainly not recommended when you are working on a repository that is shared. It will remove the commit history if someone pushed some new commits to the remote repository. Therefore, you should strictly follow these safety rules when using the git push force command.

  1. This command is not recommended when working on a repository shared between your colleagues.
  2. You can use the git revert command if you need to work on the mistake that may arise by force-pushing the changes onto the remote repository.
  3. The use of the --force-with-lease flag is considered better instead of the --force flag because if a colleague has made some changes to the commit history of the remote repository since the last pull request, then this flag will throw an error to prevent you from overwriting the new code changes made by them.

How to Deal with Destructive --force?

The --force command works like magic in some situations but its usage can also mess up a lot of things, so should be aware of how to actually deal with the destructive --force command.

Let's say you used this force command and made this mistake. Everyone's last work was lost because it was overwritten by the changes you made. Then, to resolve this, you can go to the terminal and go down the branch to the last good commit and fix this before actually pushing your changes. Now you can use --force to send this good commit back to the branch just above the bad branch. This way you can avoid this great damage.

Now consider another case where you are working on any feature branch, you have pulled some changes, made some code commits, completed the part of the feature, and pushed the code changes to the main repository. Then you combined the commits into one with the help of a git rebase --i command and pushed them again with push --force. But now, imagine that something bad happened and you want to restore the changes on your branch to the way it was before the rebase command. The beauty of Git is that it does not lose the data, so you can still use the former version of the code which was before the rebase command.

For this, you can use the git reflog command, which will print a detailed history of the repository. Whenever you modify your local repository, internally git always creates a log entry for that modification. The git reflog command will output these ref logs stored in the local Git repository. It stores all the actions that changed the status of a branch and other references in your local repository, including the switching and rebasing between the branches.

Whenever you want to restore a branch to an earlier version of it after entering the --forced command, follow this general restoration template:

If you want to avoid push --force altogether, cloud-based version control systems like GitHub and GitLab offer a very cool feature known as the Protected Branches. This will take care that no one can overwrite your code changes.

Conclusion

  • A commit is one of the mainly used concepts in git, used to create a snapshot of a state of a repository at any particular point in time.
  • The git push command is used to push all the committed code changes from a local repository to a remote server, along with ensuring that the previous git history changes on the remote server are not overwritten.
  • The command used to push changes from local to remote via a specific remote branch is: git push <remote_name> <branch_name>.
  • The --force flag is added to the git push command (git push --force) and is responsible for overriding the commit history of the remote server with the commit history of the changes on your local.
  • The git push force command is considered destructive and its use is highly discouraged by Git.
  • The origin option refers to the name of the remote and is used as an alias for your remote repository URL.
  • You can use the git revert command if you need to work on the mistake that may arise by force-pushing the changes onto the remote repository.
  • The --force option has a lesser-known cousin called the --force-with-lease option because it allows you to push --force changes with the guarantee that you won't overwrite someone else's changes.
  • The -u flag works when creating a reference to keep track of all branches that have pushed changes to the remote repository.
  • Git normally only allows you to push changes if you have previously updated your local branch with the latest commits from your remote.
  • So, you can transfer your own latest code commits to the remote server by using the push command only if they are up to date.
  • If you want to avoid pushing --force altogether, GitHub and GitLab provide us with a very cool feature known as Protected Branches. This will take care that no one can overwrite your code changes on the remote.