Git and GitHub for Beginners: Commits, Branches and Pull Requests
What are Git and GitHub?
Git is a free, open-source version control system that records snapshots of your project, called commits, so you can see what changed, work on branches and undo mistakes. GitHub is an online service that hosts Git repositories and adds collaboration features such as pull requests, code review and issue tracking. Git runs on your computer; GitHub stores a shared copy online.
Core Git terms: repository, commit, staging area and branch
- Repository (repo): a project folder that Git tracks, with its full history stored in a hidden
.gitfolder. - Commit: a saved snapshot of the project with a message, an author and a unique ID (a hash such as
a1b2c3d). - Staging area: the list of changes you have chosen to include in the next commit. It lets you commit some edits and leave others for later.
- Branch: a movable pointer to a line of commits. The default branch is usually called
main; you create other branches for features and fixes. - Merge: combining the history of one branch into another.
- Remote: a copy of the repository on another machine, usually GitHub, named
originby default.
Git and GitHub are not the same thing. You can use Git with no internet connection at all, and other services such as GitLab and Bitbucket also host Git repositories.
How Git works: working directory, staging and history
Every file change moves through three places. You edit files in the working directory, choose changes with git add to put them in the staging area, and record them permanently with git commit into the repository history. Pushing sends those commits to a remote; pulling brings other people's commits down.
git config --global user.name "Asha Verma"
git config --global user.email "[email protected]"
git config --global init.defaultBranch main
mkdir portfolio && cd portfolio
git init
git statusThe first three commands run once per computer and set the name and email attached to your commits, and the default branch name for new repositories. git init turns the current folder into a repository, and git status shows which files are untracked, modified or staged. Run git status often; it is the quickest way to know where you are.
Everyday Git commands with examples
git add index.html style.css # stage specific files
git add . # stage every change in this folder
git commit -m "Add home page layout"
git log --oneline # short history, newest first
git diff # unstaged changes
git diff --staged # staged changes, ready to commit
git branch # list branches
git switch -c contact-form # create a branch and switch to it
git switch main # go back to main
git merge contact-form # merge the branch into mainTo work with GitHub, you connect your local repository to a remote, or clone an existing one:
git clone https://github.com/your-username/portfolio.git
git remote add origin https://github.com/your-username/portfolio.git
git push -u origin main # first push; -u remembers the upstream
git push # later pushes
git fetch # download new commits without changing your files
git pull # fetch and then merge into your current branch Keeping files out of Git with .gitignore and protecting secrets
A .gitignore file in the project root lists files and folders Git should not track, such as dependencies, build output, logs and local configuration.
# Dependencies
/vendor/
/node_modules/
# Environment and secrets
.env
# Logs and editor files
*.log
.DS_Store
.vscode/Never commit secrets such as passwords, API keys or database credentials. Keep them in an .env file that is ignored, and commit a .env.example with blank values so others know which settings exist. If a secret is ever pushed, deleting it in a new commit is not enough because it stays in the history: revoke or rotate the key immediately, then clean up. This matters especially for PHP security and for database passwords used with MySQL.
Resolving a merge conflict
A conflict happens when two branches change the same lines of a file differently and Git cannot decide which version to keep. Git stops the merge and marks the file:
<<<<<<< HEAD
<h1>Welcome to Fresh Bakes</h1>
=======
<h1>Fresh Bakes, Pune</h1>
>>>>>>> update-heading- Run
git statusto list the files with conflicts. - Open each file and find the markers. The part above
=======is your current branch; the part below is the incoming branch. - Edit the section into the final version you want and delete all three marker lines.
- Save, then run
git addon the file to mark it as resolved. - Run
git committo complete the merge, and test the page before pushing.
If you want to start again, git merge --abort returns the branch to its state before the merge. Small, frequent merges keep conflicts small.
The pull request workflow on GitHub
Teams rarely commit straight to main. Instead, each change goes on its own branch and is reviewed through a pull request (PR) before it is merged.
- Update your local main with
git switch mainandgit pull. - Create a branch for one change, for example
git switch -c fix-navbar-links. - Make small commits as you work, then push the branch with
git push -u origin fix-navbar-links. - On GitHub, open a pull request from your branch into
main. Describe what changed, why, and how to test it. - Reviewers comment on the code; you push further commits to the same branch to address them, and automated checks run on each push.
- Once approved, the PR is merged into
main, and you can delete the branch.
This workflow suits every kind of project, from a WordPress theme to a framework-based app organised around the MVC pattern.
Good commit messages and undoing changes safely
A good commit message has a short summary line in the imperative mood, such as "Fix broken link in footer", ideally around 50 characters, followed by a blank line and an optional body explaining why the change was needed. Each commit should contain one logical change.
| Command | What it does | Safe on shared branches? |
|---|---|---|
git restore file.php | Discards uncommitted changes to a file in the working directory | Yes, but the discarded edits are lost |
git restore --staged file.php | Unstages a file and keeps your edits | Yes |
git revert a1b2c3d | Creates a new commit that undoes an earlier commit | Yes, history is preserved |
git reset --soft HEAD~1 | Removes the last commit but keeps its changes staged | Only if the commit has not been pushed |
git reset --hard HEAD~1 | Removes the last commit and discards its changes | No; use with great care |
Practical exercise: publish a project with a pull request
- Create a folder with an
index.htmlpage built with semantic HTML, rungit init, and make your first commit onmain. - Add a
.gitignorethat excludes an.envfile, and confirm withgit statusthat.envis not listed. - Create an empty repository on GitHub, add it as
originand pushmain. - Create a branch called
add-styles, add a stylesheet using CSS, commit and push the branch. - Open a pull request on GitHub, review your own diff, and merge it. Then pull
mainlocally.
You are done when GitHub shows at least two commits on main, one merged pull request, and no .env file anywhere in the repository. The PHP Foundation course uses version control like this throughout its projects.
Common mistakes
- Committing passwords, API keys or
.envfiles, which stay in the history even after deletion. - Working directly on
mainfor every change instead of using short-lived branches. - Writing vague commit messages such as "update" or "fix stuff" that explain nothing later.
- Using
git reset --hardor force-pushing on a branch other people use, which rewrites shared history. - Leaving conflict markers in a file after resolving a merge, which breaks the page or script.
- Running
git add .without checkinggit status, and committing files that were never meant to be tracked.
Frequently asked questions
Is GitHub free to use?
GitHub offers a free plan that includes public and private repositories, which is enough for learning and personal projects. Paid plans add features for teams and organisations.
What is the difference between git pull and git fetch?
Fetch downloads new commits from the remote without changing your files. Pull runs a fetch and then merges those commits into your current branch, so it can create conflicts.
Should beginners learn Git from the command line or a GUI?
Learning the core commands first helps you understand what any GUI or editor integration is doing. After that, tools such as the Git panel in VS Code are fine for everyday work, for example while building JavaScript projects.