Git Commands Guide

153 Git commands with descriptions, examples and copy-ready code, grouped by category and difficulty.

Advanced

git submodule add [repo_url] [path]

Adds external Git repository as submodule. Includes another repo in your project while keeping it separate.

git submodule add https://github.com/user/repo.git path/to/sub

git submodule init

Initializes submodules from .gitmodules file. Required before pulling submodule content.

git submodule init

git submodule update

Fetches and checks out correct commits for submodules. Ensures submodules match main repository.

git submodule update

git submodule foreach git pull

Runs git pull in every submodule directory. Updates all submodules at once.

git submodule foreach git pull

git worktree add [path] [branch]

Creates new working tree for multiple branches simultaneously. Work in different directories on different branches.

git worktree add ../bug-fix main

git worktree list

Lists all working trees created for this repository. Shows paths and branch information.

git worktree list

git worktree remove [path]

Removes a working tree. Cleans up directory and removes worktree reference.

git worktree remove ../bug-fix

git format-patch -n HEAD

Creates patch files from last N commits. Useful for emailing changes or applying to other repos.

git format-patch -1 HEAD

git apply [patch_file]

Applies changes from patch file to working directory. Git-aware version of patch command.

git apply fix.patch

git am [patch_file]

Applies patch and creates commit with original author/date metadata. Preserves patch commit info.

git am fix.patch

git cat-file -p [object]

Displays contents of a Git object. Useful for understanding Git's internal structure.

git cat-file -p abcd123

git hash-object [file]

Calculates Git hash for a file without staging/committing. Useful for comparing versions.

git hash-object index.html

git verify-commit [commit]

Verifies GPG signature of a commit. Ensures commit authenticity in secure environments.

git verify-commit abcd123

git filter-branch

Rewrites Git history. Advanced tool for removing sensitive data or restructuring. Affects other developers!

Caution: Rewrites the entire history and changes every commit hash. Back up first, and consider git filter-repo instead.

git filter-branch --tree-filter 'rm -f secrets.txt'

git for-each-ref

Lists all refs (branches, tags, remotes) with custom output format. Powerful for scripting.

git for-each-ref --sort=version:refname

Branching

git branch

Lists all local branches. The current branch is marked with an asterisk (*). Does not show remote branches.

git branch

git branch -a

Lists all branches: both local and remote-tracking branches. Gives complete picture of all branches in the repository.

git branch -a

git branch -r

Lists only remote-tracking branches. Shows branches that exist on the remote repository but may not be checked out locally.

git branch -r

git branch [branch_name]

Creates a new branch at the current commit. Does not switch to the new branch - you'll need to 'checkout' to start using it.

git branch feature-new-ui

git branch -d [branch_name]

Safely deletes a branch only if it has been fully merged. Git refuses to delete if there are unmerged commits, protecting you from losing work.

git branch -d feature-login

git branch -D [branch_name]

Forcefully deletes a branch regardless of merge status. Destructive - use only when absolutely sure you want to lose that branch.

Caution: Force-deletes the branch even if it has unmerged commits, which are then hard to recover.

git branch -D experimental-feature

git branch -m [old_name] [new_name]

Renames a branch. If you're on the branch you want to rename, you can omit the old name.

git branch -m old-name new-name

git branch -M main

Renames the current branch to 'main', forcefully overwriting if 'main' exists. Useful for changing default branch names.

git branch -M main

git branch --contains [commit]

Lists all branches that contain a specific commit. Helpful for finding which releases or branches include a particular change.

git branch --contains abcd123

git checkout [branch_name]

Switches your working directory to a different branch. Updates all files to match that branch's latest commit.

git checkout feature-new-ui

git checkout -b [branch]

Creates a new branch and immediately switches to it. Shortcut combining 'branch' and 'checkout' in one command.

git checkout -b feature-user-profile

git switch [branch_name]

Modern alternative to 'checkout' for switching branches. Cleaner syntax dedicated specifically to branch switching.

git switch feature-new-ui

git switch -c [branch]

Modern equivalent of 'checkout -b'. Creates and switches to a new branch using newer, cleaner Git syntax.

git switch -c feature-notifications

git checkout -

Switches to the previously checked-out branch. Quick way to toggle between two branches without typing the full name.

git checkout -

Configuration

git config --global user.name "Your Name"

Sets the author name for all your commits globally. This name identifies you across all repositories on your machine and appears in every commit's metadata.

git config --global user.name "John Doe"

