What Does git push Actually Do?

What Does git push Actually Do?

A complete, no-assumptions walkthrough of the command that sends your code from your laptop to the rest of the world — what happens under the hood, when it succeeds, and why it sometimes refuses to run.

Imagine you keep a personal diary at home, and your best friend keeps an identical copy of that same diary at their house so the two of you can always compare notes. Every time you write a new page, your friend’s copy doesn’t magically update — you have to physically walk over and hand them the new pages. Git works almost exactly like this. Your computer holds a private diary called a “local repository,” and somewhere else — usually a service like GitHub, GitLab, or Bitbucket — there’s a matching diary called the “remote repository.” git push is the act of walking over and handing your friend the new pages. Nothing you write locally is visible to anyone else until you run this one command.

1What Is git push?

Before we go anywhere near the internals, let’s build a rock-solid definition in plain English.

The Simple Definition

git push is a command that uploads the commits you’ve made on your local machine to a remote repository, so that other people (or other machines, like a deployment server) can see and use your changes. A “commit” is simply a saved snapshot of your project at a specific point in time — think of it as a save file in a video game. Git tracks a whole chain of these save files, and git push is the mechanism that copies the new ones in that chain to a shared location.

Simple Analogy

Think of a shared Google Drive folder that only syncs when you manually click “Upload.” You can edit files on your own laptop all day long — rename them, delete paragraphs, add new ones — and none of that is visible to your teammates until you click that upload button. git push is that upload button for your code history.

Why This Command Exists

Git was designed to be a “distributed” version control system, which means every single developer has a full, independent copy of the entire project history on their own machine — not just the latest files, but every past version too. This is powerful because you can work completely offline: you can save progress, undo mistakes, and branch off into experiments without ever touching the internet. But it creates an obvious problem: if everyone’s copy lives in isolation, how does anyone ever combine their work? git push (and its counterpart, git pull) are the bridges that connect these isolated copies back together.

i
Key Idea

Making a commit and pushing a commit are two completely separate actions. Committing saves a snapshot on your own machine only. Pushing is the separate, deliberate step that shares that snapshot with everyone else.

2Local vs. Remote Repositories

To understand what gets pushed, we first need to understand where things live before and after the push.

On Your Machine

Local Repository

The full copy of the project living on your own laptop, inside a hidden folder Git creates for tracking history. You have complete control here and can experiment freely.

Somewhere Else

Remote Repository

A copy of the project hosted on a server — often GitHub, GitLab, or a company’s internal Git server — that acts as the shared meeting point for the whole team.

The Nickname

“origin”

By default, Git gives the remote repository the nickname origin the moment you clone a project, so you don’t have to type its full web address every time.

The Bookmark

Remote-Tracking Branch

A local bookmark (like origin/main) that records where the remote’s branch was, last time your machine checked in with it.

Every developer on a team has their own local repository, and all of those local repositories synchronize through one shared remote repository. This “hub and spoke” pattern means you never talk directly to a teammate’s laptop — you always go through the central remote. git push is one half of that synchronization: it sends your new commits up to the hub. git pull is the other half: it brings other people’s commits down from the hub into your own local copy.

graph LR
    A[Alice's Laptop
Local Repository] -- git push --> R[(Remote Repository
e.g. GitHub)] B[Bob's Laptop
Local Repository] -- git push --> R R -- git pull --> A R -- git pull --> B
FIG 1 — Every developer’s local repository connects to one shared remote. Push sends work up; pull brings work down.

3How git push Works Internally

Now let’s open the hood and see exactly what happens, step by step, when you type this command and hit enter.

1

Git figures out what’s new

Git compares your local branch (for example, main) against its stored bookmark for the remote branch (origin/main) and calculates exactly which commits exist locally but are missing on the remote.

2

Objects are packed for transfer

Every commit is really a bundle of underlying objects — snapshots of file content, folder structures, and the commit metadata itself. Git gathers only the objects the remote doesn’t already have and compresses them into a single package for an efficient upload.

3

The package is uploaded

That compressed package travels over the network (usually HTTPS or SSH) to the remote server, where the server’s own copy of Git unpacks and stores the new objects permanently.

4

The remote’s branch pointer moves

A branch in Git is really just a labeled pointer to a specific commit — nothing more. Once the objects are safely stored, the server updates its main pointer to point at your newest commit, officially making it “the latest version” for everyone.

5

Your local bookmark is refreshed

Finally, your local machine updates its own origin/main bookmark to match, so Git knows your local and remote branches are now in sync — until the next commit, that is.

Simple Analogy

Picture mailing a package. You don’t re-send everything you own — you only pack the new items since your last shipment (step 2). The courier delivers the box (step 3), the recipient unpacks it and places the items on their shelf (step 4), and you update your own shipping log to say “delivered” (step 5).

sequenceDiagram
    participant L as Local Repository
    participant R as Remote Repository (origin)
    L->>L: Compare local main vs origin/main
    L->>L: Package new commit objects
    L->>R: Upload packaged objects
    R->>R: Unpack and store objects
    R->>R: Move main pointer to new commit
    R-->>L: Confirm success
    L->>L: Update local origin/main bookmark
        
