What is git push vs git backup?
Git push is a command that sends committed objects from your local repository to a remote server like GitHub, GitLab, or Bitbucket. It transfers only committed data on the branches you push. It does not transfer uncommitted changes, staged files, stashes, local-only branches, git hooks, reflog history, or files excluded by .gitignore (like .env files). A git backup, by contrast, captures the complete state of your local repository, including all five namespaces of uncommitted work: the index, working tree changes, untracked files, stashes, and in-progress operation state. The distinction matters because a remote is a collaboration tool, while a backup is a recovery tool. They solve different problems and leaving one out creates a gap most developers do not discover until a hardware failure.
Think of GitHub like a shared folder for your finished work. When you push, you are sending only the commits you have made. Anything you have not committed yet stays on your laptop and nowhere else.
- Work you have not committed yet
- Stashes (temporary saves you made mid-task)
- Local branches you have not pushed
- Your
.envfile with passwords and API keys - Git hooks you set up for your workflow
Everything. Committed work, work in progress, stashes, environment files. All captured automatically, without you having to remember to push.
A push is for sharing. A backup is for saving. They are not the same thing.
A git push is a partial state transfer. It serializes committed objects reachable from the specified refs and transmits them to the remote. Five namespaces are systematically excluded from this transfer:
- INDEX Staged but uncommitted changes
- WORKTREE Unstaged modifications
- UNTRACKED New files not yet added
- STASH refs/stash entries (dangling commits)
- OP_STATE In-progress merge, rebase, cherry-pick state
A git backup captures all five namespaces atomically. A git push captures none of them. This is the infrastructure gap this post addresses.
A remote is not a backup. Say it until you believe it.
The scenario you are ignoring
Your laptop dies. The SSD fails at 2am on a Tuesday. No warning. You had uncommitted changes across three repos. A stash you have been sitting on for a week. Environment variables you never backed up because they were in .gitignore where they belong.
No problem. You have GitHub.
Except GitHub is down. February 2026 alone had 37 incidents. Your repos are there, somewhere, on Microsoft's servers. You just cannot reach them. And even when you can, half of what you lost was never pushed in the first place.
This is not a hypothetical. This is what happens when you confuse a remote with a backup.
Your computer stops working. It could be a spilled drink, a failed hard drive, or a laptop that will not turn on. You stayed calm because you have been pushing to GitHub regularly.
- 3 hours of work you were about to commit
- A stash you saved mid-feature last Thursday
- Your entire
.envfile (passwords, API keys, configs) - A local branch with early experiments you were not ready to share
This is fixable with the right setup. GitHub is still useful. You just need one more layer that runs automatically and captures everything, not only what you remembered to push.
Single-point-of-failure analysis. A developer with a standard GitHub workflow has exactly one local copy and one partial remote copy. When the local machine fails, recovery depends entirely on what was pushed to the remote at failure time.
- Agent workspace state (mid-task context accumulated in working tree)
- CI environment configurations not committed to the repo
- Secrets and credentials in
.envfiles excluded by gitignore - In-flight rebase or merge operation state
- Any stash refs (not transmitted by push protocol)
GitHub had 37 incidents in February 2026. Even if the remote is intact, provider availability adds a second failure mode. A resilient recovery architecture requires a backup that is independent of GitHub's uptime and complete beyond what push transmits.
What "backup" actually means
The backup industry has had a standard answer for decades. It is called the 3-2-1 rule.
- 3 copies of your data. The original plus two backups.
- 2 different storage types. Your laptop SSD and a cloud bucket. Or a local NAS and an external drive. The point is that one failure mode does not take out both.
- 1 copy offsite. Somewhere physically separate from your machine, so that a fire, theft, or flood does not erase everything at once.
Now test GitHub against this rule. You have your laptop (copy one) and GitHub (copy two). That is two copies on two media. Seems close.
But the 3-2-1 rule assumes complete copies. GitHub does not have a complete copy. It has whatever you last pushed. If you have uncommitted work, unpushed branches, stashes, environment files, or work-in-progress code, GitHub has none of it. You have one and a half copies at best.
Backup experts have a simple rule called the 3-2-1 rule. It has worked for photographers, writers, and businesses for decades. Here is what it means for your code.
Your laptop is copy one. GitHub is copy two. You are missing copy three.
Your laptop SSD and a cloud bucket count as two different storage types. GitHub counts as one of them.
A fire, flood, or theft should not be able to erase everything at once. That offsite copy is what protects you.
The problem with using GitHub as your backup is that it only holds a partial copy. Anything you have not committed and pushed is missing. You have one and a half copies, not three complete ones.
The 3-2-1 rule is an infrastructure requirement, not a best practice. Three independent copies. Two different storage classes. One geographically separate. GitHub satisfies one of the three copies and partially satisfies the second storage class requirement.
| 3-2-1 Requirement | GitHub | Compliant Backup |
|---|---|---|
| 3 complete copies | Partial (push only) | Yes |
| 2 storage types | 1 of 2 | Yes |
| 1 offsite | Yes | Yes |
The critical compliance gap: GitHub's offsite copy is incomplete. The 3-2-1 rule requires complete copies. A partial push state does not satisfy the rule, even though it satisfies the "offsite" checkbox superficially.
What git push leaves behind
When you run git push, git sends your committed objects to the remote. That is it. Here is everything that stays behind on your local machine.
| What | Pushed to GitHub? | At risk? |
|---|---|---|
| Committed + pushed branches | Yes | No |
| Uncommitted changes (staged or unstaged) | No | Yes |
| Stashes | No | Yes |
| Local branches not yet pushed | No | Yes |
.env and gitignored files |
Never | Always |
| Work-in-progress (WIP commits) | Only if pushed | Usually |
| Git hooks | No | Yes |
| Reflog history | No | Yes |
Most developers have at least two or three of these sitting on their machine at any given time. Some have all of them. Every single one is invisible to GitHub.
Stashes are local only. They are not branches. They are not pushed. They are not backed up anywhere. When your disk dies, every stash dies with it.
When you push to GitHub, only your committed code goes up. Everything else stays on your laptop. Here is what that means in practice.
The code you are writing right now, before you commit it. If your laptop dies while you are mid-feature, this is gone. It was never on GitHub.
When you save unfinished work with git stash, those saves are local only. They do not go to GitHub. They do not get pushed. If your laptop dies, every stash is gone permanently.
API keys, database passwords, service tokens. These are in .env on purpose, kept off GitHub to stay safe. But that means they have no backup at all unless you create one.
If you started a branch and have not pushed it yet, GitHub does not know it exists. It only lives on your machine.
Risk matrix for what a standard git push leaves unprotected on the local filesystem.
| Namespace | Git location | Push transmits? | Risk |
|---|---|---|---|
| Index | .git/index |
No | High |
| Working tree | Project files | No | High |
| Stash | refs/stash |
No | High |
| Untracked files | Filesystem only | Never | Always |
| Op state | .git/MERGE_HEAD etc |
No | Medium |
| Gitignored files | .env, secrets |
Never | Always |
refs/stash. The push protocol does not transmit dangling commits or local-only refs. There is no mechanism in standard git to push stashes to a remote. They are structurally local-only.
Five scenarios where GitHub fails you
1. GitHub has an outage
Between May 2025 and April 2026, GitHub logged 257 incidents with 48 major outages. GitHub Actions usage has grown from 500 million minutes per week in 2023 to 2.1 billion in early 2026, and infrastructure has not kept pace. The platform's own CTO admitted they initially planned for 10x scale but realized by early 2026 they needed to design for 30x.
During an outage, you cannot clone, pull, or push. If your machine is also dead, you have zero copies.
| Period | Total Incidents | Major Outages |
|---|---|---|
| 2023 (full year) | 94 | 22 |
| 2024 (full year) | ~120 | 26 |
| 2025 (full year) | ~180 | 36 |
| May 2025 - Apr 2026 | 257 | 48 |
The trend is going up, not down.
2. Your account gets compromised
In March 2026, a campaign called ForceMemo compromised hundreds of GitHub accounts through malicious VS Code and Cursor extensions. The malware harvested GitHub tokens and used them to force-push malicious code into every repository the victim owned. Hundreds of Python repos were injected with malware before anyone noticed.
Earlier, the Gitloker extortion campaign took a different approach. Attackers compromised accounts, wiped repository contents, renamed repos, and left a ransom note as the README. Pay up or lose your code.
If an attacker has your GitHub token, they can delete every repo you own. GitHub might be able to restore it. They might not. Their terms say they will make "a reasonable effort" to provide a copy within 90 days. Reasonable effort is not the same as a guarantee.
3. Accidental force push
Someone on your team runs git push --force to the wrong branch. The remote history is rewritten. The commits you were depending on are gone from GitHub. If your local copy still has them, you can recover. If your local copy is also gone, those commits are permanently lost.
This happens more often than anyone admits. GitHub community forums are full of developers asking how to recover from accidental force pushes. Some recover. Many do not.
4. Terms of Service violation
GitHub can suspend your account at any time for a Terms of Service violation. The suspension can happen "with or without notice," according to their own terms. In 2025 alone, GitHub processed 2,661 DMCA deletion requests and removed 47,228 repositories.
Some of those were legitimate takedowns. Some were false positives. GitHub community forums include reports of developers locked out for weeks or months while resolving verification issues. During that time, every repo on the account was inaccessible.
GitHub does have a Developer Defense Fund. But legal processes take time. Your deadline does not wait for a dispute resolution.
5. GitHub changes or disappears
GitHub is owned by Microsoft. Microsoft has shut down products before. It is unlikely that GitHub goes away tomorrow. But "unlikely" is not "impossible," and building your entire backup strategy on the continuity of a single company is a bet, not a plan.
Terms change. Pricing changes. Free tiers shrink. A strategy that depends entirely on one provider's goodwill is not a strategy. It is a dependency.
GitHub is a company, not a guarantee. Here are five situations where having GitHub as your only copy is not enough.
257 incidents in one year. When GitHub is down, you cannot pull, push, or clone. If your laptop is also broken, you have no copies at all.
In 2026, hundreds of GitHub accounts were compromised through malicious editor extensions. Attackers wiped projects and left ransom notes. GitHub might restore it. They might not.
A force push rewrites history on the remote. If your local copy is gone and the remote history was overwritten, those commits are permanently lost.
GitHub suspended 47,228 projects in 2025. Some were legitimate takedowns. Some were false positives. If your account is locked, you cannot access your projects until the dispute is resolved. That could take weeks.
GitHub is owned by Microsoft. Companies change, get acquired, shut down features, or change pricing. Building your entire safety plan on one company's promises is a bet, not a plan.
Five infrastructure failure modes. Each represents a distinct risk vector that a GitHub-only backup strategy does not mitigate.
257 incidents in 12 months. During degraded API access, git operations fail. Backup strategy requires independence from provider uptime. A local-encrypted backup on user-owned storage is unaffected by GitHub availability.
Malicious VS Code/Cursor extensions harvested GitHub tokens and executed force-push attacks across all repos the victim owned. An independent encrypted backup is unaffected by account-level credential compromise.
Force push rewrites remote ref targets. Original commit objects become unreachable from the remote. Without a backup that captured those objects before the rewrite, they are unrecoverable from GitHub.
47,228 repositories removed in 2025. Suspension locks access to all repos on the account. A backup stored on user-owned infrastructure remains accessible regardless of account status.
Free tier elimination, pricing changes, or product discontinuation are all within Microsoft's discretion. Vendor lock-in at the backup layer is a survivability risk for long-running projects.
What you actually lose
When developers say "I use GitHub as my backup," they usually mean they push regularly and feel safe. Here is a realistic picture of what a working developer has on their machine that GitHub does not have.
- 2-4 hours of uncommitted work on an average day. More on a deep focus day.
- 3-5 stashes from context-switching between tasks last week.
- 1-2 local branches for features not yet ready for review.
- Environment files with API keys, database credentials, and service configurations that took hours to set up correctly.
- Git hooks for linting, testing, and deployment that are not tracked in the repo.
- IDE configurations and local tooling that make the repo actually buildable on your machine.
A disk failure does not ask whether you committed. It does not wait for you to push. It takes everything.
Think about a typical Tuesday. You have been coding for a few hours. Here is a realistic picture of what is sitting on your laptop that GitHub does not have.
- 3 hours of code you are writing (not committed yet)
- 4 stashes from switching between tasks this week
- 1 local branch with experiments you are not ready to share
- Your entire
.envfile (API keys, database passwords, tokens) - Custom git hooks that make your workflow run smoothly
When your laptop stops working, it does not ask whether you remembered to commit. It takes all of it. The question is whether you have a copy somewhere else.
Quantified risk assessment for a standard development workday. These figures represent the expected unprotected state at any given failure boundary.
| Asset | Typical exposure | Recovery possible? |
|---|---|---|
| Uncommitted work | 2-4 hours per day | No |
| Stash entries | 3-5 per week | No |
| Unpushed branches | 1-2 active | No |
| Gitignored env files | Hours to reconstruct | Partial |
| Local hooks + tooling | 30-90 min setup | Partial |
Time-to-recovery with a GitHub-only strategy after total local failure: measured in hours to days. With a complete automated backup to user-owned storage: measured in minutes.
A remote is not a backup
A git remote is a collaboration tool. It lets multiple people work on the same codebase. It is designed for sharing, not for recovery.
A backup is a recovery tool. It is designed to restore your complete working state after a failure. Every file. Every change. Every secret. Back to the exact moment before things went wrong.
Here is the difference.
| Property | Git Remote (GitHub) | Real Backup |
|---|---|---|
| Captures uncommitted work | No | Yes |
| Captures stashes | No | Yes |
| Captures gitignored files | No | Yes |
| Captures all local branches | Only if pushed | Yes |
| Runs automatically | No (manual push) | Yes |
| Encrypted at rest | No (readable by provider) | Should be |
| Independent of provider uptime | No | Yes |
| Survives account compromise | No | Yes |
| Survives force push | No | Yes |
| Survives account suspension | No | Yes |
Ten properties. GitHub satisfies one. Maybe two if you are disciplined about pushing branches.
A remote is for sharing. A backup is for saving. They are built for completely different jobs.
Think of GitHub like a whiteboard in a shared office. It is great for collaborating. It is not where you keep the only copy of something important.
- Sharing code with teammates
- Reviewing pull requests
- Running CI/CD pipelines
- Hosting your committed history
- Save work you have not committed
- Run automatically without you pushing
- Encrypt your code so only you can read it
- Stay available when GitHub is down
- Survive if your account is compromised or suspended
GitHub does 1 out of 10 things a real backup needs to do. The good news is the other 9 are solvable.
Capability matrix comparing git remote semantics against backup system requirements. This is a compliance analysis, not a criticism of GitHub's design. GitHub is designed for collaboration, not recovery.
| Backup requirement | GitHub | Compliant backup |
|---|---|---|
| Captures all 5 git namespaces | No (1 of 5) | Yes |
| Automated scheduling | No | Yes |
| Encryption at rest (user-keyed) | No | Yes |
| Provider-independent availability | No | Yes |
| Survives account-level compromise | No | Yes |
| Survives force-push history rewrite | No | Yes |
| Captures gitignored secrets | Never | Yes |
| Verifiable restorability | No | Yes |
| User-owned storage | No | Yes |
| Compliance gap count | 9 of 9 | 0 of 9 |
GitHub satisfies zero of the nine backup system requirements. It satisfies many collaboration requirements. These are different product categories.
The fix
A real backup for code needs to do three things.
- Capture everything. Committed work, uncommitted changes, stashes, local branches, environment files. All of it. Automatically. Without waiting for you to remember to push.
- Encrypt before storing. Your code should not be readable by your storage provider. GitHub can read every file in your private repos. A subpoena, a breach, or an internal policy change is all it takes. Encryption means even if the storage is compromised, the data is useless without your key.
- Store independently. Your backup should not depend on the same provider, the same account, or the same infrastructure as your primary copy. If GitHub goes down, your backup should still be there. On your own storage. Under your own control.
This is what we built DevSafe to do.
Keep using GitHub. It is a great remote. It is a great collaboration tool. It is not a backup. Stop treating it like one.
The 3-2-1 rule for code: Your laptop is copy one. GitHub is copy two (partial). An encrypted, automated backup to your own storage is copy three. That is the one most developers are missing.
The good news: fixing this is straightforward. You need three things.
Not just committed code. Your work in progress, stashes, local branches, and environment files too. And it needs to run automatically, not just when you remember to push.
Your code should be scrambled before it goes anywhere. That way, even if the cloud storage is breached, no one can read your project without your key.
Your backup needs to be in a separate place that you control, independent of GitHub. That way if GitHub is down or your account has a problem, your backup is still there.
That is what DevSafe does. Keep using GitHub for collaboration. Add a real backup that runs automatically in the background.
Three infrastructure requirements for a compliant code backup system.
Index, working tree, untracked files, stash refs, and in-progress operation state. Automated scheduling. No manual intervention required. Agent workspace state must be captured between task boundaries.
Data must be encrypted on the local machine before transmission. Keys must not leave the machine. Storage provider must not have access to plaintext. This addresses both provider breach and subpoena risk.
S3-compatible bucket under the user's own credentials. No dependency on GitHub account status, GitHub availability, or GitHub's terms of service. Backup must be accessible when GitHub is not.
DevSafe implements all three requirements: complete state capture, AES-256-GCM encryption before egress, and user-owned S3-compatible storage. GitHub remains the collaboration layer. DevSafe is the recovery layer.
Frequently asked questions
Does git push back up everything in my repository?
No. Git push only sends committed objects on the current branch to the remote. It leaves behind uncommitted changes in your working directory, staged but uncommitted files, stashes, local-only branches, git hooks, .env files, and anything in .gitignore. If your laptop dies, all of that unpushed work is gone even though your remote is intact.
Is GitHub reliable enough to use as my only backup?
GitHub had 257 incidents in 12 months, including complete outages, degraded API access, and git operations failures. Even with perfect uptime, GitHub only stores what you have pushed. It is a collaboration tool and a remote, not a backup service. A real backup follows the 3-2-1 rule: three copies, two different storage types, one offsite.
What is the difference between a git remote and a backup?
A git remote stores pushed commits on a server you do not control. A backup is an independent, complete copy of your data stored on infrastructure you own, with automatic scheduling, encryption, and verified restorability. A remote requires you to remember to push. A backup runs automatically. A remote skips uncommitted work. A backup captures everything. A remote is controlled by a third party. A backup is yours.
Does pushing to GitHub save everything in my project?
No, and this surprises a lot of people. When you push, only your committed code goes up. Anything you have not committed yet stays on your laptop only. That includes your temporary saves (stashes), any branches you have not pushed, your environment file with passwords and API keys, and code you are actively writing. If your laptop breaks before you commit and push, that work is gone even though GitHub looks fine.
Can I count on GitHub to always be there when I need it?
GitHub is reliable most of the time, but it had 257 problems in one year, including periods where you could not push, pull, or access your projects at all. More importantly, even if GitHub is always available, it still only holds what you pushed. A real backup runs automatically and holds everything, not just what you remembered to send up.
What is the actual difference between GitHub and a backup?
GitHub is for sharing with teammates and storing your finished commits. A backup is for emergencies. It captures everything automatically, not just what you pushed. It encrypts your code so only you can read it. It stores everything on your own cloud storage, not a company that could go down or suspend your account. GitHub is a great collaboration tool. A backup is what protects you when things go wrong.
Does git push provide complete state capture for backup purposes?
No. The git push protocol transmits committed objects reachable from the specified refs. It excludes four of the five local git namespaces: the index, working tree, untracked files, and stash refs. It also excludes gitignored files such as environment configs and secrets. For agent-based workflows, this means any in-progress task state accumulated in the working tree between commits is not transmitted and is lost on local machine failure.
Is GitHub's availability sufficient for a production backup dependency?
No. 257 incidents in 12 months, including degraded git operations and complete API unavailability. Beyond availability, GitHub's backup value is bounded by what was last pushed. A resilient production backup architecture requires independence from GitHub's availability, account status, and terms of service. User-owned S3-compatible storage satisfies this independence requirement where GitHub does not.
What is the architectural difference between a git remote and a backup system?
A git remote is a collaboration synchronization endpoint. It receives push protocol payloads and stores the transmitted objects. A backup system is a recovery infrastructure component. It captures complete local state across all namespaces, encrypts before egress, stores on independent infrastructure, runs on automated scheduling, and provides verified restorability. These are different product categories with different design goals. GitHub satisfies zero of nine backup system requirements as analyzed in this post.