Git

Setup and Configuration

Command Name Description
git config --global user.name "Name" User Name Set the author name for all Git repositories at the global level. This name appears in all your commits. The --global flag applies the setting to all user repositories. Without --global, the setting applies only to the current repository. Example: git config --global user.name "Vlad". To temporarily override in a specific repository, use the command without --global or the GIT_AUTHOR_NAME environment variable.
git config --global user.email "mail@example.com" User Email Set the author email address for all commits at the global level. Email is attached to each commit and used for author identification. It's important to specify a correct email, especially when working with GitHub/GitLab — it must match the verified email for push. For privacy on GitHub, use no-reply emails like id+noreply@github.com. To check the setting: git config user.email.
git config --list View Configuration Shows all active Git settings combined from files: ~/.gitconfig (global), .git/config (repository) and system settings. Settings are displayed in the format section.key = value. In case of conflict, priority is: local > global > system. To view a specific value: git config user.name. To edit using GUI: git config --edit.
git help Help Opens Git's built-in help system. Shows detailed documentation for commands, including options, examples, and links to additional information. For help on a specific command: git help config or git config --help. To search help: git help -g (list of groups), git help -a (all commands). In Windows it opens an HTML page, in Linux — a man page.
git version Git Version Shows the installed Git version in the system. Output format: git version X.Y.Z. Useful for compatibility diagnostics — some commands are available only in new versions. For example, git switch and git restore appeared in Git 2.23+. To check Git availability: git --version (equivalent). On CI/CD servers, a specific Git version is often required.
git bugreport Create Bug Report Generates a detailed diagnostic report for bug reports. Includes Git version, system information, configuration, paths and environment. Output is directed to the terminal or file. Use before submitting a bug: git bugreport | git compress. Alternative — git env for outputting only environment variables. Useful when debugging Git problems on complex configurations.

Creating and Cloning a Repository

Command Name Description
git init Create Repository Initializes a new Git repository in the current directory, creating a hidden folder .git/ with metadata. After execution, you can start tracking files. To initialize in a specific directory: git init /path/to/dir. To initialize with an initial branch (Git 2.28+): git init -b main. The --bare flag creates a "bare" repository without a working directory (for a server). The --separate-git-dir flag allows placing .git elsewhere.
git clone https://github.com/user/project.git Clone Repository Downloads a full copy of the remote repository into a local directory, including all commit history, all branches and tags. By default, it creates a local branch main or master with tracking of the remote branch under the name origin. To clone into a specific directory: git clone url new-dir/. Supports protocols: https://, ssh://, git@. For SSH authentication, set up keys: ssh-keygen + add key to GitHub/GitLab.
git clone --depth 1 repo-url Shallow Clone Clones a repository with limited commit history (--depth 1 = only the latest commit). Significantly speeds up cloning of large repositories (e.g., Linux kernel). git log history will contain only 1 commit. To increase depth after cloning: git fetch --depth 10. With Git 2.24+, you can convert shallow clone to full: git fetch --unshallow. Does not support git branch and git tag without additional git fetch.
git clone --branch dev repo-url Clone Branch Clones a specific branch instead of the default branch. Useful when working with monorepos or when you need to get a specific branch immediately. To clone a specific branch with tracking: git clone --branch dev --single-branch url. The --single-branch flag limits download to only one branch (saves space). You can clone a tag: git clone --branch v1.0 --depth 1 url to get a specific version.

Staging and File Changes

Staging area (index) — intermediate storage for changes before creating a commit. Git tracks only files added to staging.

