Skip to main content

Git Commands We Should Know

· 32 min read
Anand Raja
Senior Software Engineer

Useful Git Commands ​

  1. Uninitialize Git repository
cd path/to/repo
rm -rf .git
  1. To see your initialized Git user locally
git config --list
  1. Drop all the changes
git stash -u && git stash drop
  1. Stash your changes:

    git stash

    This command saves your local modifications and reverts the working directory to match the HEAD commit.

  2. Pop the most recent stash:

    git stash pop

    This command applies the changes from the most recent stash and removes it from the stash list.

  3. Apply the most recent stash:

    git stash apply

    This command applies the changes from the most recent stash but keeps the stash in the stash list.

These commands will operate on the most recent stash without needing to specify stash@{0}.

  1. Stash your changes with a message:

    git stash push -m "my_stash_name"

  2. List your stashes to see the stash you just created:

    git stash list

    You will see an output similar to:

    stash@{0}: On branch_name: my_stash_name
  3. Apply the stash:

    git stash apply stash@{0}

    Replace stash@{0} with the appropriate stash reference if it's not the most recent one.

  4. Or pop the stash (apply and remove from stash list):

git stash pop stash@{0}

Again, replace stash@{0} with the correct reference if needed.

Using apply will keep the stash in the list, while pop will remove it after applying.

  1. Create a new branch from the stash:
git stash branch <branch-name>

Replace <branch-name> with the desired name for your new branch. This command will create a new branch, apply the stashed changes, and drop the stash.

git checkout vs git switch​

Both git switch and git checkout can be used to switch branches in Git, but git switch is a newer and more focused command introduced to simplify branch switching. Here are the differences and usage examples:

The git checkout command is versatile and can be used for various purposes, including switching branches, creating new branches, and checking out specific commits or files. However, its versatility can sometimes make it confusing.

  1. Switch to an existing branch:
git checkout branch-name
  1. Create and switch to a new branch:
git checkout -b new-branch-name

The git switch command is specifically designed for switching branches, making it more intuitive for this purpose. It does not support all the functionalities of git checkout.

  1. Switch to an existing branch:
git switch branch-name
  1. Create and switch to a new branch:
git switch -c new-branch-name
  • Use git switch for a more straightforward and focused way to switch branches.
  • Use git checkout if you need its additional functionalities, such as checking out specific commits or files.

For most branch switching tasks, git switch is recommended for its simplicity and clarity.

The git log command is used to view the commit history of a Git repository. It shows a list of commits, including their hashes, author information, dates, and commit messages. Here are some common options and their differences:

  1. Basic git log:
git log

This command shows the commit history in a simple format.

  1. git log --oneline:
git log --oneline

This command shows the commit history in a condensed format, with each commit on a single line. It displays the commit hash and the commit message.

  1. git log --graph:
git log --graph

This command shows the commit history as a graph, which is useful for visualizing branch and merge history.

  1. git log --stat:
git log --stat

This command shows the commit history along with a summary of changes made in each commit (files changed, insertions, and deletions).

  1. git log -p:
git log -p

This command shows the commit history along with the actual changes (diffs) made in each commit.

  1. git log --author="Author Name":
git log --author="Author Name"

This command filters the commit history to show only commits made by a specific author.

  1. git log --since="2022-01-01":
git log --since="2022-01-01"

This command filters the commit history to show only commits made since a specific date.

  1. git log --until="2022-12-31":
git log --until="2022-12-31"

This command filters the commit history to show only commits made until a specific date.

  1. git log --grep="keyword":
git log --grep="keyword"

This command filters the commit history to show only commits with messages containing a specific keyword.

  1. Combining options:

    git log --oneline --graph --decorate --all

    This command combines multiple options to show a decorated graph of the commit history, with each commit on a single line, including all branches.

  2. Compact graph view for recent commits:

    git log --graph --oneline --decorate --all --max-count=15

    This is one of the most useful commands for quickly understanding a repository's recent history.

    • --graph draws the branch and merge structure using ASCII lines.
    • --oneline shows each commit in a short single-line format.
    • --decorate shows branch names, tags, and remote references beside commits.
    • --all includes all branches, not just the current branch.
    • --max-count=15 limits the output to the latest 15 commits, so the view stays readable.

    Use it when you want to quickly see where branches split, where they merged, and which commit belongs to which branch.

    Related useful commands:

    git log --graph --oneline --decorate --all

    Shows the full decorated graph for all branches.

    git log --graph --oneline --decorate --all --max-count=30

    Same graph view, but with the latest 30 commits.

    git log --graph --oneline --decorate --branches

    Shows the graph for local branches only.

    git log --graph --oneline --decorate --remotes

    Shows the graph for remote-tracking branches.

    git log --graph --oneline --decorate --all --author="Author Name"

    Shows the graph filtered by author.

    git log --graph --oneline --decorate --all --since="2 weeks ago"

    Shows recent branch history from the last two weeks.

