Git is a version control system. It tracks changes in files so you can:
Think of Git as 3 places:
A commit is a snapshot of your project at a point in time.
Typical flow:
git add .
git commit -m "message"
git push
Meaning:
git add = choose what goes into the next snapshotgit commit = save the snapshot locallygit push = send it to remote like GitHubgit config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global init.defaultBranch main
Useful settings:
git config --global core.editor "code --wait"
git config --global -l
Create a new repo:
git init
Clone an existing repo:
git clone <repo-url>
Example:
git clone https://github.com/user/project.git
These are the commands you use all the time:
git status
git diff
git diff --staged
git log
git log --oneline --graph --decorate --all
What they mean:
git status = what changed?git diff = what changed but not staged?git diff --staged = what is staged and ready to commit?git log = commit historyA file can be:
You usually move files like this:
edit -> git add -> git commit
Add one file:
git add file.txt
Add all changes in current directory:
git add .
Commit:
git commit -m "Add login form"
Good commit messages are:
Examples:
Fix login redirectAdd Docker supportRemove unused helpergit restore file.txt
This brings the file back to the last committed version.
git restore --staged file.txt
This removes it from the staging area, but keeps the file changes.
git reset --soft HEAD~1
Use this when the last commit was wrong, but you want the changes back staged.
git reset --mixed HEAD~1
This keeps the changes in your files, but unstaged.
git reset --hard HEAD~1
Be careful. This deletes local changes.
git log
git log --oneline
git show <commit-hash>
git checkout <commit-hash>
Better modern form:
git switch --detach <commit-hash>
This puts you in detached HEAD state. It is okay for inspection, but not for normal work.
A branch is just a movable pointer to a line of work.
Main use:
git branch
git branch feature-login
git switch feature-login
Create and switch in one command:
git switch -c feature-login
git branch -d feature-login
Force delete:
git branch -D feature-login
This is one of the most important Git concepts.
Combines branches by creating a merge commit.
git merge feature-login
Use merge when:
Moves your commits on top of another branch.
git rebase main
Use rebase when:
If the target branch has no new commits, Git can simply move the pointer forward.
git merge feature
This may create no merge commit if it can fast-forward.
A remote is another copy of the repo, often on GitHub/GitLab.
git remote -v
git remote add origin https://github.com/user/repo.git
git push -u origin main
-u sets the upstream, so later you can just run:
git push
git pull
git fetch
This downloads new remote data but does not merge it into your branch.
git pull
This is basically:
git fetch
git merge
If you want to be safer, use:
git fetch
git status
git log --oneline --graph --decorate --all
Then decide whether to merge or rebase.
A simple good workflow:
git switch main
git pull
git switch -c feature-x
# work...
git add .
git commit -m "Implement feature x"
git push -u origin feature-x
Then open a pull request / merge request.
A merge conflict happens when Git cannot decide how to combine changes.
Typical situation:
Git will mark conflict sections like this:
<<<<<<< HEAD
your changes
=======
their changes
>>>>>>> branch-name
Fix it by editing the file manually, then:
git add conflict-file.txt
git commit
If you are in the middle of a rebase:
git rebase --continue
If you want to stop and undo the rebase:
git rebase --abort
If you are in a merge and want to stop:
git merge --abort
Stash is temporary storage for unfinished work.
Use it when:
git stash
git stash list
git stash pop
git stash apply
git stash drop
A tag marks an important commit, often a release.
git tag v1.0.0
git push origin v1.0.0
List tags:
git tag
Useful for releases and versioning.
This is a big one.
git resetMoves branch history pointer. Mostly for local work.
git reset --soft HEAD~1
git reset --mixed HEAD~1
git reset --hard HEAD~1
git revertCreates a new commit that undoes an old commit.
git revert <commit-hash>
Use revert when:
Apply one specific commit from another branch:
git cherry-pick <commit-hash>
Useful when you need one fix from somewhere else without merging everything.
Git remembers where HEAD and branches used to point.
git reflog
This is very useful after:
You can often recover a lost commit from reflog.
Before you switch branches or commit, check:
git status
A clean state is easiest to manage.
Useful habits:
.gitignoreSome files should not be tracked:
Create .gitignore:
node_modules/
dist/
.env
*.log
Important:
.gitignore only prevents new untracked files from being added..gitignore will not stop tracking it automatically.To stop tracking a file but keep it locally:
git rm --cached file.txt
See changed files:
git diff --name-only
See who changed lines:
git blame file.txt
See file history:
git log -- file.txt
See branch graph:
git log --oneline --graph --decorate --all
See a file at a commit:
git show <commit-hash>:path/to/file
Typical branch workflow:
git switch main
git pull
git switch -c fix-bug
# edit
git add .
git commit -m "Fix bug"
git push -u origin fix-bug
Later, after merge:
git switch main
git pull
git branch -d fix-bug
Sometimes teams prefer rebasing when pulling updates:
git pull --rebase
This keeps history more linear.
Use carefully, especially if your branch is shared.
Use:
git reset --soft HEAD~1
Then fix staging and recommit.
Use:
git restore file.txt
Use:
git restore --staged file.txt
Use:
git stash
git switch other-branch
git stash pop
Check:
git reflog
A common professional flow:
This keeps main stable.
A common clean-history flow:
git switch feature-x
git fetch origin
git rebase origin/main
Then resolve conflicts if any, continue, and push:
git push --force-with-lease
Important:
--force-with-lease, not plain --force, when possible.HEAD meansHEAD points to your current position in history.
Usually:
HEAD -> current branch -> latest commitWhen detached:
HEAD points directly to a commitExample:
git show HEAD
git reset --soft HEAD~1
HEAD~1 means “one commit before HEAD”.
origin meansorigin is usually the default name for the remote repo you cloned from.
Example:
git push origin main
git pull origin main
You can have multiple remotes, but origin is the common one.
These are the essentials:
git status
git add .
git commit -m "message"
git push
git pull
git fetch
git branch
git switch -c new-branch
git merge branch-name
git stash
git log --oneline --graph --decorate --all
git diff
git restore file.txt
git restore --staged file.txt
git reset --soft HEAD~1
git revert <commit>
When something feels confusing, ask these questions:
What files changed?
git statusAre they staged?
git status, git diff --stagedWhich branch am I on?
git branchWhat is my history?
git log --oneline --graph --decorate --allDo I need to save work first?
git stash or commitAm I rewriting local history or shared history?
reset for local, revert for sharedgit init
git add .
git commit -m "Initial commit"
git clone <url>
git switch -c feature-name
git add .
git commit -m "Describe change"
git push -u origin feature-name
git pull
git status
git diff
git log --oneline --graph --decorate --all
git restore file.txt
git reset --soft HEAD~1
git revert <commit>
revert for public undo.git status before every commit..gitignore clean.git log --graph often to understand history.