Git 101: The Push Command
After committing your changes, the Git push command is used to upload your changes to the server. As a result, your changes will be available to your team members, too.
Push to the corresponding remote branch
The most common use case will be to push to the corresponding remote branch. This means, that when you have a branch called "my-new-feature", you want to push to the remote branch called "my-new-feature". There are two possible scenarios:
- the corresponding remote branch already exists or
- the corresponding remote branch does not exist yet.
We will talk about these two cases now.
Push to an already existing remote branch
In case that the remote branch already exists you can push your changes directly. To do so, you can use the push command as follows:
Push to a non-existing remote branch
In case that the remote branch does not exist yet, and you are trying to use the above command, Git will let you know that the remote branch does not exist yet:
fatal: The current branch test has no upstream branch. To push the current branch and set the remote as upstream, use git push --set-upstream origin my-new-feature
You only have to follow the instructions mentioned by Git. The only thing you need to do is copying the mentioned command and executing it:
git push --set-upstream origin my-new-feature
You might know that the remote branch does not exist yet (I mean, you created the new branch locally, didn’t you?). You can shorten the above procedure by directly specifying the upstream branch by either using the mentioned solution by Git or by using the following command which is even a bit shorter:
git push -u origin my-new-feature
Pushing to another remote branch
It might happen that you want to push to another branch than the one you are currently working on. You can do this by using the push command as follows:
git push origin source_branch:target_branch
The command means "push the changes from local source_branch to origin target_branch".
A use case for this command could be that you worked on the branch feature1, finished the task by pushing to origin/feature1. You then start working on the next feature but forget to switch to a new branch. You do your stuff, commit them and then realize that you still are on feature1 instead of feature2. To push your changes from your local feature1 to origin/feature2, you can use the Git push command as follows:
git push origin feature1:feature2
When you are creating tags locally, they are not pushed to the origin by default. Instead, you have to be specific about your intention to push your locally created tags.
You can either push a specific tag, let’s say a tag called "v1.2", by using the following command:
git push origin v1.2
You can also push several tags at once by providing the –tags option to the push command:
git push origin --tags
Force pushing should be used carefully because by force pushing your changes, you can overwrite changes made by others. It should never be used on your main branches like master or development. Instead, you can use force pushing on your own branches.
When do you need to force push?
You will need to force push your changes when you changed your commit history which was already pushed to the remote branch. You could have done this by pushing to the remote branch, then deciding to use the Git reset command and adding your changes to a new commit.
Let’s assume that we have the following commits:
You will now use the Git reset command to soft reset your changes to commit C. This will lead to the commits D and E being deleted but the changes made being kept. The result is the following Git log:
Now, you will create a new commit D’ which will contain the changes which beforehand have been part of commit D and E:
Assuming that you pushed the initial scenario to the remote beforehand and want to push the new history, Git will complain
git push To some-git:some-user/some-repo.git ! [rejected] my-new-feature -> my-new-feature (non-fast-forward) error: failed to push some refs to 'git@some-git:some-user/some-repo.git' hint: Updates were rejected because the tip of your current branch is behind hint: its remote counterpart. Integrate the remote changes (e.g. hint: 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
What Git is telling you here is that your local branch is behind the remote branch. The local branch is on commit D’ whereas the remote branch is on commit E.
What you can do now to push your changes is force pushing as follows:
git push -f
How can force pushing overwrite changes made by others?
When you are on one of your main branches, you can easily overwrite commits by force pushing your changes. Let’s have a look at an example:
Let’s assume that you are on the master branch. You pulled from the master branch and therefore have the latest commits locally. You start working on your stuff, create commits and want to push. Meanwhile, someone else might have pushed some changes to the master branch. When you are force pushing now, you will overwrite the commits the other team member did meanwhile. This happens because you did not pull the latest changes before force pushing. You might say that you can pull before force pushing. But: What if you both push almost simultaneously? In case that the other team member pushes just slightly before you do: You would overwrite the changes the other team member made. In this scenario you would not even have a chance to pull the latest commits before pushing because both pushes happen at the same time.
Let’s have a closer look at this scenario. The initial history on master is as follows:
You and your team mate pull this latest state from the master so that you have this state locally. Both of you work on their stuff and create a commit each:
You created the commit D and your team member created the commit D’
Let’s assume that your team member pushes his changes to master. This will lead to master having commit D’ as the latest commit:
When you want to push your changes now, Git will complain with the above mentioned message because your local master branch is behind the remote master. When you are force pushing your changes now, the remote master branch will look as follows:
As you can see: The result is the commit of your team member being deleted because you overwrote it.
I hope you are not afraid of force pushing now. Instead, keep in mind what can happen when force pushing and to use it on your own branches, solely.
How to force push
You can force push your changes by using the Git push command with the -f flag:
git push -f
Deleting a remote branch
You might be surprised but the Git push command is also used to delete a remote branch. In case that we wanted to delete a remote branch called "featureXYZ", the command would look as follows:
git push origin :featureXYZ
git push -d origin featureXYZ
For full reference see the Git push documentation.