FIG 2 — The full lifecycle of a single git push, from comparison to confirmation.

4Branches, Refs, and What Actually Gets Pushed

git push always operates on branches, so understanding branches is essential to understanding push.

A branch is best understood as a movable sticky note attached to one commit in your project’s history. When you make a new commit while “on” a branch, Git simply slides that sticky note forward to point at the newest commit. When you run a plain git push, you are telling Git: “take whatever commit my current branch’s sticky note is pointing at, and move the matching sticky note on the remote to point at the same place.” Only the branch you’re currently on (and any commits it depends on) is affected — your other branches stay exactly where they were.

i
Terminology

These “sticky notes” are formally called refs in Git — short for references. A branch is a type of ref, and so is a tag. git push is, at its core, a tool for uploading refs and the commits behind them.

Tracking Relationships

The first time you push a brand-new local branch, Git doesn’t automatically know which remote branch it should update — you typically tell it once, and from then on the two branches are “linked” as a tracking pair. After that link exists, a plain git push with no extra arguments knows exactly where to send your work, because it remembers the relationship you set up.

5Fast-Forward vs. Non-Fast-Forward Pushes

This is the single most common source of confusion for beginners: why does git push sometimes just work, and other times get rejected?

The Fast-Forward Case (Success)

If the remote branch hasn’t moved at all since your local machine last checked in — meaning nobody else has pushed anything new — your new commits simply build directly on top of what the remote already has. Git can move the remote’s pointer forward in a straight line, like extending a train track. This is called a “fast-forward,” and it’s the smooth, no-conflict scenario.

The Non-Fast-Forward Case (Rejected)

If a teammate pushed their own commits to the same branch after you last synced, the remote’s history has now branched away from what your local machine expects. Git refuses to blindly overwrite that history, because doing so would silently erase your teammate’s work. Instead, it rejects the push and asks you to first bring down the missing commits (usually with git pull), reconcile the two histories on your own machine, and then push the combined result.

!
Common Misconception

A rejected push does not mean something is broken. It’s Git’s built-in safety net doing exactly its job — protecting the team’s shared history from being accidentally overwritten.

graph TD
    subgraph "Fast-Forward (allowed)"
    A1[Remote: C1 - C2] --> A2[Local adds C3] --> A3[Remote becomes: C1 - C2 - C3]
    end
    subgraph "Non-Fast-Forward (rejected)"
    B1[Remote: C1 - C2 - C4 by teammate] 
    B2[Local still expects: C1 - C2 - C3]
    B1 -.conflict.- B2
    end
        
FIG 3 — A fast-forward simply extends history in a straight line; a non-fast-forward means the two histories have already split.

6Common Options You’ll See Used with git push

git push accepts several options that change its default behavior. Here are the ones you’ll run into constantly, described conceptually.

Set the link

Set upstream

Used the first time you push a brand-new branch, to establish the tracking relationship described in Chapter 4 so future pushes don’t need extra arguments.

Everything at once

Push all branches

Instead of pushing just your current branch, this option uploads every local branch that has a matching tracking relationship with the remote.

Overwrite carefully

Force push

Skips the safety check from Chapter 5 and overwrites the remote branch’s history to exactly match your local branch, even if that erases someone else’s commits.

Overwrite safely

Force-with-lease

A safer version of force push that first checks whether the remote branch has changed since you last looked at it, refusing to overwrite work you haven’t seen.

Labels too

Push tags

By default, tags (often used to mark release versions) aren’t pushed automatically; this option uploads them alongside your commits.

Remove remotely

Delete a remote branch

Pushing an “empty” update to a specific branch name tells the remote to delete that branch entirely — useful for cleaning up after a feature is merged.

ANTI-PATTERN-01 Avoid
Problem

New developers, when their push gets rejected, sometimes reach straight for the force-push option to “make it go through.”

Why It’s Harmful

Force pushing overwrites the remote’s history with your own, which can permanently delete commits your teammates made — with no built-in undo on the server side.

Correct Approach

Pull the latest remote changes first, resolve any overlaps on your own machine, and only reach for a force push on branches you are certain nobody else is relying on, ideally using the safer “force-with-lease” variant.

7git push vs. git fetch vs. git pull

These three commands are the ones beginners mix up most often. Here’s how they actually differ.

CommandDirectionWhat It Does
git pushLocal → RemoteUploads your local commits so others can see them.
git fetchRemote → LocalDownloads other people’s commits into your local bookmarks, but does not touch your working files.
git pullRemote → LocalRuns a fetch and then automatically merges the downloaded commits into your current branch.

A useful way to remember this: git push is the only one of the three that sends information outward. The other two are both about bringing information inward, and they differ only in whether that new information is immediately blended into your working copy or simply stored on the side for you to review first.

8Advantages and Trade-offs

