Your essential guide to Git commands, core concepts, and popular workflows.
Set your user identity for all local repositories. Typically done once per machine.
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
git config --global init.defaultBranch main
git config --global core.editor "code --wait"
(Example for VS Code)git config --list
Start a new project with Git or obtain a copy of an existing one.
Navigate to your project directory, then run: git init
git clone <repository_url>
Example: git clone https://github.com/example/project.git
This creates a local copy named after the project.
Understand Git's core areas: Working Directory, Staging Area (Index), and the Repository itself.
Your project files
Changes for next commit
Committed history
git add
to stage.git commit
to save staged changes here.Specify intentionally untracked files or directories that Git should ignore (e.g., build artifacts, log files, environment variables).
Create a file named .gitignore
in your project's root directory.
Each line in .gitignore
specifies a pattern:
#
are treated as comments.*.log
, node_modules/
, build/
)./
matches files only in the root directory./
specifies a directory.!
to negate a pattern (un-ignore) if a parent folder is ignored..gitignore
:# Comments start with a hash
# Ignore compiled Python files
*.pyc
__pycache__/
# Ignore dependency directories
node_modules/
vendor/
# Ignore sensitive files
.env
*.secret
# Ignore OS-generated files
.DS_Store
Thumbs.db
It's crucial to commit your .gitignore
file to the repository so it's shared with collaborators.
For common templates, check GitHub's .gitignore collection.
The fundamental workflow: check status, stage changes, and commit them to history.
git status
(shows current state of working directory and staging area)
git add <filename>
git add <file1> <file2>
git add .
git add -A
git add -p
(Patch mode)git commit -m "Your descriptive commit message"
git commit
git commit -a -m "Message"
(Does NOT add new untracked files)git commit --amend
(Opens editor for message, adds currently staged changes) Rewrites history!Inspect past commits and see differences between states.
git log
git log --oneline
git log --graph --decorate --oneline --all
git log -n 5
(shows last 5)git log -p
git diff
git diff --staged
(or --cached
)git diff HEAD
git diff <commit1> <commit2>
git diff <branch1>..<branch2>
Manage files within Git's tracking system.
git rm <filename>
git rm --cached <filename>
git mv <old-name> <new-name>
Equivalent to manually renaming, then git rm <old-name>
and git add <new-name>
.
Isolate development work using branches. Create, list, switch, and delete them.
Branches are lightweight movable pointers to commits, allowing parallel lines of development.
git branch
(* indicates current branch)git branch <branch-name>
git switch <branch-name>
(Modern Git)
git checkout <branch-name>
)
git switch -c <branch-name>
(Modern Git)
git checkout -b <branch-name>
)
git branch -d <branch-name>
git branch -D <branch-name>
Use with caution!git branch -m <new-name>
A basic illustration of creating and merging a feature branch.
Combine work from different branches using merge (preserves history) or rebase (linearizes history).
To merge feature-branch
into your current branch (e.g., main
):
git switch main
git merge feature-branch
May result in a "merge commit" if histories diverged.
If Git reports conflicts:
<<<<<<<
, =======
, >>>>>>>
).git add <resolved-file>
git commit
git merge --abort
(before committing).
To rebase feature
branch onto main
(reapplies feature
commits on top of main
's tip):
main
is up-to-date: git switch main
; git pull
(if remote)git switch feature
git rebase main
Warning: Do NOT rebase commits that have already been pushed to a shared remote repository and are used by others. It rewrites history and can cause severe problems for collaborators.
Conflicts during rebase: Resolve, git add <file>
, then git rebase --continue
. Abort: git rebase --abort
.
Gitflow is a structured branching model designed for projects with scheduled releases. It defines specific roles for different branches. Click branch names below for details.
Purpose: Stores the official release history. Code on main
should always be stable and deployable. Each commit on main
is a tagged release (e.g., v1.0, v1.0.1).
Derives from: Initial commit.
Merges into: Nothing (but receives merges from release
and hotfix
branches).
Purpose: Serves as an integration branch for features. Contains the latest development changes for the next release. This branch can be unstable at times.
Derives from: main
.
Merges into: Nothing directly (but feature
branches merge into it, and release
branches are created from it).
feature/user-auth
)Purpose: Used to develop new features. Each feature gets its own branch to isolate work.
Derives from: develop
.
Merges into: develop
(once the feature is complete and reviewed).
Naming: Typically feature/*
or feat/*
. Should not interact directly with main
.
release/v1.1.0
)Purpose: Prepare for a new production release. Allows for final bug fixes, documentation generation, and other release-oriented tasks. No new major features are added here.
Derives from: develop
(when develop
is deemed feature-complete for the release).
Merges into: main
(tagged with release version) AND back into develop
(to ensure fixes are in future development).
hotfix/critical-login-bug
)Purpose: Address urgent critical bugs in a production release quickly. Allows patching without disrupting ongoing development on develop
.
Derives from: main
(from the specific tagged version that has the bug).
Merges into: main
(tagged with a new patch version) AND back into develop
(to ensure the fix is also in subsequent development).
Gitflow is one of many branching strategies. Others include GitHub Flow (simpler, for continuous deployment) and GitLab Flow.
Connect your local repository to remote ones (e.g., on GitHub, GitLab, Bitbucket).
git remote -v
git remote add <name> <url>
(Common name: origin
)git remote show <name>
git remote set-url <name> <new-url>
git remote rename <old-name> <new-name>
git remote remove <name>
Download changes from a remote repository to your local one.
git fetch <remote-name>
(e.g., git fetch origin
)
Downloads commits, files, and refs from the remote into your local repository. Updates remote-tracking branches (e.g., origin/main
). Does NOT automatically merge these changes into your local working branches.
After fetching, you can inspect changes (e.g., git log origin/main..main
) or merge manually (git merge origin/main
).
git pull <remote-name> <branch-name>
(e.g., git pull origin main
)
Effectively runs git fetch
followed by git merge <remote-name>/<branch-name>
into your current local branch. If your local branch tracks a remote branch, a simple git pull
often suffices.
Upload your local commits to a remote repository to share them.
git push <remote-name> <branch-name>
(e.g., git push origin main
)
Transfers commits from your local branch to the specified branch on the remote.
The first time you push a new local branch, you may need to set its upstream counterpart on the remote:
git push -u <remote-name> <local-branch-name>
This sets <remote-name>/<local-branch-name>
as the upstream. Subsequent pushes from this local branch can use a simple git push
.
Force Push: git push --force <remote> <branch>
(or -f
). Overwrites the remote branch. Can discard history and cause problems for collaborators. Use with extreme caution and only if you know what you're doing (e.g., on a personal feature branch you haven't shared).
Understand and manage references to branches on your remotes.
Remote-tracking branches are local read-only references to the state of branches on your remote repositories (e.g., origin/main
, origin/feature-x
). You don't work on them directly.
git branch -r
git branch -a
git switch -c <local-branch> <remote>/<remote-branch>
git switch -c my-feature origin/feature-abc
)
feature-abc
only exists on one remote, git switch feature-abc
will automatically set up tracking.
git push <remote-name> --delete <branch-name>
git push origin --delete old-feature
)
Create permanent markers for specific commits, typically used for software releases (e.g., v1.0, v2.1.3).
git tag
git tag <tag-name>
git tag -a <tag-name> -m "Tag message for version X.Y.Z"
git tag -a <tag-name> <commit-hash> -m "Message"
git push <remote-name> <tag-name>
(e.g. git push origin v1.0
)git push <remote-name> --tags
git tag -d <tag-name>
git push <remote-name> --delete <tag-name>
Temporarily save uncommitted changes (stash) or remove untracked files from your working directory (clean).
Useful when you need to switch branches but have uncommitted work.
git stash
or git stash push -m "Optional message"
git stash -u
(or --include-untracked
)git stash list
git stash pop
git stash apply
git stash apply stash@{N}
(N is stash index)git stash drop
git stash clear
Irreversible!Warning: git clean
permanently deletes files from your working directory. Use with extreme caution.
git clean -n
(or --dry-run
)git clean -f
(--force
)git clean -fd
git clean -i
Powerful commands to undo changes at different levels. Understand their impact before use.
git reset
(Moves HEAD, affects Index/Working Dir based on mode):Primarily used to unstage changes or revert commits on a local branch before pushing.
git reset --soft <commit>
: Moves HEAD to <commit>
. Staging area and working directory are NOT changed. Commits after <commit>
become staged changes. Useful for redoing a series of commits.git reset --mixed <commit>
(Default mode): Moves HEAD to <commit>
. Staging area is updated to match <commit>
. Working directory is NOT changed. Changes are now unstaged. Example: git reset HEAD~1
(uncommits last commit, changes are unstaged).git reset --hard <commit>
: Moves HEAD to <commit>
. Staging area AND working directory are forcefully updated to match <commit>
.
Warning: Discards ALL uncommitted changes in staging and working directory since <commit>
. Potentially destructive and can lead to data loss if not used carefully.git restore
(Restores files in Working Dir or Staging Area):A safer, more focused command for discarding changes.
git restore <filename>
git restore --staged <filename>
git restore --source=<commit> --staged --worktree <filename>
Various ways to specify particular commits in Git commands (log, diff, reset, etc.).
1a410efbd13591db07496601ebc7a059dd55cfe9
)1a410e
- usually first 7 chars are enough)main
, feature/login
- points to the tip of the branch)v1.0.0
- points to the tagged commit)HEAD
: Points to the currently checked-out commit (tip of current branch).HEAD~1
or HEAD^
: The first parent of HEAD
.HEAD~N
: The Nth grandparent of HEAD
(following first parents).HEAD^N
: The Nth parent of HEAD
(useful for merge commits with multiple parents).<branch>@{yesterday}
or <branch>@{"2 hours ago"}
: Commit on a branch at a specific time.<branch>@{N}
: Nth prior position of the branch reference (uses the reflog).:/<text>
: Newest commit whose message contains <text>
.