git config --global user.email "your_email@example.com"

Sets the email address for all your commits globally. Essential for identifying the committer and appears alongside your name in all commits.

git config --global user.email "john@example.com"

git config --list

Displays all Git configuration settings from both global (~/.gitconfig) and repository-specific (.git/config) files. Useful for verifying your setup.

git config --list

git config --local user.name "Your Name"

Sets the author name for only the current repository, overriding global settings. Useful when working on different projects with different identities.

git config --local user.name "Work Name"

git config core.editor [editor]

Sets the default text editor for Git (used when writing commit messages). Examples: vim, nano, code, gedit.

git config --global core.editor "code --wait"

git update-index --assume-unchanged [file]

Tells Git to ignore changes to a file without removing it from version control. Useful for configs.

git update-index --assume-unchanged config.json

git update-index --no-assume-unchanged [file]

Resumes tracking changes to a file marked with --assume-unchanged.

git update-index --no-assume-unchanged config.json

Debugging

git bisect start

Initiates binary search to find which commit introduced a bug. Interactive process marking commits good/bad.

git bisect start

git bisect bad

Marks current commit as 'bad' during bisect. Continues searching in earlier history.

git bisect bad

git bisect good

Marks current commit as 'good' during bisect. Continues searching in later history.

git bisect good

git bisect reset

Ends bisect session and returns to original branch. Use after finding problematic commit.

git bisect reset

Help & Documentation

git help [command]

Opens documentation for a specific Git command. Provides comprehensive help within terminal.

git help commit

git --version

Displays your installed Git version. Useful for checking compatibility and features.

git --version

History & Inspection

git log

Displays commit history of current branch with hash, author, date, and message. Shows newest commits first. Press 'q' to exit.

git log

git log --oneline

Compact commit history with abbreviated hashes and single-line messages. Quick overview of recent commits.

git log --oneline

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

Visualizes commit history as a graph showing branches and merges. Great for understanding repository structure.

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

git log -p

Shows detailed commit history with full diffs (patches) for each commit. Verbose but shows exact line changes.

git log -p

git log --stat

Shows history with statistics: which files changed and how many lines added/removed. Summary view of changes.

git log --stat

git log --follow [file]

Shows complete history of a file including renames. Traces file's evolution across name changes.

git log --follow index.html

git log --author="[name]"

Filters commit history to show only commits by a specific author. Useful for finding who made certain changes.

git log --author="Majid Ali"

git log --grep="[pattern]"

Searches commit messages for pattern matching. Finds commits about specific features, bugs, or keywords.

git log --grep="bug fix"

git log --since=[date]

Shows commits after a specific date. Format: YYYY-MM-DD or relative (2.weeks, 1.month, etc.).

git log --since=2024-01-01

git log --until=[date]

Shows commits before a specific date. Can combine with --since for date range queries.

git log --until=2024-12-31

git log -n [number]

Limits output to the last N commits. Useful for focusing on recent history.

git log -n 5

git show [commit]

Shows detailed information about a specific commit: changes, author, date, and full diff.

git show abcd123

git diff

Shows changes between working directory and last commit. Reveals what you've modified but not staged.

git diff

git diff --cached

Shows differences between staged changes and last commit. Review what's about to be committed.

git diff --cached

git diff [branch1] [branch2]

Compares all changes between two branches. Shows what would differ if you merged them.

git diff main feature-branch

git diff [commit1] [commit2]

Shows differences between two commits. Useful for understanding what changed between versions.

git diff abcd123 efgh456

git diff --name-only [branch1] [branch2]

Lists only filenames that differ between two branches. Useful for seeing what changed without diffs.

git diff --name-only main feature

git diff --stat [commit1] [commit2]

Shows summary of changes between commits with file statistics. Concise view of impact.

git diff --stat abcd123 efgh456

git shortlog

Summarizes commit history grouped by author with counts. Shows who contributed how much.

git shortlog

git blame [file]

Shows who last modified each line of a file and in which commit. Useful for understanding code history.

git blame index.html

git grep [pattern]

Searches tracked file contents for a pattern. Git-aware version of grep, faster and version-aware.

git grep "TODO"

Merging & Rebasing

git merge [branch_name]

Combines commits from another branch into your current branch. Creates a merge commit linking the two branches' histories.

git merge feature-login

git merge --no-ff [branch]

Merges while creating a merge commit even if fast-forward is possible. Preserves branch structure in history for better traceability.

git merge --no-ff feature-settings

git merge --squash [branch]

