Git: From Beginner to Advanced
Recommended Learning Resources
Resource 1: Learn Git Branching
An interactive visual guide to learning Git branching and workflows.
Resource 2: Pro Git Book - Git Basics
The official Git documentation covering fundamental Git concepts and repository management.
My Practical Git Workflow 🧭
Most of what I know about Git came from maintaining websites and research projects, making small mistakes, and gradually building a workflow I could trust. Git became much less intimidating when I stopped treating it as a list of commands and started using three checkpoints: inspect the repository, stage intentionally, and inspect again before committing.
The examples below use generic names such as USERNAME, REPOSITORY, feature/site-update, and path/to/file. They can be adapted without exposing local folders, account details, or project-specific information.
1. Start from a known state 🧭
Before editing anything, I confirm where I am and whether the repository is clean.
-
git branch --show-current(Shows which branch I am standing on right now.) -
git rev-parse --show-toplevel(Shows the root folder of the Git repository I am currently working in.) -
git status(Gives me the full picture of what is modified, staged, or still untracked.) -
git fetch --prune origin(Updates my view of the remote repository and removes references to remote branches that no longer exist.) -
git switch main(Moves me back to the main branch before I synchronize or begin a new task.) -
git pull --ff-only origin main(Downloads the newest main branch only when Git can update it cleanly without creating a surprise merge commit.) -
git switch -c feature/site-update(Creates a new branch and moves me onto it in one step.) -
git switch feature/site-update(Moves me to a branch that already exists.)
The older command git checkout -b feature/site-update (Does the same create-and-switch job, but I find the newer git switch wording easier to understand.)
For a few closely related follow-up edits, I may continue on the same branch. Once a pull request has been merged, however, starting a fresh branch from the latest main usually keeps the next review much easier to follow.
2. Inspect before staging 🔍
I check the repository again after editing. This is where I catch temporary files, generated outputs, and changes I did not mean to include.
-
git status --short(Shows a compact list of changed files and their two-letter status codes.) -
git diff --stat(Summarizes the unstaged files and the size of their changes.) -
git diff(Shows the exact unstaged line-by-line changes I have made.) -
git diff -- path/to/file(Shows the unstaged changes for one specific file.) -
git ls-files --others --exclude-standard(Lists only new untracked files while respecting.gitignore.)
The short status symbols are especially useful:
| Symbol | Plain-language meaning |
|---|---|
?? | A new file that Git is not tracking yet |
| ` M` | A tracked file changed, but the change is not staged |
M | A tracked modification is staged for the next commit |
A | A new file is staged for the next commit |
D | A deletion is staged for the next commit |
Some terminal themes also show a symbol such as * or ✭ beside the branch name. That usually means the working tree is not completely clean; git status (Explains the actual reason instead of making me guess what the prompt symbol means.)
3. Stage deliberately 📦
I prefer adding specific files when a change is small. Broad staging commands are convenient, but they deserve an immediate review. A stray log or transcript once reminded me that “new file” does not automatically mean “file that belongs in the repository.”
-
git add path/to/file(Stages one file I have deliberately chosen.) -
git add path/to/file another/file(Stages several named files without sweeping in everything else.) -
git add .(Stages changes under the current directory, so the directory where I run it matters.) -
git add -u(Stages modifications and deletions to tracked files, but leaves brand-new untracked files alone.) -
git add -A(Stages every addition, modification, and deletion in the repository, including new files.) -
git restore --staged path/to/file(Takes a file back out of the next commit without deleting my local copy or edits.)
4. Review, then commit ✅
Staging is not the finish line. I inspect the staged snapshot—the exact content that the commit will contain.
-
git --no-pager diff --cached --stat(Summarizes the staged files and line counts without opening an interactive pager.) -
git diff --cached(Shows the complete staged patch that will become the next commit.) -
git commit -m "Describe the change clearly"(Saves the staged snapshot locally with a short explanation of why it exists.) -
git log -1 --oneline --decorate(Confirms the newest commit and shows which branch or tag points to it.)
A blank git diff --cached (Means nothing is currently staged, even if untracked or unstaged files still exist.) Likewise, “nothing added to commit but untracked files present” simply means Git sees new local files but has not been told to include them.
5. Push and open a pull request 🚀
-
git push -u origin feature/site-update(Publishes a new branch and remembers its remote partner for future pushes.) -
git push(Uploads new commits after the local branch already has an upstream branch.) -
git push --dry-run origin HEAD(Checks where and whether a push would work without actually uploading anything.) -
git remote -v(Shows the remote addresses Git currently uses for fetching and pushing.) -
git remote set-url origin https://github.com/USERNAME/REPOSITORY.git(Updates a saved remote address when a repository moves or is renamed.)
One distinction took me time to internalize: a push uploads commits, not every file sitting in the folder. An untracked file stays on my computer unless I stage it and include it in a commit.
After pushing a feature branch, I normally open a pull request, let the automated checks finish, review the changed files once more, and then merge into main.
6. Synchronize after merging 🔄
-
git fetch --prune origin(Refreshes remote information and clears stale remote-branch references.) -
git switch main(Returns me to the branch that represents the published project.) -
git pull --ff-only origin main(Brings the merged work back to my local main branch without creating an unnecessary merge commit.) -
git branch -d feature/site-update(Deletes a fully merged local branch while refusing to remove one that may still contain unmerged work.) -
git push origin --delete feature/site-update(Removes the remote feature branch after I no longer need it.)
7. Occasional setup commands 🛠️
These are not part of every editing session, but they are useful when beginning a repository or moving to a new computer.
-
git clone https://github.com/USERNAME/REPOSITORY.git(Downloads an existing repository and configures its remote automatically.) -
git init(Turns the current folder into a new local Git repository.) -
git remote add origin https://github.com/USERNAME/REPOSITORY.git(Connects a new local repository to its GitHub repository.) -
git config --get user.name(Shows the author name Git will attach to my commits.) -
git config --get user.email(Shows the author email Git will attach to my commits.) -
git check-ignore -v path/to/file(Explains whether a file is ignored and identifies the rule responsible.)
Commands I treat with extra care ⚠️
-
git restore path/to/file(Discards unstaged edits in that file, so I check the diff before using it.) -
git branch -D feature/site-update(Force-deletes a local branch even when its work has not been merged.) -
git reset --hard(Forces tracked files back to a commit and can permanently erase uncommitted work.)
My simplest rule is still the most useful: when I am unsure, I run git status (Shows the current situation without changing anything.) before I run a command that changes state.