Command Name Description
Adding Files to Staging
git add app.js Add Files Adds the specified file to the staging area, preparing it for commit. After git add, file changes will be included in the next commit. You can add multiple files: git add file1.js file2.css. Supports glob patterns: git add *.md (all Markdown files). To add only new (untracked) files, use git add -N (incremental). Files that don't exist in the repository need to be added explicitly — Git doesn't track them automatically.
git add . Add All Changes Adds all modified and new files in the current directory and subdirectories recursively. The dot . means "current directory". Important: git add . does not add files that were previously ignored via .gitignore. Also does not add completely new (untracked) files in subdirectories if they were not previously tracked. To add all untracked files, use git add -A or git add --all.
git add -A Add All Changes Adds all changes: new (untracked), modified and deleted files relative to the specified directory. Unlike git add ., git add -A also records deletions of files that were previously in the repository. Works faster for large projects. Alternative: git add --all (full equivalent). To add only modified files: git add -u (update).
git add -p Interactive Add Allows selecting specific hunks of changes to add to staging. Opens interactive mode with prompts: y (add), n (skip), q (quit), a (rest), s (split), e (manual). Useful for large changes when you need to add only part of fixes. For example, you fixed a bug and added a new feature — you can add only the bug fix hunks. Alternative: git add --patch (full equivalent).
Restoring and Deleting
git restore index.js Restore Files Restores a file from the latest version in the working directory (undoes unstaged changes). By default, restores from HEAD (latest commit). To restore from staging: git restore --source=HEAD index.js. To restore to a specific version: git restore --source=abc123 index.js. To restore all files: git restore .. Alternative: git checkout -- index.js (classic syntax).
git restore --staged app.js Remove from Staging Removes a file from the staging area (index), but keeps changes in the working directory. The file remains modified but will not be ready for commit. Similar to git reset HEAD app.js. To remove all files from staging: git restore --staged .. With Git 3.0+, you can use --worktree for simultaneous restore and working directory.
git rm old.js Delete File Removes a file from the Git repository and filesystem. The file is automatically added to staging for the next commit. After git commit, the file will be completely deleted. To remove only from Git (keeping file on disk): git rm --cached old.js. To remove a directory: git rm -r dir/. To remove by pattern: git rm *.log. A deleted file can be restored: git restore old.js (before commit) or git checkout HEAD~1 -- old.js (after commit).
git rm --cached .env Remove from Git Removes a file only from Git tracking, but leaves it in the working directory. Useful for files with confidential data (.env, config.php) that accidentally entered the repository. After removal, add the file to .gitignore so it doesn't enter the repository again. Example: git rm --cached .env && echo ".env" >> .gitignore && git add .gitignore. The file remains on disk but stops being tracked.
git mv old.js new.js Rename File Moves or renames a file with automatic staging. Git tracks renames through content analysis. Alternative: mv old.js new.js && git add new.js && git rm old.js (manual equivalent). To move to another directory: git mv src/old.js dst/new.js. After commit, the rename will correctly appear in history: git log --follow new.js (--follow flag tracks renames).
Status
git status Repository Status Shows the current repository state: which files are modified, which are in staging, which are untracked. Output is divided into sections: "Changes to be committed" (in staging) and "Changes not staged" (not in staging). Shows the current branch and its status relative to remote. Useful flags: -sb (concise output with branch), -uno (show only untracked files). To automatically run status on each action: git config status.submoduleSummary true.
git status --short Concise Status Outputs a concise status format convenient for parsing by scripts. Each line: XY filename, where X is the index status, Y is the working directory status. Codes: A (added), M (modified), D (deleted), ? (untracked), R (renamed), U (unmerged). For color indication: --porcelain (stable format for scripts). To output only untracked: git status --short --untracked-files=no.

Checking Status and Differences

These commands help analyze changes, view history and understand what happened in the repository.

Command Name Description
git diff Differences Shows differences between the working directory and staging area (or the latest commit). Outputs line-by-line changes: + — added lines, - — removed. Useful before git add to verify what you're adding. Flags: --stat (change statistics), --color-words (highlight changed words), -W (show only functions). To compare a specific file: git diff app.js. To ignore whitespace: git diff -w.
git diff --staged Staged Differences Shows differences between staging area and the latest commit (HEAD). Useful before commit to verify what will be committed. Alternative: git diff --cached (full equivalent). To compare with a specific version: git diff --staged abc123. Combined with --name-only shows only changed file names: git diff --staged --name-only.
git show HEAD View Git Object Shows the contents of the specified Git object: commit, tag or file. HEAD is the latest commit in the current branch. Shows commit metadata (author, date, message) and diff changes. To view a specific commit: git show abc123. For a file: git show HEAD:app.js (output file contents from commit). For a tag: git show v1.0. For the first N lines of diff: git show --stat HEAD.
git log Commit History Shows full commit history of the current branch with metadata (author, date, hash). By default, outputs: hash, author name, date and message. For navigation, use vim-like commands: j (down), k (up), q (exit). Flags: -p (show diff), --stat (file statistics), --since="2 weeks ago" (last 2 weeks), --author="Vlad" (specific author), --grep="fix" (by message).
git log --oneline Concise History Compact output: short hash (7 characters) and message of each commit on one line. Ideal for quick history review. Combine with other flags: git log --oneline --graph --all (graph of all branches), git log --oneline -20 (last 20 commits), git log --oneline --since="2024-01-01" (from a specific date). To output with line numbers in diff: git log -p --oneline.
git log --graph Branch Graph Visualizes repository branching with ASCII graphics, showing how branches merge and diverge. Combine with --oneline and --all for full overview: git log --oneline --graph --all --decorate. The --decorate flag adds tag names and remote branches. To limit depth: git log --oneline --graph --max-count=50. Useful for understanding project structure before merge/rebase.
git blame app.js Line Author Shows line-by-line who and when changed each line of a file. Outputs: commit hash, author, line number, content. Useful for finding the source of bugs ("who wrote this?"). Flags: -L 10,20 (lines 10-20), -C (account for moved lines), -M (account for copied lines), -w (ignore whitespace). To view in real-time: git blame -p app.js | less. For a specific commit: git blame abc123 -- app.js.

