Git, GitHub & backups
Your code deserves a safety net. Git to version everything, GitHub to keep it safe and share it, and a real backup strategy so you never lose anything, even if the machine fries.
In this guide
Guide checked 3 months ago: some commands may have changed. Let us know if so.
In short
Before letting an agent write code, version everything with Git and push a copy to GitHub: every commit becomes a restore point, and the code survives the loss of the machine. The simplest way to link the mini-PC to GitHub is the GitHub CLI (gh auth login, SSH protocol), with a .gitignore written before the first commit so no secret ever gets pushed. For everything that isn't in Git (.env files, databases, configs), apply the 3-2-1 rule with restic, automate the backup and test a restore at least once.
Do this first: What is an AI agent?
You just laid down an agent that’s going to write code at full speed. Before it touches anything important, we install the safety net: Git, so every change is reversible, and GitHub, so your work lives somewhere other than this one little box. Because a mini-PC can fry, get stolen, or take one rm too many. Your code, though, must never disappear with it.
Why this is non-negotiable (especially with an agent)
A coding agent moves fast, and it’s confident in itself. Most of the time that’s great; sometimes it breaks something. Git turns that into a non-event:
- Every commit is a restore point. The agent broke everything?
git restoreorgit reset, and you’re back to the previous state in a second. It’s the ultimate “undo.” - You see exactly what changed.
git diffshows you, line by line, what the agent touched. You review before approving, that’s the heart of the craft (see Securing access). - GitHub puts your code out of reach of disasters. Dead disk, theft, fat-fingered mistake: your code is on GitHub, intact. You get it back on any machine with one command.
- And you can share. Granting access to a colleague, working as a team, going open source: it all goes through GitHub.
Configure Git on the machine
Three lines, once and for all. Git needs to know who you are (it signs your commits):
git config --global user.name "Your First Last"
git config --global user.email "[email protected]"
# A few sane defaults
git config --global init.defaultBranch main # the default branch is called "main"
git config --global pull.rebase false # predictable pull behavior
Give the machine access to GitHub
Your machine has to prove to GitHub that it’s allowed to push. Two paths; take the one that speaks to you.
0 of 2 steps done Your ticks stay in this browser.
-
The simplest: the GitHub CLI (gh)
The official
ghtool handles authentication for you, tokens included.# Install gh from Ubuntu's repositories sudo apt install -y gh # Connect the machine to your account, answer the questions, it opens a browser gh auth loginChoose “GitHub.com,” then “SSH” as the protocol:
ghgenerates and installs the key on its own. At the end, your machine can clone, push, create repos. That’s the option I recommend to start.Ubuntu’s package often lags several versions behind (2.46 in Ubuntu 26.04, while GitHub ships 2.102 as of October 1, 2026). That’s enough to log in and push; if you miss a recent command, install
ghfrom GitHub’s official repository. -
The manual option: an SSH key dedicated to the machine
If you prefer to control everything, create an SSH key specific to this mini-PC (one key per machine is healthier):
ssh-keygen -t ed25519 -C "mini-pc-github" cat ~/.ssh/id_ed25519.pub # copy what's displayedPaste the public key into GitHub → Settings → SSH and GPG keys → New SSH key. Then verify:
ssh -T [email protected] # should greet you by your GitHub username
Your first repo, and the agent that uses it
cd ~/my-project
git init
# The file that tells git what to IGNORE, crucial
cat > .gitignore <<'EOF'
node_modules/
.env
*.log
dist/
EOF
git add -A
git commit -m "First draft"
# Create the remote repo and push (with gh, it's one line)
gh repo create my-project --private --source=. --push
Once it’s in place, ask your agent to handle git for you: “regular commits with clear messages,” “create a branch for this feature,” “open a pull request.” You can even write it into your memory file: “commit after each approved step, conventional messages, only push to main with my OK.”
Backups: the 3-2-1 rule
GitHub saves your code. But your mini-PC contains plenty of other things that aren’t in git: your .env files, your databases, generated data, system configs. For those, we apply the golden rule of backup:
0 of 4 steps done Your ticks stay in this browser.
-
Decide what to back up
- The code → already on GitHub, nothing more to do.
- The secrets (
.env, keys) → back them up encrypted, never in plaintext. - The data that matters (databases, generated files, custom configs).
- Not the Ollama models or
node_modules: they re-download, no point backing them up.
-
Pick a tool and a destination
restic is the ideal tool: encrypted, deduplicated, incremental backups. You send it to a NAS, another disk, or cloud storage.
sudo apt install -y restic # Initialize a backup repository (e.g., to a mounted NAS) restic -r /mnt/nas/backups init # First backup restic -r /mnt/nas/backups backup ~/projects ~/configsrcloneis an excellent alternative for targeting cloud storage (encrypted client-side). -
Automate, a manual backup always ends up forgotten
Schedule a systemd timer or a daily
cronjob. Your agent can write that in two minutes: ask it “create a systemd service that runs my restic backup every night at 3 a.m.” -
TEST your restore
A backup you’ve never restored isn’t a backup, it’s a hope. Do the exercise at least once:
restic -r /mnt/nas/backups restore latest --target /tmp/test-restore, and check that your files are really there.
Three traps you only discover when restoring
Target the disk by its label, never by its path
An external disk does not always mount in the same place. If the folder already exists, your desktop appends a digit and mounts on /media/you/1TB1, leaving /media/you/1TB behind as an empty folder on the system disk.
The naive test [ -d "$DEST" ] passes just fine. And your backup quietly writes to the system disk while believing it is writing to the external one.
# resolve by label, and demand a real mount point
DEST="$(findmnt -rn -S LABEL=1TB -o TARGET 2>/dev/null | head -1)"
[ -n "$DEST" ] && mountpoint -q "$DEST" \
|| { echo "external SSD not mounted, backup cancelled"; exit 1; }
A hardcoded list forgets the newcomers
A script that lists your databases by hand never backs up the project you created last month. And it does not say so. Sweep what is actually running:
for c in $(docker ps --format '{{.Names}}'); do
# probe for the tool rather than matching the image name:
# this also catches pgvector, timescaledb and other derivatives
docker exec "$c" sh -c 'command -v pg_dumpall' >/dev/null 2>&1 || continue
docker exec "$c" pg_dumpall -U postgres | gzip > "$DEST/$c.sql.gz"
done
A destructive rebuild must be atomic
A script that deletes the database then rebuilds it leaves you with nothing if it dies halfway. Build alongside, then rename: on the same filesystem, renaming is atomic.
sqlite3 base.sqlite.tmp < schema.sql
# … filling …
mv base.sqlite.tmp base.sqlite # instant swap, or nothing
And before the swap, check: integrity, index count, row floor. A rebuild that half succeeds otherwise passes for a success.
All the commands in this guide
Frequently asked questions
What is the difference between Git and GitHub?
Git is the version control tool that runs on your machine and records your files' history locally. GitHub is an online service where you push a copy of that history. Git is your logbook, GitHub your remote safe, and you need both.
How do you roll back when a coding agent has broken everything?
If the work is versioned with Git, every commit is a restore point: git restore or git reset brings the files back to their previous state in a second. And before you approve anything, git diff shows line by line what the agent touched.
What should you do if an API key was pushed to GitHub?
Treat it as leaked, even in a private repository: revoke it and generate a new one. To avoid it, write the .gitignore file, with at least .env and node_modules, before your very first git add.
Should you back up Ollama models and the node_modules folder?
No, they can be downloaded again. Back up what exists nowhere else instead: .env files and keys, always encrypted, databases, generated files and your own configurations. The code itself is already on GitHub.
Why can a backup fail without anyone noticing?
Because some traps fail silently: an external drive mounted under another name sends the backup to the system disk, a hard-coded list of databases forgets new projects, and a rebuild interrupted halfway passes for a success. Target the disk by its label, scan what is actually running, and build alongside before renaming.
Terms in this guide: AgentGitCommitOpen source (vs open-weight)
Spotted a mistake?
A command stopped working, a price changed?
Tools change every month. Tell me what is wrong in this chapter and I will fix it and update its date.