đ Initial Configuration
Set these up once on any new machine.
git config --global user.name "Your Name"- Sets the name that will appear on your commits.
git config --global user.email "you@example.com"- Sets the email for your commits.
git config --global init.defaultBranch main- Sets the default branch name to
mainfor new repos.
- Sets the default branch name to
git config --global alias.lg "log --graph --oneline --decorate --all"- Creates a
git lgshortcut for a clean, comprehensive log.
- Creates a
git config --global alias.st "status -s"- Creates a
git stshortcut for a short, one-line status.
- Creates a
đĻ Basic Workflow: Staging & Committing
This is your day-to-day command cycle.
git init- Initializes a new Git repository in the current directory.
git status- Shows the status of your working directory and staging area (untracked, modified, and staged files).
git add <file...>- Adds one or more specific files to the staging area.
- Example:
git add README.md package.json
git add .- Adds all new and modified files in the current directory to the staging area.
git add -p- Interactively stages parts of files. Git will show you each "hunk" of changes and ask if you want to stage it (y/n/q).
git commit -m "Your descriptive message"- Saves a permanent snapshot of the staged files to the project history.
git commit -am "Your message"- A shortcut to stage all tracked files and commit them in one step. (Note: Does not add new, untracked files).
git rm <file>- Removes a file from both the working directory and the staging area.
git rm --cached <file>- Removes a file from the staging area (index) but keeps the file in your working directory. Useful for "untracking" a file, like a config file you accidentally added.
git mv <old-name> <new-name>- Renames a file. This is equivalent to
mv <old> <new>,git rm <old>, andgit add <new>.
- Renames a file. This is equivalent to
đ Inspecting History & Logs
See what has happened in the project.
git log- Shows the full commit history for the current branch.
git log --oneline- Shows a compact, one-line view of the commit history.
git lg(orgit log --graph --oneline --decorate --all)- A powerful, customized log (using the alias from setup) that shows all branches, commit graphs, and tags in a clean one-line format.
git log -p <file>- Shows the commit history for a specific file, including the changes (patches) made in each commit.
git reflog- Shows a log of all movements of
HEAD(commits, checkouts, resets, merges). This is your ultimate safety net for finding "lost" commits.
- Shows a log of all movements of
đŋ Branching & Merging
Manage parallel lines of development.
Branching
git branch- Lists all your local branches.
git branch -a- Lists all local and remote-tracking branches.
git branch <branch-name>- Creates a new branch based on your current
HEAD.
- Creates a new branch based on your current
git checkout <branch-name>- Switches your working directory to the specified branch.
git checkout -b <branch-name>- A shortcut to create a new branch and switch to it immediately.
git branch -m <new-name>- Renames the current branch.
git branch -d <branch-name>- Deletes a merged local branch. Git will stop you if the branch isn't merged (safety feature).
git branch -D <branch-name>- Force deletes a local branch, even if it's not merged.
Merging & Rebasing
git merge <branch-name>- Merges the specified branch into your current branch. This creates a new "merge commit" if there are new commits on both branches (a non-fast-forward merge).
git rebase <branch-name>- Re-applies your current branch's commits on top of the specified branch. This creates a cleaner, linear history.
- Example: You're on
featureandmainhas updated. Rungit rebase mainto move yourfeaturework to the tip ofmain.
git rebase -i HEAD~3- Interactively rebase the last 3 commits. This opens an editor allowing you to
squash(combine),reword(change message),edit,drop, or reorder commits.
- Interactively rebase the last 3 commits. This opens an editor allowing you to
đĨ Stashing
Temporarily save changes you aren't ready to commit.
git stashorgit stash save "Your message"- Takes all your uncommitted changes (in tracked files), saves them, and cleans your working directory back to
HEAD.
- Takes all your uncommitted changes (in tracked files), saves them, and cleans your working directory back to
git stash list- Shows all stashes you've saved.
git stash pop- Applies the most recent stash to your working directory and deletes it from the stash list.
git stash apply <stash@{n}>- Applies a specific stash (e.g.,
stash@{1}) but does not delete it from the list.
- Applies a specific stash (e.g.,
git stash drop <stash@{n}>- Deletes a specific stash from the list.
đĄ Remote Repositories (e.g., GitHub)
Manage connections to other repositories.
Managing Remotes
git remote add <name> <url>- Adds a new remote. The standard name is
origin. - Example:
git remote add origin https://github.com/user/repo.git
- Adds a new remote. The standard name is
git remote -v- Lists all your remotes with their URLs.
git remote rename <old-name> <new-name>- Renames a remote.
git remote remove <name>- Removes a remote.
Syncing Changes
git fetch <remote-name>- Downloads all branches and history from the remote without merging them into your local branches. This is safe and lets you inspect changes first.
git pull <remote-name> <branch-name>- A shortcut for
git fetchfollowed bygit merge. It fetches and immediately tries to merge the remote branch into your current local branch. - Example:
git pull origin main
- A shortcut for
git push <remote-name> <branch-name>- Uploads your local branch's commits to the remote repository.
git push -u <remote-name> <branch-name>- Pushes and sets the remote as the "upstream" tracking branch. After this, you can just run
git pullorgit pushfrom that branch.
- Pushes and sets the remote as the "upstream" tracking branch. After this, you can just run
git push <remote-name> --delete <branch-name>- Deletes a branch on the remote repository.
git push --force-with-lease- â ī¸ Force-pushes your local branch, overwriting the remote. This is safer than
git push --forcebecause it will fail if someone else has pushed new commits in the meantime. Use this only when you have rewritten history (e.g., rebase) and have coordinated with your team.
- â ī¸ Force-pushes your local branch, overwriting the remote. This is safer than
âŠī¸ Undoing & Rewriting History
How to fix mistakes "after the fact."
Before Committing (Working Directory / Staging)
git restore <file>- Discards changes in your working directory. (The modern, clearer version of
git checkout -- <file>).
- Discards changes in your working directory. (The modern, clearer version of
git restore --staged <file>- Unstages a file, moving it from the staging area back to the working directory. (The modern version of
git reset HEAD <file>).
- Unstages a file, moving it from the staging area back to the working directory. (The modern version of
After Committing (But Before Pushing)
git commit --amend- Lets you change the last commit's message or add more staged files to it. It replaces the last commit with a new one.
git reset --soft HEAD~1- Un-commits the last commit. The changes from that commit are moved to the staging area.
git reset --mixed HEAD~1(This is the default)- Un-commits the last commit. The changes are moved to the working directory (unstaged).
git reset --hard HEAD~1- â ī¸ Destroys the last commit and all changes associated with it. Your working directory is reset to the state of the commit before it. This is permanent.
git reset --hard <commit-hash>- â ī¸ Resets your entire project (working directory and index) to a specific commit. Discards all subsequent commits and changes.
After Pushing (Public Commits)
git revert <commit-hash>- The safe way to "undo" a public commit. This creates a new commit that is the exact inverse of the specified commit. It doesn't rewrite history.
git revert -m 1 <merge-commit-hash>- Reverts a merge commit.
-m 1tells Git which parent to keep (usually 1).
- Reverts a merge commit.
- Changing a Pushed Commit Message:
- This is highly disruptive to your team. Avoid if possible.
git rebase -i HEAD~5(Go back far enough to find the commit)- Find the commit line, change
picktoreword(orr). - Save and close. Git will prompt you to enter the new message.
git push --force-with-lease
- You must force-push because you've rewritten public history. All collaborators will need to re-sync their branches.
đ ī¸ Advanced Tools
Git Worktrees
Manage multiple branches in separate directories simultaneously.
git clone --bare . /path/to/my-bare-repo.git- Clone the current repository as a bare repository
git worktree add <path> <branch-name>- Checks out a branch into a new directory. This is great for working on a hotfix while keeping your main
featurebranch checked out in your primary folder. - Example:
git worktree add ../my-hotfix-branch hotfix
- Checks out a branch into a new directory. This is great for working on a hotfix while keeping your main
git worktree list- Shows all active worktrees.
git worktree remove <path>- Removes the worktree at the specified path.
Git Submodules
Manage a repository inside another repository.
git submodule add <repo-url> <path>- Adds the other repo as a submodule in the specified path.
git clone --recurse-submodules <repo-url>- Clones a repository and automatically initializes and updates all its submodules.
git submodule update --init --recursive- Run this after a normal
git clone(orgit pull) to initialize or update submodules.
- Run this after a normal
- Workflow for updating a submodule:
cd <submodule-path>git checkout main(or desired branch)git pullcd ..(back to the parent repo)git add <submodule-path>git commit -m "Update submodule to latest"
- This "parent" commit locks the submodule to the new commit hash you just pulled.