Commit

Commit — a snapshot of the repository state at a specific point in time. Each commit has a unique hash, author, date and message.

Command Name Description
git commit Create Commit Creates a commit from staged changes, opening a text editor (vim/nano) for the message. The commit message should describe what changed: feat: add login page, fix: resolve null pointer. After saving the editor, the commit is created automatically. To configure the editor: git config core.editor "code --wait". To cancel: Ctrl+C in vim (without saving). Commit is created locally — to publish, use git push.
git commit -m "Fix login bug" Commit with Message Creates a commit with a single-line message, without opening the editor. Useful for automation and quick commits. Message is enclosed in quotes: -m "message". For multi-line message: git commit -m "Title" -m "Detailed description". Convention: use the format type: description (Conventional Commits): feat, fix, docs, style, refactor, test, chore.
git commit --amend Amend Commit Modifies the last commit: replaces it with a new one with an edited message or staged changes. Useful for fixing typos in the message or adding forgotten files. If staging is empty — only the message is edited. If there are staged files — they are added to the last commit. IMPORTANT: amend changes the commit hash — don't use for already published branches. To modify a commit in the middle of history: git rebase -i.
git commit --amend --no-edit Amend Commit Adds staged changes to the last commit, preserving the original message. Used when you forgot to add files: git add missed.js && git commit --amend --no-edit. Date and author of the commit are preserved. Commit hash will change. Alternative: git commit --amend -C HEAD (equivalent syntax). To add without amend: create a new commit.

Branches

A branch is an independent development path. By default, all changes go to the main or master branch. Branches allow parallel work on different features without interfering with the main code.

Command Name Description
Listing and Creating Branches
git branch List Branches Shows all local branches, current branch marked with an asterisk *. To include information about the latest commit: git branch -v. To show remote branches: git branch -a (all), git branch -r (remote only). To search branches with a specific name: git branch -a | grep feature. To show merged branches: git branch --merged. To show unmerged: git branch --no-merged (dangerous to delete).
git branch feature-auth Create Branch Creates a new branch with the specified name, pointing to the same commit as the current branch. Branch is created instantly (lightweight operation). To create from another branch: git branch feature-auth main. To create and immediately switch: git switch -c feature-auth or git checkout -b feature-auth. Branch names: lowercase letters, dashes, no spaces. Allowed: feature/user-login, fix/header-bug, hotfix/security.
git branch -d old-feature Delete Branch Deletes the specified local branch, but only if it is merged with the current branch (safe deletion). If the branch is not merged — Git will ask for confirmation. After deletion, commits remain accessible via git reflog. To delete all merged branches: git branch --merged | grep -v '\*' | xargs git branch -d. Delete a remote branch separately: git push origin --delete old-feature.
git branch -D Force Delete Forcefully deletes a branch regardless of its merge status. Equivalent to git branch --delete --force. Use with caution — unmerged commits may become difficult to access. Usually applied to remote branches: git branch -D origin/old-feature. Before deletion, verify: git branch --no-merged will show which branches are not merged. For safety, first run git log old-feature to check.
Switching Branches
git switch Switch Branch Modern replacement for git checkout for switching branches (Git 2.23+). Switches the working directory to the specified branch, updating files. To switch: git switch main. If the branch doesn't exist and you need to create: git switch -c new-branch. To return to the previous branch: git switch -. Unlike checkout, switch is not used for checking out files/commits — for that there is git restore.
git switch -c feature-api Create + Switch Creates a new branch from the current HEAD and immediately switches to it. The -c flag means "create". Equivalent: git checkout -b feature-api (classic). You can create from another branch: git switch -c feature-api main (from main, not from current). After creation, tracking with origin is automatically set (if it exists). Useful in workflow: git switch -c feature/$(echo $ISSUE | tr '[:lower:]' '[:upper:]').
git checkout Checkout Object Universal command for checking out objects. Historically used for branches, but also works with commits/tags/files. For branches: git checkout main. To create: git checkout -b feature-api. For files: git checkout -- app.js (restore file). For a commit: git checkout abc123 (detached HEAD). In Git 2.23+, it is recommended to separate: git switch for branches, git restore for files.
git checkout Checkout Commit Switches the repository to "detached HEAD" mode — you can browse code at a specific commit without creating a branch. Working directory is updated to the state of this commit. Useful for viewing old versions: git checkout abc123, git checkout v1.0. To create a branch from this state: git checkout -b view-branch. To return: git checkout main. In detached mode, you can't make a commit without creating a branch.

Merge / Rebase / Cherry-pick

These commands merge changes from different branches. Merge creates a merge commit, rebase moves commits to another branch, cherry-pick copies individual commits.