These options allow you to customize the output of git log to suit your needs and make it easier to navigate and understand the commit history.

Here are the basic Git commands to check the status of your repository, add changes to the staging area, and commit them:

  1. Check the status of your repository:
git status

This command will show you the current state of your working directory and staging area, including any changes that have been made, files that are staged for commit, and untracked files.

  1. Add changes to the staging area & unstaging
git add <file>

Replace <file> with the path to the file you want to stage. For example, to stage the index.html file:

git add src/index.html

To stage all changes in the repository, you can use:

git add .

To Unstage all files

git restore --staged .

Unstage the specific file

git restore --staged src/index.html
  1. Commit the staged changes:
git commit -m "Your commit message"

Replace "Your commit message" with a meaningful message describing the changes you made. For example:

git commit -m "Update index.html with systemjs-importmap and preload link"
  1. Switch to the specific commit in detached HEAD state:
git switch --detach <commit-hash>

Replace <commit-hash> with the hash of the commit you want to switch to. You can inspect the state of the repository at a specific commit without creating a new branch. This is useful for debugging or reviewing the code at a particular point in time.

In a detached HEAD state, you can make changes and commit them, but these commits will not belong to any branch. If you want to keep these changes, you should create a new branch:

  1. Create a new branch from the detached HEAD state:
git switch -c new-branch-name

Replace new-branch-name with the desired name for your new branch. This will create a new branch and move your changes to it.

  1. git merge is used to combine the changes from one branch into another. Depending on the branch history, Git may perform a fast-forward or create a merge commit.
git checkout main
git merge feature-branch

For a safer promotion flow where you want to ensure the target branch only moves forward without creating an unexpected merge commit, use:

git merge --ff-only feature-branch

--ff-only succeeds only when the current branch can be moved directly to the source branch commit. If the branches have diverged, Git stops instead of creating a merge commit.

  1. git rebase is a powerful Git command that allows you to move or combine a sequence of commits to a new base commit. It is often used to keep a linear commit history and to integrate changes from one branch into another.
git checkout feature-branch
git rebase main
  • This command will rebase the feature-branch onto the main branch. It effectively takes the commits from feature-branch and re-applies them on top of the latest commit in main.
  • During the rebase process, you might encounter conflicts. Git will pause the rebase and prompt you to resolve the conflicts.
  • Identify conflicted files by git status
  1. Resolve conflicts manually or accept incoming changes:
git checkout --theirs <file>
git add <file>
  1. Resolve conflicts manually or ignoring incoming changes/ keeping current changes:
git checkout --ours <file>
git add <file>
  1. Continue with the rebase:
git rebase --continue

This command tells Git to continue the rebase process after resolving the conflicts.

  1. Abort the rebase (if needed): If you want to stop the rebase process and return to the original state, you can use:
git rebase --abort
  1. git merge --squash is used to combine the changes from one branch into another, but it does not create a merge commit. Instead, it squashes all the changes into a single commit.
git checkout main
git merge --squash feature-branch
  1. Pull changes from the remote master branch to the currently checked-out branch
git pull origin master
warning

git pull origin master does not switch you to master and update your local master branch automatically.

For example, if you are currently on feature/my-work, this command fetches origin/master and merges it into feature/my-work.

If your intention is to update your local master, first switch to it:

git switch master
git pull origin master

If you only want to download the latest remote information without changing your current branch, use:

git fetch origin

Or fetch only one remote branch:

git fetch origin master
  1. Check the differences between the working directory and the staging area:
git diff
  1. Check the differences between the staging area and the last commit:
git diff --staged
  1. Useful Git Commands for Remote URLs
  • Show current remote URLs:

    git remote -v

    This lists all remotes and their fetch/push URLs.

  • Set or change the remote URL:

    git remote set-url <remote_name> <new_url>

    Example:

    git remote set-url origin https://github.com/username/repo.git
  • Add a new remote:

    git remote add <remote_name> <url>

    Example:

    git remote add upstream https://github.com/otheruser/repo.git
  • Remove a remote:

    git remote remove <remote_name>

    Example:

    git remote remove upstream
  • Rename a remote:

    git remote rename <old_name> <new_name>

    Example:

    git remote rename origin upstream
  • Show detailed info about a remote:

    git remote show <remote_name>

    Example:

    git remote show origin

Breakdown of git pull origin master​

  1. Fetch Changes: The command first fetches the latest changes from the master branch of the remote repository named origin. This updates your local copy of the remote branch.

    git fetch origin master
  2. Merge Changes: After fetching the changes, it merges the master branch from the remote repository into your current branch. This integrates the changes from the remote master branch into your working branch.

    git merge origin/master

Forking in Git: Contributing to Repositories You Don't Own ​

In Git (and especially on platforms like GitHub), forking is needed when you want to contribute to a repository you do not own or do not have write access to.

Why can't you just create a branch in someone else's repo?​

  • You cannot create branches directly in a repository unless you have write access (are a collaborator or member).
  • Most open source projects do not give write access to everyone for security and quality reasons.

What does a fork do?​

  • Fork creates a copy of the original repository under your own GitHub account.
  • In your fork, you have full control: you can create branches, make changes, and commit freely.

How does fork help you contribute?​

  1. Fork the repository (creates your own copy).
  2. Clone your fork locally.
  3. Create a branch in your fork, make changes, and commit.
  4. Push the branch to your fork on GitHub.
  5. Open a Pull Request (PR) from your branch (in your fork) to the original repository’s branch (usually master or main).

How does merging work?​

  • The repository owner reviews your PR.
  • If approved, they merge your changes into the original repo’s master/main branch.

Summary Table​

Without ForkWith Fork
No write access to other's repoFull control in your fork
Can't create branchesCan create branches
Can't push changesCan push changes
Can't open PRs from branchesCan open PRs from fork to original repo

In short:
A fork lets you propose changes to someone else’s repository by giving you your own copy to work in, and then you use a pull request to ask the original repo to merge your changes.

Cloning Guide ​

  1. Clone only the remote primary HEAD (default: origin/master)
git clone <url> --single-branch
  1. Only specific branch
git clone <url> --branch <branch> --single-branch [<folder>]
git clone <url> --branch <branch>
  1. Cloning repositories using degit

    • main branch is default.
npx degit github:user/repo#branch-name <folder-name>

Git Merge, Rebase, and Squash: Differences Explained ​

Git Merge​

git merge is used to combine the changes from one branch into another. It creates a new "merge commit" that records the history of both branches.

Example:

git checkout main
git merge feature-branch
  • The changes from feature-branch are merged into main.
  • A merge commit is created if there are new commits on both branches.

Git Rebase​

git rebase moves or combines a sequence of commits to a new base commit. It rewrites commit history by placing your branch’s commits on top of another branch.

Rebase Explained with an Analogy​

Imagine you are writing a paragraph for a report. While you are writing, someone else updates the report with new lines.
git rebase lets you move your paragraph to the end of the latest version of the report, so it looks like you wrote it after those new lines.

Visual Example​

  • Before rebase:

    A → B   (main branch)
    A → B (main)
    \
    C → D (feature)
  • Main branch gets new commits:

    A → B → E → F   (main)
    \
    C → D (your branch is outdated now)
  • After rebase:

    A → B → E → F → C' → D'  (rebased feature branch)

Mermaid Diagram​

Example:

git checkout feature-branch
git rebase main
  • The commits from feature-branch are reapplied on top of the latest commit in main.
  • Results in a linear history, but can rewrite commit hashes.

Git Squash​

Squashing means combining multiple commits into a single commit.
You can squash commits during an interactive rebase or with git merge --squash.

Example (interactive rebase):

git rebase -i HEAD~3
  • The above command starts an interactive rebase for the last 3 commits on your current branch.

Example editor view:​

