Programming and IT

git push

Until you run git push, your commits exist only on your own disk. The command sends them to a remote repository and moves the branch pointer there — which is also why it is the command that most often refuses, when someone else got their work in first.

Updated
In this article

What goes to the server#

Git sends commits — the ones the server does not have yet — and the new position of the branch pointer. Uncommitted edits, files in your working directory and the contents of the index go nowhere: first git commit, then push.

The server accepts a change only if it continues the history it already has. That kind of continuation is called a fast-forward. If the server branch has moved ahead or your history was rewritten, Git stops and touches nothing — this is the main safeguard against losing other people's work.

Syntax and options#

git push <remote> <branch>

Most often the remote is called origin, and the branch is the current one. When a branch is linked to a server branch (its upstream), plain git push is enough.

Option What for
-u, --set-upstream push and link the branch to the server branch — needed once
--force-with-lease overwrite the server branch, but only if it has no commits you have not seen
-f, --force overwrite unconditionally; other people's work can disappear
--tags push tags, which an ordinary push does not send
--delete <branch> delete a branch on the server
-n, --dry-run show what would happen without changing anything

Example: the first push of a new branch#

git switch -c feature/login
git add login.py
git commit -m "Add login form"
git push -u origin feature/login
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 512 bytes | 512.00 KiB/s, done.
Total 5 (delta 2), reused 0 (delta 0)
To https://github.com/example/notes.git
 * [new branch]      feature/login -> feature/login
branch 'feature/login' set up to track 'origin/feature/login'.

Without -u, Git reminds you itself:

fatal: The current branch feature/login has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin feature/login

From then on, git push with no arguments is enough for this branch.

The non-fast-forward rejection#

The most common picture: while you were working, someone else's commit landed on the server branch.

To https://github.com/example/notes.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'https://github.com/example/notes.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally.

The note may say fetch first or non-fast-forward — the second appears when your history has diverged from the server's, for example after --amend or a rebase. The fix is the same: first get their work, then send yours.

git pull --rebase
git push

The rebase moves your commits on top of theirs, and the push becomes an ordinary fast-forward. Details are in the article on git pull. Never answer this rejection with --force: it wipes from the server exactly the commits that caused the rejection.

When you really do need to rewrite#

There are legitimate cases: you fixed the message of your last commit on a personal branch nobody else is looking at. Then instead of --force use its careful relative:

git push --force-with-lease origin feature/login

The option checks that the server branch is still where you last saw it. If someone else's commit has appeared, the push is rejected with stale info, and you investigate instead of overwriting. On a shared branch like main, do not rewrite history at all — the reasons are spelled out in git rebase.

How to take back what you pushed#

The commit is on the server and others have seen it — there is only one safe way:

git revert 9d31c07
git push

A new commit appears that cancels the effect of the old one. History stays continuous, and nobody's copy breaks.

A branch created by mistake is removed entirely:

git push origin --delete feature/login

And a tag pushed by accident goes with git push origin --delete v1.4. Remember that anything pushed to a shared server may already have been downloaded, and a secret that ended up in a commit counts as compromised whatever you do with the history: change the password or token, do not try to hide it. The other commands for talking to a server are in the cheat sheet.

Step-by-step plan

  1. Make sure everything is committedgit status: uncommitted edits do not go to the server.
  2. Get other people's workgit pull --rebase so your commits sit on top of the server's.
  3. Push with trackingThe first time git push -u origin branch, after that just git push.
  4. Read the server's replyA new branch line or a hash range means accepted; rejected means read the hint.
  5. Fix with a revert, not with forcegit revert for shared branches, --force-with-lease only for your own.

Start learning this in your own space

The plan goes into your repository: tick off stages, keep notes — the change history shows how far you have come.

Start the plan

Check yourself

1.First push of a new branch: which command both pushes it and links it to the server branch?

2.A push was rejected as non-fast-forward. What do you do first?

3.Why is --force-with-lease better than plain --force?

Sources

Was this helpful?

More articles

Programming and IT Git branches A Git branch is a movable pointer to a commit, not a copy of your files. That is why creating one costs nothing, and the git branch command is what you use to list, create, rename and delete branches. Programming and IT How to undo a commit The question "how do I undo a commit" actually hides four different ones: fix the last commit, take it back and redo it, erase several, or cancel an old commit in the middle of history. The answer depends above all on one thing — whether anyone besides you has seen that commit. Programming and IT git clone git clone takes an entire repository from a server — with all its history, branches and tags — and puts a copy into a new folder on your computer. It is how you start working on any existing project, yours or someone else's. Programming and IT How to create a repository from scratch A repository is your project folder plus a hidden `.git` folder that stores the whole history. One command creates it, but between that command and your first meaningful commit there are a few steps that are hard to redo later — the branch name, the list of ignored files and the link to a server. Programming and IT Python: strings A string in Python is an immutable sequence of characters. Almost all of its quirks follow from that: methods do not change a string but return a new one, and fast text building goes through join, not through adding strings in a loop. Below is the working minimum with examples and output. Programming and IT Python: decorators A decorator is a function that takes another function and returns a new one with extra behaviour. The `@` sign above a definition is just a shorthand for an assignment. Keep that in mind and the whole topic takes one evening.

More solutions