Like every tool, git push brings real benefits alongside a few sharp edges worth knowing about.

Advantages

  • Gives you full control over exactly when your work becomes visible to others.
  • Uploads only the new data since the last push, making it efficient even for large projects.
  • Comes with a built-in safety check that prevents accidental overwrites of teammates’ work.
  • Works over both HTTPS and SSH, fitting almost any network or security setup.
  • Can trigger automated workflows, such as tests or deployments, the moment it succeeds.

Disadvantages / Trade-offs

  • Rejected pushes can feel confusing to beginners who don’t yet understand fast-forwards.
  • Force pushing, if used carelessly, can permanently destroy shared history.
  • Requires network access and correctly configured authentication to succeed.
  • Pushing large binary files repeatedly can bloat the repository over time.

9Security Considerations

Since git push is the gateway from your machine to a shared server, it naturally touches on a few security concerns.

Authentication

Every push must prove who you are, typically through an SSH key pair or a personal access token rather than a plain password, so the remote server can confirm you’re allowed to write to the repository.

Branch Protection Rules

Hosted platforms let teams mark certain branches — most commonly the main production branch — as protected, blocking direct pushes and force pushes so that all changes must go through a reviewed pull request instead.

Secrets Accidentally Committed

Because push is irreversible in the sense that the data becomes visible to others (and possibly the public internet) the moment it succeeds, accidentally committing passwords or API keys and pushing them is a well-known real-world security incident category.

“A push is a one-way door — once teammates or the internet have seen a commit, assume it can never truly be un-seen.”

10Best Practices and Common Mistakes

A short, practical checklist that separates smooth teams from ones constantly fighting their own Git history.

Do

Pull before you push

Getting into the habit of syncing down first dramatically reduces the number of rejected, non-fast-forward pushes you’ll ever see.

Do

Push small, focused commits

Frequent, well-described pushes are far easier for teammates to review than one enormous push containing a week’s worth of tangled changes.

Avoid

Force pushing to shared branches

Reserve force pushes for your own private feature branches, never for branches other people are actively building on.

Avoid

Pushing untested code to production branches

Since a push can immediately trigger automated deployments, pushing broken code straight to a production branch can take a live system down.

11Real-World and Industry Examples

git push isn’t just an academic concept — it sits at the center of how modern software actually gets built and shipped.

100M+
repositories hosted on GitHub alone
1 cmd
to trigger a full CI/CD pipeline
2005
the year Git itself was created

Continuous Integration Pipelines

Companies like Netflix, Google, and countless startups configure their systems so that every push automatically kicks off a pipeline of automated tests, catching bugs within minutes of the code being shared.

Automatic Deployments

Platforms such as Vercel, Netlify, and Heroku are built around the idea that a push to a specific branch is the trigger for deploying a new version of a website or application straight to the internet.

Open-Source Collaboration

Massive open-source projects like the Linux kernel or React rely on thousands of contributors pushing to their own personal copies (forks) and then proposing that work back to the original project, all built on the same push mechanics covered in this post.

12Frequently Asked Questions

Q1Does git push send my entire project every single time?

No. Git is smart enough to calculate the difference between what the remote already has and what’s new on your machine, and only that difference is uploaded.

Q2What happens if my internet connection drops halfway through a push?

The push simply fails and the remote repository is left unchanged, because Git only finalizes the branch pointer move after all the data has arrived successfully. You can safely try again once you’re back online.

Q3Can I undo a push after it succeeds?

You can push a new commit that reverses the change, or in some cases force push over it, but you should treat a successful push as something others may have already seen, downloaded, or built upon.

Q4Is git push the same as “saving” my work?

No — “saving” your work locally happens when you make a commit. Pushing is the separate, later step of sharing those already-saved commits with a remote repository.

Q5Why did Git ask me to set an “upstream” the first time I pushed?

Because your brand-new branch didn’t yet have a matching branch on the remote to link to, so Git needed you to confirm where it should create one and track it going forward.

13Summary and Key Takeaways

git push is the command that turns your private, local commits into shared, visible history on a remote repository. Under the hood, it compares your branch against the remote’s last known position, packages up only the new objects, uploads them, and then moves the remote’s branch pointer forward to match. Understanding this mechanism — rather than memorizing the command as a magic incantation — is what turns confusing rejected pushes and force-push accidents into predictable, manageable events.

Key Takeaways

  • Commit ≠ Push — committing saves work locally; pushing shares it with others.
  • Branches are pointers — a push really just moves a labeled pointer forward to a new commit.
  • Only new data travels — Git uploads the difference, not the whole project, on every push.
  • Rejections are a safety feature — a non-fast-forward rejection protects teammates’ work, it isn’t an error to panic over.
  • Force pushing is powerful and risky — reserve it for your own private branches, and prefer the safer “force-with-lease” when you must use it.
  • Push is a trigger point — in modern teams, a single push can kick off automated tests and even live deployments.
  • It’s a one-way door — once pushed, assume the change is visible and potentially in use by others.