Command Name Description
git merge develop Merge Branches Combines the specified branch into the current one, creating a merge commit (or fast-forward without a new commit). During fast-forward (branch didn't diverge), no new commit is created. During a merge conflict: Git will leave markers <<<<< / ======= / >>>>> in files — resolve manually, then git add + git commit. To create a merge without fast-forward: git merge --no-ff develop (preserves branch history). To merge with a specific message: git merge develop -m "Merge feature-auth".
git merge --abort Abort Merge Aborts the current merge and returns the repository to its initial state. Works only during a merge conflict. After resolving the conflict, --abort will not work. To abort after git commit, use git reset --hard HEAD~1. Alternative: git merge --abort is equivalent to git reset --merge. Before merging, always run git status to check working directory cleanliness.
git rebase Rebase Branch Transplants all commits from the current branch onto the tip of another branch, creating a linear history. Unlike merge, it doesn't create a merge commit — commits are rewritten. Useful for maintaining a clean history. To rebase onto main: git rebase main. Before rebasing, verify that the branch is not published — rebase changes commit hashes. For published branches, use git merge. To prevent accidental rebasing: git config --global rebase.verifyRemoteRefs false.
git rebase -i Interactive Rebase Opens an interactive editor for editing commit history. Allows: pick (keep), reword (change message), edit (stop for changes), squash (combine with previous), fixup (combine, keeping previous message), drop (delete), exec (run command). For the last N commits: git rebase -i HEAD~5. To rebase onto a specific commit: git rebase -i abc123. Order in the editor = execution order (top — oldest).
git rebase --continue Continue Rebase Continues rebase after resolving conflicts. After resolving conflicts in files: git add (check via git diff), then git rebase --continue. To skip a commit: git rebase --skip. To abort: git rebase --abort. During interactive rebase, conflicts may occur for each commit — repeat the process. For automatic conflict resolution: git config rerere.enabled true (rerere — reuse recorded resolution).
git rebase --abort Abort Rebase Completely aborts the current rebase and returns to the initial state. Works at any point during the rebase process. After abort, the repository fully returns to the state before git rebase. All conflict resolutions are lost. To save a rebase point: git reflog will show a new HEAD. Before abort, verify you won't lose important data.
git cherry-pick Apply Commit Applies changes from the specified commit to the current branch, creating a new commit with the same changes. Useful for transferring fixes between branches: git cherry-pick abc123. For multiple commits: git cherry-pick abc123 def456 (sequentially). For a range: git cherry-pick abc123..def456. For the last commit: git cherry-pick HEAD~1. During conflict: resolve and git cherry-pick --continue. To abort: git cherry-pick --abort. To apply without commit (only changes): git cherry-pick -n abc123 (no-commit).
git cherry-pick --abort Abort Cherry-pick Aborts the current cherry-pick when a conflict occurs. Returns the repository to the state before cherry-pick. Works only during a conflict. After abort, all staged changes from cherry-pick are lost. To abort an already applied cherry-pick: git revert HEAD (creates a canceling commit).

Working with Remote Repositories

Remote repositories are remote code storage (GitHub, GitLab, Bitbucket). By default, the main remote is named origin. Working with remotes allows synchronizing local and remote repositories.

Command Name Description
git remote -v List Remotes Shows all configured remote repositories with URLs. The -v flag (verbose) shows the remote name and full URL. Usually there is origin (main) and possibly upstream (for forks). For a specific remote: git remote -v | grep origin. To check availability: git ls-remote origin. To show only names: git remote. To show only URLs: git remote get-url origin.
git remote add origin repo-url Add Remote Adds a remote repository with the specified name and URL. The origin name is the default standard. To add multiple remotes (e.g., for fork workflow): git remote add upstream https://github.com/original/repo.git. To check duplicates: git remote. To change URL: git remote set-url origin new-url. To test the connection: git ls-remote origin (should return a list of branches).
git fetch Fetch Changes Downloads changes from remote to the local repository WITHOUT merging. After fetch, you can review changes before merging. Downloads remote branches as origin/branch-name. To fetch a specific remote: git fetch origin. For a specific branch: git fetch origin main. For all remotes: git fetch --all. To track new branches: git fetch --prune (removes deleted remote branches from local cache). For monitoring: git fetch --progress (shows progress).
git pull Fetch + Merge Runs git fetch + git merge in one command. Downloads changes and automatically merges with the current branch. Equivalent: git fetch && git merge origin/main. For a specific remote/branch: git pull origin develop. During conflict: resolve and git commit. For automatic stash before pull: git pull --autostash. To abort an unsuccessful pull: git reset --hard ORIG_HEAD. Use with caution in team work — may create unexpected merge commits.
git pull --rebase Pull via Rebase Downloads changes and moves local commits on top of remote ones (instead of merge commit). Creates a cleaner linear history. Alternative to git pull with merge. To automatically use: git config pull.rebase true. During conflict: resolve and git rebase --continue. Useful in feature-branch workflow — each commit remains separate. To abort: git rebase --abort. Don't use on shared branches without team coordination.
git push Push Changes Sends local commits to the remote repository. Sends only branches with tracking setup. For a specific branch: git push origin main. To create a new remote branch: git push origin feature-api. To delete a remote branch: git push origin --delete old-feature. To send all branches: git push --all. For tags: git push --tags. During conflict (remote has new commits): first git pull. To send with verification: git push --dry-run (no actual push).
git push -u origin main Push with Upstream Sends a branch to remote and sets up tracking for future synchronization. After this, git pull and git push without arguments will work with origin/main. The -u flag = --set-upstream. To check tracking: git branch -vv. To change upstream: git branch --set-upstream-to origin/main. To remove: git branch --unset-upstream. This is the standard workflow for the first push of a new branch.
git push --force-with-lease Safe Force Push Forcefully sends a branch but checks that remote hasn't changed since the last fetch (safer than --force). Used after rebase/pick when history is rewritten. To enable by default: git config push.forceWithLease true. Unlike --force, it won't overwrite changes made by other developers. For GitHub/GitLab: ensure force-push is allowed. For full safety: git push --force-with-lease --force-with-lease=origin/main (checks specific remote tracking).
git remote remove origin Remove Remote Removes a remote repository from configuration. You can add a remote back: git remote add origin url. To remove without confirmation: git remote remove origin. Alternative: git remote rm origin (short equivalent). To remove all remotes: git remote | xargs git remote remove. After removal, you'll lose push/pull capability until adding a new remote. To view the result: git remote (should be empty).

Stash

Stash — temporary saving of unstaged changes for switching to another task. Changes are stored as individual commits in a special stack.

Command Name Description
git stash Save Changes Temporarily saves all modified and staged files, clearing the working directory. Stash stack is limited (usually up to 50 entries). To save only staged (not unstaged): git stash -S or git stash --staged. To save untracked files: git stash -u or git stash --include-untracked. To save ignored files: git stash -all or git stash --all. Stash can be restored on any branch — it's not tied to a specific branch.
git stash push -m "WIP auth" Stash with Message Saves changes with a named message for identification. Useful when there are many stashes. Format: git stash push -m "description" [path]. To stash specific files: git stash push -m "auth" app.js config.js. To create in a specific branch: git stash push -m "WIP" --include-untracked. To view stash contents: git stash show stash@{n}. To create a patch stash (part of changes only): git stash push -p.
git stash list List Stashes Shows all stash entries with indices (stash@{0}, stash@{1}, etc.) and messages. The newest stash is always stash@{0}. For filtering: git stash list --author="Vlad". To show a specific one: git stash show stash@{2}. To delete empty stashes: git stash prune. To count: git stash list | wc -l. Stash is stored in .git/refs/stash.
git stash pop Restore Stash Applies the last stash (stash@{0}) and removes it from the stack. Working directory will contain the saved changes. If there is a conflict: resolve and git add + git commit. To apply a specific stash: git stash apply stash@{2}. To apply without removal: git stash apply stash@{0}. To pop with a specific branch: switch first, then git stash pop. On error: git stash drop to delete an unsuccessful stash.
git stash apply Apply Stash Applies stash to the current branch WITHOUT removing from the stack. Similar to pop, but stash remains available for reapplication. For a specific stash: git stash apply stash@{2}. To apply in another directory: git stash apply stash@{0} -- /path/to/dir. To view without applying: git stash show stash@{0}. To apply with conflict: resolve as a normal merge. To create a branch from stash: git stash branch feature-name stash@{0}.
git stash drop Delete Stash Deletes the specified stash entry from the stack. By default, deletes the last: git stash drop (equivalent to git stash drop stash@{0}). For a specific: git stash drop stash@{3}. To delete all except the last: git stash drop stash@{1}. After drop, stash is permanently deleted — but can be restored via git reflog. To delete all stashes: git stash clear. To delete empty ones: git stash prune.
git stash clear Clear Stash Deletes ALL stash entries from the stack. Irreversible operation — all saved changes will be lost. Before clearing: git stash list to view. For safe clearing: first apply needed stashes, then git stash clear. To clear a specific range: use git stash drop one by one. After clear, git stash list will return an empty result.

Tags

Tags — named references to specific commits, usually for release versions (v1.0.0, v2.1.3). Two types: lightweight (simple reference) and annotated (with metadata).

Command Name Description
git tag List Tags Shows all repository tags in alphabetical order. To sort by version: git tag -v (requires git-vtag). To search tags with a pattern: git tag -l "v2.*" or git tag --list "v2.*". To show with commit information: git tag -n (message), git tag -n10 (10 characters). To show the latest tag: git describe --tags. To sort by date: git tag --sort=-creatordate (newest first).
git tag v1.0.0 Create Tag Creates a lightweight tag — a simple link to a commit without additional metadata. For a specific commit: git tag v1.0.0 abc123. Lightweight tags are smaller but don't contain author, date or message. To create with signature (GPG): git tag -s v1.0.0 -m "Release v1.0.0". To create on a specific branch: switch to the needed commit, then create a tag. Lightweight tags can't be updated — to change, create a new one with the same name (overwrite).
git tag -a v1.0 -m "Release" Annotated Tag Creates an annotated tag with full metadata: author, date, message, GPG signature capability. Contains a tag object in Git storage (unlike lightweight). To create with a specific author: git tag -a v1.0 -m "Release" --author="Vlad ". For GPG signature: git tag -s v1.0.0 -m "Release". To verify signature: git tag -v v1.0.0. Annotated tags are recommended for releases.
git push origin --tags Push Tags Sends all local tags to the remote repository. Tags are not sent automatically on push — they need to be sent separately. To send a specific tag: git push origin v1.0.0. To send all new tags: git push origin --tags. To delete a remote tag: git push origin --delete v1.0.0. To update a tag: first git tag -f v1.0.0, then git push origin --tags --force. To view what will be sent: git push --dry-run origin --tags.
git tag -d v1.0.0 Delete Tag Deletes the specified local tag. To delete: git tag -d v1.0.0 or git tag --delete v1.0.0. To delete all tags: git tag | xargs git tag -d. After deleting a local tag, also delete from remote: git push origin --delete v1.0.0. To delete a tag on remote directly: git push origin --delete v1.0.0. Deleting a tag doesn't delete commits — they remain in the repository. To delete a tag and its objects: git gc --prune=now (caution).

Reset / Undo

Reset and Undo — commands for undoing changes at different levels: HEAD (branch pointer), staging area (index) and working directory. Important: git reset --hard is irreversible — changes are permanently lost.

Command Name Description
git reset Reset HEAD Moves HEAD and updates the staging area, but preserves the working directory. By default, works in --mixed mode. For a specific commit: git reset abc123. To undo the last commit while preserving staged: git reset HEAD~1. To return to a specific branch: git reset main. After reset, unpublished commits can be restored via git reflog. To view what will be reset: git reset --dry-run (not directly supported — use git diff HEAD).
git reset --soft Soft Reset Moves HEAD, but preserves staged changes in the staging area and working directory. Useful for combining multiple commits into one: git reset --soft HEAD~3 (combines 3 commits). Commit remains in staging — next commit will include all changes. To fix the last commit: git reset --soft HEAD~1 + git commit. Working directory is not changed. Commit hash will change. Use git log to verify the result.
git reset --mixed Mixed Reset Moves HEAD and updates the staging area, but preserves changes in the working directory (not staged). This is the default mode for git reset without a flag. Changes remain in files but need to be re-added via git add. For a specific commit: git reset --mixed abc123. For the current branch: git reset --mixed HEAD~1. Changes can be restaged and committed. To verify: git status will show modified files.
git reset --hard Hard Reset Completely moves HEAD, clears the staging area and updates the working directory to the specified commit. ALL changes (staged and unstaged) are permanently deleted. Use with extreme caution! To undo the last commit: git reset --hard HEAD~1. To return to a specific version: git reset --hard abc123. To clean untracked files: git clean -fd (separate command). For safety: first git status and git diff. To restore after an incorrect reset: git reflog + git reset --hard ORIG_HEAD.
git revert Revert Commit Creates a NEW commit that undoes the changes of the specified commit. Unlike reset, it's safe for published branches — doesn't rewrite history. For one commit: git revert abc123. For a range: git revert abc123..def456. For the last: git revert HEAD. To abort without opening the editor: git revert --no-edit HEAD. To undo multiple: git revert abc123 def456 ghi789. During conflict: resolve and git revert --continue. To abort: git revert --abort.
git clean -fd Delete Untracked Deletes untracked (untracked) files and directories from the working directory. The -f flag (force) is required for actual deletion, -d — includes directories. To view what will be deleted without deleting: git clean -fd --dry-run. To delete only files: git clean -f. To delete only directories: git clean -fd. To delete ignored files: git clean -fdx. For interactive deletion: git clean -i (interactive mode). To delete only files with an extension: use find + git clean. Before clean, always run --dry-run!

Working with History

Commands for analyzing and navigating repository history. Useful for auditing, finding change causes and understanding codebase evolution.

Command Name Description
git reflog HEAD History Shows ALL HEAD changes (and other refs) including reset, merge, checkout, rebase. Unlike git log, reflog shows even "lost" commits. Useful for recovery after git reset --hard. Format: hash@{n: timestamp}. To find a lost commit: git reflog | grep "message". To recover: git reset --hard abc123 (from reflog). For a specific ref: git reflog show origin/main. To clear: git reflog expire --expire=now --all. Commits remain accessible until gc (usually 30 days).
git shortlog Concise Statistics Groups commits by authors, showing the number of commits per person. Useful for evaluating participant contributions. For the entire repository: git shortlog. For a specific branch: git shortlog main. For a specific file: git shortlog -- app.js. Flags: -s (count only), -n (by count), -e (show email), -a (all branches), -p (breakdown by subsystems). To include all commits (not just HEAD): git shortlog --all. For export: git shortlog -s -n --all > CONTRIBUTORS.md.
git describe Describe Commit Finds the nearest tag to the specified commit and describes it in the format tag-N-g&hash (N commits after the tag, g&hash — hash). Useful for determining code version. For current HEAD: git describe. For a specific commit: git describe abc123. For only the latest tag: git describe --tags --abbrev=0. For tags with a prefix: git describe --tags --match "v*". For CI/CD: git describe --always --abbrev=0 (always returns a result). For version number: git describe --tags | sed 's/^v//' .
git bisect Find Bug Commit Uses binary search to find the commit that introduced a bug. Works in 3 steps: 1) git bisect start bad good, 2) git bisect run test-command or git bisect good/bad manually. For automatic search: git bisect start HEAD~10 v1.0 (bad=HEAD~10, good=v1.0), then git bisect run npm test. For manual: git bisect good (no bug) / git bisect bad (bug exists). Git will choose the next commit to check. To exit: git bisect reset. For visualization: git bisect visualize.
git range-diff Compare Rebase Compares two ranges of commits (usually before and after rebase), showing how patches changed. Useful for verifying rebase correctness. To compare: git range-diff origin/main..HEAD main..HEAD. To compare with specific ranges: git range-diff abc123..def456 ghi789..jkl012. Flags: --color (highlighting), --indent-heuristic (indentations). For review before push after rebase: git range-diff HEAD~5 HEAD origin/HEAD~5 origin/HEAD. Shows: which commits changed, which added, which removed. Indispensable for safe rebasing of published branches.