Combines all commits from another branch into a single commit before merging. Cleans up history by consolidating branch work into one commit.

git merge --squash feature-temp-work

git merge --abort

Cancels an ongoing merge process if you encounter conflicts or change your mind. Returns to the state before the merge started.

git merge --abort

git rebase [branch]

Re-applies your commits on top of another branch. Creates cleaner, linear history compared to merging by replaying commits.

Caution: Rewrites commit history. Don't rebase commits that others have already pulled.

git rebase main

git rebase -i [commit]

Interactive rebase - reorder, squash, or edit commits. Powerful tool for cleaning up commit history before pushing.

Caution: Rewrites commit history. Don't rebase commits that others have already pulled.

git rebase -i HEAD~3

git rebase --abort

Cancels an ongoing rebase if you encounter conflicts or issues. Returns to the state before rebase started.

git rebase --abort

git rebase --continue

Resumes a paused rebase after resolving conflicts. Git continues applying the remaining commits.

git rebase --continue

git cherry-pick [commit]

Applies changes from a specific commit onto your current branch. Useful for selectively bringing in changes without merging entire branches.

git cherry-pick abcd123

git cherry-pick [commit1] [commit2] ...

Cherry-picks multiple specific commits in sequence. Useful for integrating several commits without merging.

git cherry-pick abcd123 efgh456

git cherry-pick --abort

Cancels an ongoing cherry-pick operation. Returns to the state before cherry-pick started.

git cherry-pick --abort

Remote

git remote add [name] [url]

Connects your repository to a remote repository with a given name (usually 'origin'). Enables pushing and pulling from that remote.

git remote add origin https://github.com/user/repo.git

git remote -v

Lists all configured remotes with their fetch and push URLs. Shows where your code is being pushed to and pulled from.

git remote -v

git remote show [remote_name]

Displays detailed information about a remote: branches, tracking configuration, and current status.

git remote show origin

git remote rm [name]

Removes a remote repository connection from your local configuration. Does not affect the actual remote repository.

git remote rm old-remote

git remote rename [old_name] [new_name]

Renames a remote connection in your configuration. Useful when changing how you reference a remote.

git remote rename origin upstream

git remote set-url [remote_name] [new_url]

Changes the URL of an existing remote. Useful when migrating repositories or switching between HTTPS and SSH.

git remote set-url origin https://github.com/new-user/new-repo.git

git push -u origin [branch]

Pushes a branch to remote and sets it as the upstream. The -u flag establishes tracking - essential for first push of new branches.

git push -u origin feature-login

git push [remote] [branch]

Uploads commits from your local branch to the remote. After initial -u setup, just use this simpler form.

git push origin main

git push --all

Pushes all local branches to the remote at once, rather than pushing them individually.

git push --all

git push --force

Forces a push even if it overwrites remote commits. Use with extreme caution - can cause loss for other team members. Only use in private branches.

Caution: Overwrites the remote history and can erase teammates' commits. Prefer --force-with-lease.

git push --force origin feature-branch

git push --force-with-lease

Safer alternative to --force that only overwrites if no one else has pushed. Protects against accidentally losing others' work.

Caution: Still rewrites remote history. Fetch first and only use it on branches you own.

git push --force-with-lease origin feature-branch

git push [remote] --delete [branch]

Deletes a branch on the remote repository. Useful for cleaning up old feature branches after merging.

Caution: Deletes the branch on the remote for everyone who uses it.

git push origin --delete feature-old

git push --tags

Pushes all local tags to remote without pushing any commits. Useful for publishing release versions.

git push --tags

git pull [remote] [branch]

Fetches and merges changes from a remote branch into your current branch. Combines 'fetch' and 'merge' in one command.

git pull origin main

git pull

