We have all had a file named index-final-v2-fixed.php. Git solves this mess with a simple idea: it records every important point of your work with a message, and you can return to it whenever you want. Teamwork, safe experimentation and orderly deployment are all built on this idea.
To get started you need only a few concepts: repository, commit, branch and merge. With these alone, most of your daily work runs.
Installation and first setup#
Install Git from the official git-scm.com page. Then set your name and email once so each commit is recorded under your name:
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global init.defaultBranch mainCreating a repository and the first commit#
mkdir my-site && cd my-site
git init
echo "<?php echo 'Hello';" > index.php
git status
git add index.php
git commit -m "Add the home page"Every change goes through three steps: edit in the working folder, stage with git add and record with git commit. The git status command always shows which step you are at and is Git's most used command. See the history with git log --oneline and changes not yet recorded with git diff.
Write the commit message for humans. "Changes" is a bad message; "Validate email in the contact form" is a good one.
The gitignore file#
Not everything should enter the history. Create a .gitignore file in the project root:
.env
vendor/
node_modules/
storage/logs/
*.log
.DS_StoreFiles containing secrets, such as .env or a wp-config.php with real credentials, should never be in the repository, especially if you put it anywhere public. The vendor folder can also be rebuilt with Composer; we explain more in Composer and dependency management.
Branches#
A branch is a separate line of work. You can build a new feature without breaking the main version:
git switch -c feature/contact-form # create and switch to a new branch
# ... edit files ...
git add .
git commit -m "Build the contact form"
git branch # list branches
git switch main # go back to the main branchA practical rule: create a branch with a descriptive name (feature/..., fix/...) for each task. Branches are cheap, and every small task deserves its own.
Merging#
When the branch work is finished, bring it into the main branch:
git switch main
git merge feature/contact-form
git branch -d feature/contact-form # delete the merged branchIf main has had no changes since the branch split off, Git just moves the pointer forward (a fast-forward). If both sides have changes, a merge commit is created.
Resolving conflicts#
If both branches changed the same place in a file, Git stops and marks it:
<<<<<<< HEAD
$title = 'Contact us';
=======
$title = 'Get in touch';
>>>>>>> feature/contact-formSteps to resolve:
- Open the file and decide which version (or a mix of both) is right.
- Delete the three marker lines
<<<<<<<,=======and>>>>>>>. - Stage the file with
git add. - Complete the merge with
git commit.
If you regret it midway, git merge --abort returns you to before the merge. A conflict isn't a sign that something is broken; it only means two people changed the same spot.
Undoing changes#
| I want to | Command |
|---|---|
| Discard an unrecorded change to one file | git restore <file> |
| Unstage a staged file | git restore --staged <file> |
| Remove the last commit but keep the changes | git reset --soft HEAD~1 |
| Undo a published commit | git revert <hash> |
The commands git reset --hard and git restore erase unrecorded changes permanently. Before running them, make sure you know what will be lost.
A remote repository#
For backup and teamwork, the repository is kept on a service like GitHub:
git remote add origin <repository-url>
git push -u origin main
git pullpull fetches other people's changes and push sends yours. Run git pull before starting your daily work so you run into fewer conflicts. The next step, Pull Requests and code review, is covered in GitHub for teamwork, and for publishing on a server, see deploying a site with Git on shared hosting.
Good habits from the start#
- Make small, frequent commits; one commit per task.
- Don't work directly on
main. - Glance at
git statusbeforegit add .so unwanted files don't slip in. - Never commit passwords and API keys.
- If you write a WordPress plugin, create a repository from day one; the folder structure is covered in building a WordPress plugin from scratch.
A daily workflow#
What usually gets left out of Git exercises is the real routine. A typical working day goes like this: in the morning git switch main and git pull to get the latest changes; create a new branch for today's task; make a few small commits during the day; and in the evening git push the branch to keep a backup. When the work is done, you merge it or send it for review.
git switch main
git pull
git switch -c fix/login-error
# ... work and commit ...
git push -u origin fix/login-errorIf you have to switch to another branch midway and you have unfinished changes, git stash sets them aside temporarily and git stash pop brings them back. This is better than committing half-finished code.
A few useful commands for exploring#
git log --oneline --graph --all: shows the history with branches as a text graph.git blame <file>: shows who wrote each line and in which commit.git show <hash>: shows the contents of a commit.git diff main..feature/x: shows the difference between two branches.
These commands help a lot when you have found a bug and want to learn when it began. Clear commit messages show their worth right here.
Summary#
- Git keeps the project history as commits with messages.
- The workflow: edit,
git add,git commit; andgit statusis always your friend. - Create a branch for each feature and bring it into
mainwithgit merge. - Resolve conflicts by editing the file, then
addandcommit;merge --abortis the way back. - Put
.env, secrets andvendorin gitignore. - To undo, distinguish between
restore,resetandrevert, and use destructive commands with care.