Worktree and Submodules

Worktree allows having multiple working directories for one repository with different branches. Submodule allows embedding one Git repository into another.

Command Name Description
git worktree add Additional Working Copy Creates an additional working copy of the repository in the specified directory with a specified branch. Useful for parallel work on multiple tasks without commit/stash. To create: git worktree add ../feature-api feature-api. To create from an existing branch: git worktree add ../hotfix hotfix. To create a new branch: git worktree add -b new-feature ../new-feature. Worktree shares the repository object but has a separate staging and working directory. To verify: git worktree list. To remove: git worktree remove ../feature-api. For automatic deletion on branch removal: git config worktree.autoprune on.
git worktree list List Worktrees Shows all worktrees of the repository with paths and status. Format: path branch HEAD [detached]. For detailed output: git worktree list --porcelain (for scripts). To show only active: git worktree list | grep -v detached. To show with branch information: git worktree list -v. To delete "dead" worktrees: git worktree prune. To verify that a worktree is not in use: git worktree list --ahead-behind (shows difference with upstream).
git submodule add repo-url libs/core Add Submodule Adds an external Git repository as a submodule in the specified directory. Creates a record in .gitmodules and clones the repository. To add: git submodule add https://github.com/user/lib.git libs/core. For a named submodule: git submodule add -b main repo-url libs/core --name my-lib. After adding: git add .gitmodules libs/core && git commit -m "Add submodule". To update submodule URL: git submodule set-url libs/core new-url. To change branch: git submodule update --remote -- libs/core.
git submodule update --init --recursive Initialize Submodule Clones and initializes all submodules of the repository. --init — initializes submodule from .gitmodules. --recursive — recursively processes nested submodules. For full cloning with submodules: git clone --recurse-submodules url. To update to specific commits: git submodule update. To update to latest remote versions: git submodule update --remote. To initialize a specific submodule: git submodule init libs/core && git submodule update libs/core. To sync URLs: git submodule sync --recursive.