pick 1234567 Commit message 1
pick 89abcde Commit message 2
pick fedcba9 Commit message 3
  • You can choose actions for each commit:

    • pick (keep as is)
    • reword (change commit message)
    • edit (change the commit itself)
    • squash (combine with previous commit)
    • drop (remove the commit)
  • In the editor, change pick to squash or s for the commits you want to squash.

  • The selected commits will be combined into one.

Example (merge squash):

git checkout main
git merge --squash feature-branch
git commit -m "Squashed changes from feature-branch"
  • All changes from feature-branch are staged as a single commit on main.
  • No merge commit is created; the branch history is not preserved.

Differences Table​

CommandCombines ChangesCommit HistoryMerge CommitLinear HistoryUse Case
git mergeYesPreservedYesNoStandard branch integration
git rebaseYesRewrittenNoYesClean, linear history
git squashYesSquashedNoYesCombine multiple commits into one

Summary​

  • Merge preserves branch history and creates a merge commit.
  • Rebase rewrites history for a linear commit log and makes your changes appear after the latest updates.
  • Squash combines multiple commits into one for a cleaner history.

Git Cherry-Pick​

git cherry-pick lets you apply a specific commit (or a range of commits) from one branch onto your current branch — without merging the entire branch.

When to use it​

  • You fixed a bug on main and need that exact fix on an older release branch.
  • A teammate committed a useful change on their feature branch, and you need just that one commit — not everything else they did.
  • You accidentally committed something to the wrong branch and want to bring it over cleanly.

Basic usage​

git cherry-pick <commit-hash>

Replace <commit-hash> with the SHA of the commit you want (find it via git log --oneline).

Pick a range of commits​

git cherry-pick <start-hash>^..<end-hash>

This picks all commits from <start-hash> through <end-hash> (inclusive) onto your current branch.

Handling conflicts​

If a conflict occurs during cherry-pick, Git pauses and lets you resolve it:

# After resolving conflicts in the file(s):
git add <file>
git cherry-pick --continue

To abort and go back to the original state:

git cherry-pick --abort

Visual example​

Before cherry-pick — feature-branch has commits E, F, G branching off main:

If you only want commit F on main:

git checkout main
git cherry-pick <hash-of-F>

After cherry-pick — only F' is copied onto main, leaving feature-branch untouched:

F' is a new commit with the same changes as F but a different hash.

tip

Use git cherry-pick for surgical, targeted commits. For integrating an entire branch, prefer git merge or git rebase.


Revert Commands in Git​

Git provides several ways to undo changes, depending on what you want to revert:

1. git revert​

  • Creates a new commit that undoes the changes made by a previous commit.
  • Safe for shared/public branches because it doesn't rewrite history.

Example:

git revert <commit-hash>

This will open an editor for a commit message and create a new commit that reverses the changes of <commit-hash>.

  • Push the revert commits to the remote
git push origin <your-branch-name>

Replace <your-branch-name> with the actual name of your branch (e.g., main, master, or a feature branch).

2. git reset​

  • Moves the branch pointer and optionally changes the staging area and working directory.

  • --soft: Keeps changes staged.

    • Useful if you want to undo commits but keep the changes staged for a new commit.

      git reset --soft HEAD~2

      This moves the branch pointer back by 2 commits, but all changes from those commits remain staged.

  • --mixed (default): Keeps changes in working directory, unstaged.

  • --hard: Discards all changes.

Example:

git reset --hard HEAD~1

This will move the branch pointer back by one commit and delete all changes from that commit.

  • Force push the reset changes to the remote
git push --force origin <your-branch-name>

Replace <your-branch-name> with the actual name of your branch. The --force flag is necessary because you are rewriting history and the remote branch will not accept a non-fast-forward push otherwise

Note

Use git reset --soft for safe undo, and git reset --hard only when you are sure you want to discard changes.

3. git checkout or git restore​

  • Used to restore files or commits to a previous state.

Restore a file to last committed state:

git restore <file>

Checkout a previous commit (detached HEAD):

git checkout <commit-hash>

Summary Table

CommandHistory Changed?Safe for Shared BranchesWhat It Does
git revertNoYesCreates a new commit to undo changes
git reset --hardYesNoDeletes commits & changes
git restore <file>NoYesRestores file to last commit
tip

Use git revert for undoing changes in public/shared branches.
Use git reset for local/private changes where history rewriting is safe.

How to Change the master Branch to main in Git​

If you want to rename your local master branch to main and update your remote repository, follow these steps:

1. Rename the local branch​