Pulls from the tracked upstream branch (usually the branch you've previously pushed). Uses branch tracking to know where to pull from.

git pull

git pull --rebase

Fetches changes and rebases your commits on top instead of merging. Keeps history linear and clean without merge commits.

git pull --rebase origin

git fetch [remote]

Downloads new commits and objects from remote without merging. Updates remote-tracking branches but leaves your working directory untouched.

git fetch origin

git fetch --prune

Fetches and removes stale remote-tracking branches for branches that no longer exist on remote. Cleans up deleted branches.

git fetch --prune

git fetch --all

Fetches updates from all remote repositories, not just the default 'origin'. Useful when working with multiple remotes.

git fetch --all

Repository

git clone [url]

Creates a complete local copy of a remote repository. Downloads all commits, branches, and history from the remote source (GitHub, GitLab, Bitbucket, etc.).

git clone https://github.com/Majid-Ali-Watto/Git-factory.git

git clone [url] [directory]

Clones a repository into a custom directory with a name of your choice instead of using the repository's default name.

git clone https://github.com/user/repo.git my-project

git clone --depth 1 [url]

Creates a shallow clone with only the latest commit history. Much faster and smaller download, useful when you don't need full history.

git clone --depth 1 https://github.com/user/repo.git

git clone --mirror [url]

Creates a bare mirror of a repository (no working directory). Used for backing up or duplicating repositories.

git clone --mirror https://github.com/user/repo.git repo.git

git init

Initializes a new Git repository in the current directory. Creates the necessary .git folder and metadata to start tracking project changes.

git init

git init [directory]

Creates a new Git repository in a specified directory and initializes it with Git's internal structure.

git init my-project

git reflog

Shows log of all HEAD movements: commits, resets, rebases, etc. Useful for recovering lost commits.

git reflog

git fsck --lost-found

Scans for lost commits and objects in the repository. Can help recover work lost to resets.

git fsck --lost-found

git gc

Garbage collection - removes unreachable objects and optimizes database. Improves performance.

git gc

git archive [branch] --format=zip --output=[file.zip]

Creates zip archive of a branch without .git directory. Useful for distributing clean versions.

git archive main --format=zip --output=project.zip

git mv [old_path] [new_path]

Moves or renames a file while preserving Git history. Automatically stages the change.

git mv old-name.txt new-name.txt

Repository Information

git rev-parse HEAD

Returns the full commit hash of the current HEAD. Useful for scripts and CI/CD automation.

git rev-parse HEAD

git rev-parse --short HEAD

Returns abbreviated (7-char) version of current commit hash. More readable for display.

git rev-parse --short HEAD

git rev-parse --abbrev-ref HEAD

Returns the name of the current branch. Useful for scripts needing to know current branch.

git rev-parse --abbrev-ref HEAD

git describe --tags

Shows the most recent tag reachable from current commit. Useful for determining version.

git describe --tags

git ls-files

Lists all files currently tracked by Git. Useful for seeing what's under version control.

git ls-files

git symbolic-ref HEAD

Shows what branch HEAD is pointing to. Returns current branch reference.

git symbolic-ref HEAD

git name-rev [commit]

Shows human-readable name for a commit relative to tags/branches. Useful for commit description.

git name-rev abcd123

Staging & Committing

git status

Shows the current state of your working directory and staging area. Displays modified, staged, and untracked files with helpful next-step suggestions.

git status

git status -s

Short format of git status. Shows file state using abbreviations (M=modified, A=added, D=deleted, etc.) for a compact view.

git status -s

git status --porcelain

Machine-readable status output. Designed for scripts and automation tools that need to parse repository state programmatically.

git status --porcelain

git add [file]

Stages changes to a specific file for the next commit. Tells Git to include this file in your next commit snapshot.

git add index.html

git add .

Stages all modified and new files in the current directory and subdirectories. Quick way to stage everything you've changed.

git add .

git add -A

Stages all changes globally: modified, new, and deleted files across the entire repository. Different from 'git add .' which doesn't include deletions.

git add -A

git add -p

Interactive staging mode - review your changes hunk by hunk and choose which ones to stage. Great for crafting clean commits with only related changes.

git add -p

git add -u

Stages only modified and deleted files - not new untracked files. Useful when you've changed existing files but added nothing new.

git add -u

git commit -m "Commit message"

Records staged changes to the repository with a descriptive message. The message should summarize what changed and why - keep it clear and concise.

git commit -m "Fix: Resolve login form validation bug"

git commit -m "Title" -m "Description"

Creates a commit with both a title and detailed description. First message is the short title, second provides context and explanation.

git commit -m "Add user authentication" -m "Implements JWT-based auth with refresh tokens"

git commit -a

Stages and commits all tracked files that have been modified. Skips the staging step for known files (won't include new untracked files).

git commit -a

git commit --amend

Modifies the most recent commit by adding new staged changes or changing the commit message. Opens editor for message editing.

Caution: Rewrites the last commit. Don't amend a commit you've already pushed to a shared branch.

git commit --amend

git commit --amend --no-edit

Adds staged changes to the last commit without changing its message. Quick way to add forgotten files to previous commit.

Caution: Rewrites the last commit. Don't amend a commit you've already pushed to a shared branch.

git commit --amend --no-edit

git commit --allow-empty -m "message"

Creates a commit with no changes. Useful for triggering CI/CD pipelines or creating milestone commits with no actual code changes.

git commit --allow-empty -m "Trigger CI/CD pipeline"

git rm --cached -r [directory]

Stops tracking a directory in Git without deleting it locally. Useful for removing accidentally tracked folders.

git rm --cached -r dev-dist/

Stashing

git stash

Temporarily saves work-in-progress changes without committing. Cleans your working directory so you can switch branches or pull updates.

git stash

git stash save "Work in progress"

Stashes changes with a descriptive message for easier identification when reviewing stashes later.

git stash save "WIP: User auth form"

git stash list

Lists all stashed changes with references (stash@{0}, stash@{1}, etc.). Helps you track saved work.

git stash list

git stash apply

Applies a stash back to your working directory without removing it from the stash list. Stash remains available.

git stash apply stash@{0}

git stash pop

Applies the most recent stash and removes it from the stash list. One-command alternative to apply + drop.

git stash pop

git stash drop [stash]

Permanently deletes a specific stash. Once dropped, the stashed changes cannot be recovered.

Caution: Permanently removes this stash entry.

git stash drop stash@{0}

git stash clear

Permanently deletes all stashes. Cannot be undone - use with caution!

Caution: Deletes every stash and cannot be undone.

git stash clear

git stash show

Shows the changes in a stash without applying it. Useful for previewing what's in a stash before applying.

git stash show stash@{0}

git stash branch [branch_name]

Creates a new branch and applies a stash to it. Useful if you stashed work and then made conflicting changes.

git stash branch my-stash-branch

Tagging

git tag [tag_name]

Creates a lightweight tag pointing to the current commit. Tags mark specific points in history like release versions.

git tag v1.0.0

git tag -a [tag_name] -m "message"

Creates an annotated tag (preferred method) with descriptive message, author, and timestamp. More durable than lightweight tags.

git tag -a v1.0.0 -m "Release version 1.0.0"

git tag

Lists all tags in the repository. Shows all marked releases and versions.

git tag

git tag -l [pattern]

Lists tags matching a pattern. Useful for filtering tags by version numbers or prefixes.

git tag -l 'v1.*'

git show [tag_name]

Shows detailed information about a tag including the tagged commit, tagger, date, and message.

git show v1.0.0

git tag -d [tag_name]

Deletes a tag from the local repository. Useful for removing accidentally created or outdated tags.

git tag -d v1.0.0

git push origin [tag_name]

Pushes a specific tag to the remote repository, making it available to other team members and CI/CD systems.

git push origin v1.0.0

git push origin --delete [tag]

Deletes a tag from the remote repository. Useful for cleaning up mistagged versions.

Caution: Removes the tag from the remote for everyone who uses it.

git push origin --delete v0.9.0

Undoing Changes

git reset [file]

Unstages a file from the staging area. Changes remain in working directory - safe operation.

git reset myfile.txt

git reset --soft [commit]

Moves HEAD to a previous commit while keeping changes staged. Useful for reorganizing commits.

git reset --soft abcd123

git reset --mixed [commit]

Moves HEAD and unstages changes. Files remain modified but not staged. Default reset behavior.

git reset --mixed abc123

git reset --hard [commit]

Completely resets to a previous commit, discarding all changes. Destructive - use with caution!

Caution: Permanently discards all uncommitted changes in tracked files.

git reset --hard abcd123

git revert [commit]

Creates a new commit that undoes changes from a previous commit. Safe for shared branches - preserves history.

git revert abcd123

git checkout -- [file]

Discards local changes to a file, restoring it to the last commit. Destructive - cannot be undone.

Caution: Permanently discards your uncommitted changes to the file.

git checkout -- index.html

git restore [file]

Modern alternative to 'checkout --'. Restores a file to its committed state, discarding changes.

Caution: Permanently discards your uncommitted changes to the file.

git restore index.html

git restore --staged [file]

Unstages a file without affecting working directory. Modern alternative to 'git reset'.

git restore --staged myfile.txt

git clean -df

Removes untracked files and directories. Destructive - use 'git clean -dn' to preview first!

Caution: Permanently deletes untracked files and directories. Preview first with git clean -dn.

git clean -df

git clean -dn

Shows what untracked files would be deleted without actually deleting. Safe preview for 'git clean -df'.

git clean -dn