Archiving and Transfer

Commands for creating portable repository archives that can be distributed without Git metadata or with full history.

Command Name Description
git archive Create Archive Creates an archive (zip/tar) of repository contents WITHOUT Git metadata. For a specific commit/tag: git archive -o release.zip v1.0.0. For tar with gzip: git archive --format=tar.gz -o release.tar.gz HEAD. For a specific directory: git archive -o src.tar HEAD -- src/. To add a prefix to the archive: git archive --prefix="my-project/" -o release.zip HEAD. To output to stdout: git archive HEAD | gzip > release.tar.gz. To view contents without unpacking: git archive HEAD --list. Useful for CI/CD deployment and creating releases.
git bundle create Bundle Repository Exports full Git history into one file that can be transferred to another machine and cloned. To create: git bundle create repo.bundle main. For a bundle with conditions: git bundle create repo.bundle v1.0.0..HEAD (only new commits). To verify: git bundle verify repo.bundle. For a branch list: git bundle list-heads repo.bundle. To clone: git clone repo.bundle. Bundle contains full history — size close to .git directory. Useful for transferring a repository via USB or when there is no network access.

Diagnostics and Maintenance

Commands for checking integrity, optimizing and monitoring Git repository state. Useful when there are performance problems or data corruption.

Command Name Description
git fsck Repository Check Checks Git object integrity and finds corrupted/orphan objects. For a full check: git fsck --full. To show only errors: git fsck --strict. To show dangling objects: git fsck --dangling. To check a specific object: git fsck --unreachable. To check with information about each object: git fsck --verbose. Typical results: dangling commit (lost commits), dangling blob (lost files). To restore dangling: git fsck --dangling | grep commit | awk '{print $3}'. Before git gc, always run git fsck.
git gc Garbage Collection Optimizes the repository, removing unused objects and compressing data. Automatically runs on push/commit, but can be run manually: git gc. For forced cleanup: git gc --prune=now (removes everything older than 2 weeks). To delete specific objects: git gc --prune=abc123. For optimization without deletion: git gc --aggressive (slower, but better compression). To check before gc: git fsck. For automatic setup: git config gc.auto 256 (automatically when >256 objects). To monitor result: git count-objects -v.
git maintenance run Git Maintenance Runs comprehensive repository maintenance (Git 2.34+). Includes: gc, repack, index optimization, commit-graph. To run manually: git maintenance run. For background work: git maintenance start (runs as background process). To stop: git maintenance stop. To set interval: git maintenance set --interval daily. For one-time run with aggressive optimization: git maintenance run --aggressive. To view status: git maintenance status. Works only with regular (not bare) repositories.
git count-objects -v Object Statistics Shows detailed statistics of Git objects. Output: count: N (number of objects), size: N (size in KB), in-pack: N (in pack files), packs: N (number of packs), prunable: N (can be removed), size: N (prunable size), empty: N (empty packs). For concise format: git count-objects (count + size only). For monitoring repository growth: run regularly. If prunable is large — run git gc --prune=now. If count > 10000 — repository needs optimization.

