For years a lot of freelance web work ran on folders named site-final, site-final-2 and site-final-REAL. I've opened projects like that from previous developers, and I've had to guess which copy was actually live. Git fixes that problem, and once I started using it on every client website I stopped losing work, stopped breaking live sites with small edits, and found it much easier to hand projects over.
This isn't a full Git tutorial. It's how I use Git and GitHub on normal client websites as a freelancer: what I put in the repository, what I keep out, how I name things, and how it helps when a client comes back a year later.
Why Git matters even on small sites
Most of my projects are small business websites, portfolios and custom PHP sites with an admin panel. It's easy to think version control is only for big teams. In practice it helps most on exactly these projects, because they get touched once in a while, often months apart, by someone who has forgotten the details.
Git gives me three things I don't want to work without:
- A history I can trust. Every change has a date and a short note, so I can see what changed, when, and why.
- An easy way back. If an update breaks the contact form, I can compare it with the last working version and undo just that change.
- Room to try things. I can work on a redesign in a separate branch while the live version stays untouched.
How I set up a repository for a client site
I start a repository on the first day of a project, not at the end. A repository started late tends to have one huge first commit that tells nobody anything.
One repository per website
Each client site gets its own private repository on GitHub. I don't mix two clients in one repository, even when the sites share code. If I reuse something, like a small admin panel, I copy it in and let each project grow on its own. That keeps every client's code separate and makes it easy to transfer ownership later.
What I keep out of Git
This is the part people get wrong most often, and it can be serious. A .gitignore file tells Git which files to skip. On a typical PHP site I leave out:
- The config file with database passwords, SMTP logins and API keys. I commit an example file with empty values instead, so the next developer knows what's needed.
- The uploads folder with client images and documents. Those belong in backups, not in code history.
- Dependency folders like
vendorandnode_modules, which can be rebuilt from the lock files. - Cache files, log files and editor settings.
If a password ever ends up in a commit by mistake, deleting the file later isn't enough, because it's still in the history. The safe fix is to change that password straight away and then clean the history.
Private by default
Client repositories are always private. Even when the code itself isn't sensitive, the history can show business details, staging addresses and email settings that shouldn't be public.
The simple workflow I actually use
I don't run a complicated branching system on a five page website. My routine is small and boring on purpose:
- The main branch matches what's live. If it's on
main, it's on the website, or about to be. - Bigger changes get their own branch. A new booking page or a redesign goes on a branch like
booking-pageuntil it's tested. - Small, clear commits. I commit each logical change on its own, with a message that says what it does, like "Fix contact form reply-to header" rather than "updates".
- Test before merging. I click through the changed pages on desktop and on a phone, submit the forms, and only then merge into
main. - Tag releases. When something important goes live, I add a tag with the date, so I can find that exact version again quickly.
That's it. Most of the value comes from doing these few things every time, not from clever Git commands.
Previews before anything goes live
For static sites and frontend projects, connecting a GitHub repository to a hosting service like Vercel or Netlify gives a preview link for every branch. I send that link to the client so they can see the change on their own phone before it reaches the real site. It saves a lot of "can you move this up a bit" messages after launch.
PHP sites with a database usually need a staging copy on the hosting instead, but the idea is the same: the client checks a separate version first, and the live site only changes after they're happy.
Handing a project over
This is where Git pays off for clients, even ones who never look at code. When a project ends, I can:
- Transfer the repository to the client's own GitHub account, or add them as an owner.
- Leave a short README that explains how the site is set up, which settings go in the config file, and how to deploy changes.
- Point the next developer to a clean history instead of a zip file of unknown age.
I'd always rather a client owns their own code. If they work with someone else later, that person starts with the full picture instead of guessing which folder is the real one.
Mistakes I see on freelance projects
- Committing the live config file with the database password in it.
- Editing files directly on the server so the repository and the live site slowly drift apart.
- Keeping the only copy of a client's code in the freelancer's personal account with no way for the client to get it.
- Commit messages like "fix" and "changes" that make the history useless.
- Treating Git as a backup. It tracks code, but it doesn't back up the database or uploaded files, so real backups are still needed.
If you're hiring a developer
You don't need to learn Git yourself. It's still worth asking a few questions before a project starts: will the code be in a repository, who owns that repository, and how do changes get from the developer's computer to the live site? A clear answer usually means the project will be easier to maintain later. If you'd like help setting this up for an existing site, you can reach me through my contact page.
Back to Blogs