git branch -m master main

2. Fetch the latest branches from remote​

git fetch origin

3. Set the upstream branch for main​

git branch -u origin/main main

4. Update the remote HEAD reference​

git remote set-head origin -a

5. Push the new branch and update remote (if needed)​

If you have push access and need to update the remote branch name:

git push origin main
git push origin --delete master

Or, rename the branch on GitHub/Git server using the web interface.


Practical Daily Git Workflows and Safety Commands ​

This section collects practical commands that are especially useful when working with feature branches, deployment branches, and master/main.

Fetch the latest remote state safely​

git fetch downloads remote commits and updates remote-tracking references such as origin/master without modifying your current working branch.

git fetch origin

Fetch one branch only:

git fetch origin master

Fetch all remotes:

git fetch --all

Fetch and remove stale remote-tracking branches that were deleted on the server:

git fetch --prune

or:

git fetch origin --prune

After fetching, compare your local branch with the remote branch:

git status
git log --oneline HEAD..origin/master
git log --oneline origin/master..HEAD

Interpretation:

  • HEAD..origin/master shows commits that exist remotely but not locally.
  • origin/master..HEAD shows commits that exist locally but not remotely.

A compact branch overview:

git branch -vv

Show local and remote branches:

git branch -a

Show remote branches only:

git branch -r

Update the branch you actually intend to update​

To update local master:

git switch master
git pull --ff-only origin master

To update a feature branch from its own remote branch:

git switch feature/my-feature
git pull --ff-only origin feature/my-feature

git pull --ff-only is useful on branches where you do not want Git to create an automatic merge commit during pull.

If the command fails because the branches diverged, inspect the history before choosing merge or rebase:

git log --graph --oneline --decorate --all --max-count=30

Merge one feature branch into another feature branch​

Suppose:

feature/base-work
feature/next-work

and feature/next-work needs everything from feature/base-work.

Switch to the target branch first:

git switch feature/next-work
git fetch origin
git merge --ff-only feature/base-work

If --ff-only fails because both branches contain unique commits and you intentionally want to combine them:

git merge feature/base-work

Then push the target branch:

git push origin feature/next-work

Always remember:

git merge SOURCE_BRANCH merges SOURCE_BRANCH into the branch you currently have checked out.

Check your current branch before merging:

git branch --show-current

Merge a feature branch into master​

A safe fast-forward workflow:

git switch master
git pull --ff-only origin master
git fetch origin
git merge --ff-only feature/my-feature
git push origin master

This is ideal when master has not diverged from the feature branch's base.

If the feature branch exists only on the remote and you do not need a local copy, you can merge the remote-tracking branch:

git switch master
git pull --ff-only origin master
git fetch origin
git merge --ff-only origin/feature/my-feature
git push origin master

Merge a feature branch into another deployment branch, then promote to master​

A useful workflow when you maintain a deployment branch such as main-github:

# 1. Promote feature to deployment branch
git switch main-github
git pull --ff-only origin main-github
git merge --ff-only feature/my-feature
git push origin main-github

# 2. Verify deployment / CI

# 3. Promote the exact tested commit to master
git switch master
git pull --ff-only origin master
git merge --ff-only main-github
git push origin master

This keeps the code tested on the deployment branch identical to what is later promoted to master.

Why git merge --ff-only is useful​

git merge --ff-only feature/my-feature

Use it when you expect the target branch to be directly behind the source branch.

It will:

  • fast-forward when safe,
  • avoid creating an unexpected merge commit,
  • stop with an error when branches have diverged.

That failure is useful because it tells you to inspect the history instead of silently changing it.

Check whether a fast-forward is possible:

git merge-base --is-ancestor HEAD feature/my-feature

Exit code 0 means the current branch is an ancestor of the feature branch and can normally be fast-forwarded.

You can also compare branches:

git log --oneline master..feature/my-feature
git log --oneline feature/my-feature..master

Push the current branch​

Push the current branch to its configured upstream:

git push

Push and set upstream the first time:

git push -u origin feature/my-feature

After -u, normal git pull and git push know which remote branch to use.

Show the configured upstream:

git rev-parse --abbrev-ref --symbolic-full-name @{u}

Verify local and remote commits match​

Show the latest local commit:

git log --oneline -1

Show the latest commit for several local branches:

git log --oneline -1 master
git log --oneline -1 main-github
git log --oneline -1 feature/my-feature

Fetch first, then inspect remote-tracking branches:

git fetch origin
git log --oneline -1 origin/master
git log --oneline -1 origin/main-github
git log --oneline -1 origin/feature/my-feature

Compare commit hashes directly:

git rev-parse master
git rev-parse origin/master

If both hashes are identical, the local and remote branch tips match.

Check what will be merged before merging​

Commits in the feature branch that are not yet in master:

git log --oneline master..feature/my-feature

File-level summary:

git diff --stat master...feature/my-feature

Full diff:

git diff master...feature/my-feature

Name only:

git diff --name-only master...feature/my-feature

Check for whitespace problems before commit or merge​

Before committing:

git diff --check

For staged changes only:

git diff --cached --check

This is a quick and useful quality check before pushing code.

Create an empty commit to trigger CI/CD​

Sometimes you need to rerun a CI/CD pipeline without changing any file:

git commit --allow-empty -m "Triggering CI build"
git push

A Conventional Commit style alternative is:

git commit --allow-empty -m "ci: trigger build"
git push

An empty commit changes the commit history but does not change project files.

Use it when:

  • CI/CD did not run and you need another push event,
  • a deployment needs to be retriggered,
  • you want to verify pipeline configuration after changing repository-side settings or secrets.

Do not repeatedly create empty commits when the real issue is a failing build; fix the build error first.

Re-run CI without changing source code — when an empty commit is appropriate​

Typical flow:

git switch main-github
git pull --ff-only origin main-github
git commit --allow-empty -m "ci: trigger GitHub Pages build"
git push origin main-github

Because the commit is created on main-github, pushing it triggers workflows configured for pushes to that branch.

Amend the latest commit​

Change the most recent commit message:

git commit --amend -m "new commit message"

Add forgotten staged changes to the latest commit while keeping the same message:

git add <file>
git commit --amend --no-edit
warning

Amending changes the commit hash. Avoid amending commits that other people may already be using unless you understand the history-rewrite implications.

Undo the most recent local commit but keep the changes​

Keep changes staged:

git reset --soft HEAD~1

Keep changes but unstage them:

git reset HEAD~1

For a shared branch, prefer git revert instead of rewriting history.

Safely force-push rewritten history​

If you intentionally rebased or amended a branch that you alone control, prefer:

git push --force-with-lease

over:

git push --force

--force-with-lease refuses to overwrite the remote branch if somebody else pushed unexpected commits since your last fetch.

Compare git pull, git pull --rebase, and git pull --ff-only​

git pull

Fetches remote changes and then merges them into the current branch.

git pull --rebase

Fetches remote changes and reapplies your local commits on top of them. This keeps history linear but rewrites your local commit hashes.

git pull --ff-only

Fetches remote changes and updates the branch only when a fast-forward is possible. It refuses to create a merge commit.

A safe default for important shared branches such as master is often:

git pull --ff-only origin master

Inspect the exact current branch and repository state​

Current branch:

git branch --show-current

Working tree status:

git status

Short status:

git status --short

Show the current commit hash:

git rev-parse HEAD

Show the repository root directory:

git rev-parse --show-toplevel

Show which branches contain a commit:

git branch --contains <commit-hash>

Include remote branches:

git branch -a --contains <commit-hash>

Find the common ancestor of two branches​

git merge-base master feature/my-feature

This is useful when diagnosing branch divergence.

To check how far two branches differ:

git rev-list --left-right --count master...feature/my-feature

Example output:

2	5

means:

  • master has 2 commits not present in the feature branch,
  • the feature branch has 5 commits not present in master.

Clean stale local references​

Remove references to remote branches that no longer exist:

git fetch --prune

Delete a local feature branch after it has been merged:

git branch -d feature/my-feature

Force-delete an unmerged local branch only when you are certain:

git branch -D feature/my-feature

Delete a remote branch:

git push origin --delete feature/my-feature

Recover useful history with reflog​

If you accidentally reset, rebase, or move a branch and need to find the previous commit:

git reflog

Then inspect or restore a known commit:

git show <commit-hash>

or create a recovery branch:

git switch -c recovery-branch <commit-hash>

git reflog is one of the most useful recovery tools when a commit seems to have disappeared locally.

Practical pre-push checklist​

A useful sequence before pushing important changes:

git status
git diff
git diff --cached
git diff --check
git log --oneline --decorate -5

Then, when everything is correct:

git push

For a project with lint, tests, and build commands, run those project-specific checks before the push as well.

Quick reference: common branch promotion flows​

GoalCommands
Update local mastergit switch master → git pull --ff-only origin master
Update local feature branchgit switch feature/x → git pull --ff-only origin feature/x
Feature → featureswitch to target feature → git merge --ff-only source-feature → push target
Feature → masterswitch to master → update master → git merge --ff-only feature/x → push
Feature → deployment branchswitch to deployment branch → update it → git merge --ff-only feature/x → push
Deployment branch → masterswitch to master → update it → git merge --ff-only deployment-branch → push
Trigger CI without file changesgit commit --allow-empty -m "ci: trigger build" → git push
Check whitespacegit diff --check
Download remote state onlygit fetch origin
Remove stale remote refsgit fetch --prune
See branch graphgit log --graph --oneline --decorate --all --max-count=30
Compare ahead/behindgit rev-list --left-right --count branch-a...branch-b
Recover lost local commitgit reflog

Conventional Commit Format​

Many teams follow the Conventional Commits specification to write consistent, readable commit messages. It also enables automation tools to generate changelogs and auto-bump version numbers.

Format​

<type>(<optional scope>): <description>

Example:

git commit -m "feat(auth): add Google OAuth login"
git commit -m "fix(api): handle null response from payment service"
git commit -m "chore: update dependencies"

Common Types​

TypePurpose
featA new feature
fixA bug fix
choreMaintenance tasks (deps, config, tooling)
docsDocumentation changes only
styleCode formatting — no logic changes
refactorCode restructure — not a fix or feature
testAdding or fixing tests
perfPerformance improvements
ciCI/CD pipeline changes
revertReverting a previous commit

With Emoji (Gitmoji)​

Some teams use gitmoji instead of or alongside the text prefix:

EmojiTypeMeaning
✨featNew feature
🐛fixBug fix
🔧choreConfiguration / tooling
📝docsDocumentation
♻️refactorCode refactor
🚀perfPerformance improvement
✅testTests
👷ciCI/CD changes
⏪️revertRevert a commit

Both styles are equivalent — it's a team preference. Some projects combine them:

git commit -m "✨ feat: add dark mode toggle"
tip

Tools like commitlint (with a git hook) can enforce the conventional commit format automatically across your team.

Commit Message Tense​

Use the imperative (simple present) tense — even though the work is already done. This is the universal standard.

The reasoning: a commit message describes what the commit does when applied, not what you did. Think of it as a command:

"If you apply this commit, it will add dark mode toggle."

Git itself uses this convention in its own auto-generated messages (e.g. Merge branch 'main'). Major projects like the Linux kernel, React, and VS Code all follow imperative tense.

A helpful mental check: "If applied, this commit will ___."

✅ Correct (imperative)❌ Avoid
add dark mode toggleadded dark mode toggle
fix null pointer in authfixed null pointer in auth
update login stylesupdating login styles

Commit Type for CSS / UI Style Changes​

The style type sounds like it fits CSS changes, but it actually means code formatting (whitespace, semicolons, indentation) — not visual styling. For CSS or design changes, pick the type based on intent:

SituationType
Adding new CSS for a new UI featurefeat
Fixing a broken or incorrect stylefix
Tweaking/refining existing appearance (not a bug)refactor
Updating a CSS variable, theme, or design tokenrefactor or chore
Removing unused styleschore

Examples:

git commit -m "feat: add responsive styles for mobile nav"
git commit -m "fix: correct button alignment on Safari"
git commit -m "refactor: simplify card hover state CSS"
note

Some teams define a custom ui type specifically for visual/CSS changes since the built-in types can feel ambiguous here — but this is a team-level decision and not part of the official spec.


Resources​

  1. 10 Git Commands Every Developer Should Know
  2. Git Branching Commands Explained with Examples
  3. git commands
  4. Git Branches: List, Create, Switch to, Merge, Push, & Delete
  5. git stash and git pull - Stack Overflow
  6. Git Merge vs. Rebase: Key Differences
  7. How to Create Diagrams as Code with Mermaid, GitHub, and Visual Studio Code
  8. Creating diagrams
  9. The Ultimate Git Command Cheatsheet