Modern Git Commands

New Git commands (2.23+) that separate functionality of old commands for better clarity and safety.

Command Name Description
git switch Switch Branches Modern alternative to checkout for switching branches (Git 2.23+). Separates checkout functionality: only branches, not files/commits. To switch: git switch main. To create and switch: git switch -c feature-api. To return to previous: git switch -. For detached HEAD: git switch --detach abc123. Unlike checkout, switch can't accidentally restore a file — this prevents accidental loss. To set as default: git config checkout.defaultRemote main.
git restore Restore Files Modern undo command for working with files (Git 2.23+). Separates checkout functionality: only file restoration. To restore a file: git restore app.js (from HEAD). To restore from staging: git restore --source=HEAD app.js. To restore all files: git restore .. To remove from staging: git restore --staged app.js. To restore to a specific version: git restore --source=abc123 app.js. To restore only working directory (not staging): git restore --worktree app.js. Combine with switch for full control.
git sparse-checkout Partial Checkout Allows cloning only part of the files in a monorepo (saves space and time). To initialize: git sparse-checkout init --cone. To add directories: git sparse-checkout add libs/core docs. For a list: git sparse-checkout list. To remove: git sparse-checkout remove libs/core. To disable: git sparse-checkout disable. To clone with sparse: git clone --filter=blob:none --sparse url && git sparse-checkout init --cone. To update: git sparse-checkout set libs/core src. Works with Git 2.28+ and server support for the filter protocol.
git worktree Multiple Working Directories Parallel work with branches in separate directories. To create: git worktree add ../feature-api feature-api. To create a new branch: git worktree add -b new-feature ../new-feature. For a list: git worktree list. To remove: git worktree remove ../feature-api. For forceful removal: git worktree remove -f ../feature-api. For automatic deletion on branch removal: git config worktree.autoprune on. To clean dead ones: git worktree prune. Worktree shares the repository object but has a separate staging and working directory. Useful for hotfixes during development.
git maintenance Automatic Maintenance Repository optimization (Git 2.34+). To run: git maintenance run. For background work: git maintenance start (runs as daemon). To stop: git maintenance stop. For status: git maintenance status. To set interval: git maintenance set --interval daily. For aggressive mode: git maintenance run --aggressive. Includes: gc, repack, index optimization, commit-graph. Works only with regular repositories. For Windows: use git maintenance start with Task Scheduler.
git backfill Partial Clone Objects Downloads missing partial clone objects (Git 2.38+). For partial clone repositories (with --filter): git backfill. To download specific objects: git backfill pack . To download all: git backfill --all. To check status: git backfill status. Partial clone downloads objects on demand — first only the structure is downloaded. Backfill loads all objects for full local work. To create a partial clone: git clone --filter=blob:none url. Backfill is useful for very large repositories (Linux kernel, Chromium).