What it is
Git is a distributed version control system for tracking changes in source code during software development, enabling collaboration and rollback capabilities.
Installation
Linux
sudo apt update
sudo apt install git
or
sudo yum install git
macOS
Using Homebrew:
brew install git
Or download from the official Git website: https://git-scm.com/downloads
Windows
Download the installer from the official Git website: https://git-scm.com/downloads
Core Concepts
- Repository (Repo): A collection of files and their history. Can be local (on your machine) or remote (on a server like GitHub, GitLab, Bitbucket).
- Working Directory: The directory on your file system where your project files reside.
- Staging Area (Index): An intermediate area where you prepare changes to be committed. You add specific changes to the staging area before committing them.
- Commit: A snapshot of your project at a specific point in time. Each commit has a unique identifier (SHA-1 hash) and a commit message describing the changes.
- Branch: An independent line of development. Branches allow you to work on new features or fixes without affecting the main codebase.
main(ormaster) is typically the primary branch. - HEAD: A pointer to the currently checked-out commit or branch.
- Remote: A repository hosted on a different server, usually for collaboration.
originis the conventional name for the default remote repository. - Fetch: Downloads commits, files, and refs from a remote repository into your local repo, but does not merge them into your local working branch.
- Pull: Fetches from and integrates with another repository or a local branch. It’s a
git fetchfollowed by agit merge. - Push: Updates your remote repository with commits from your local repository.
Commands / Usage
Initializing and Configuring a Repository
git initInitialize an empty Git repository in the current directory.git initgit init <directory>Initialize an empty Git repository in a specified directory.git init my-new-projectgit clone <repository_url>Clone a remote repository to your local machine.git clone https://github.com/user/repo.gitgit config --global user.name "Your Name"Set your Git username for all repositories on your system.git config --global user.name "Alice Wonderland"git config --global user.email "youremail@example.com"Set your Git email address for all repositories on your system.git config --global user.email "alice@example.com"git config --listView your Git configuration settings.git config --list
Making Changes and Committing
git statusShow the status of your working directory and staging area.git statusgit add <file>Add a specific file to the staging area.git add README.mdgit add .Add all changes in the current directory and subdirectories to the staging area.git add .git add -uStage modified and deleted files, but not new files.git add -ugit commit -m "Commit message"Commit staged changes with a descriptive message.git commit -m "Add initial README file"git commit -am "Commit message"Stage all tracked modified files and commit them with a message (skipsgit add).git commit -am "Update project configuration"git commit --amendAmend the last commit, allowing you to add forgotten changes or modify the commit message.
(This will open your editor to modify the message and staged changes).git commit --amendgit restore <file>Discard changes in the working directory for a specific file (restores to the last commit).git restore index.htmlgit restore --staged <file>Unstage a file (remove it from the staging area).git restore --staged main.py
Viewing History
git logShow the commit history.git loggit log --onelineShow commit history in a compact, one-line format.git log --onelinegit log --graph --oneline --allShow a graphical representation of commit history across all branches.git log --graph --oneline --allgit diffShow changes between the working directory and the staging area.git diffgit diff --stagedShow changes between the staging area and the last commit.git diff --stagedgit diff <commit>Show changes between the working directory and a specific commit.git diff HEAD~1git diff <commit1> <commit2>Show changes between two specific commits.git diff abc1234 def5678
Working with Branches
git branchList all local branches.git branchgit branch <branch_name>Create a new branch.git branch feature-logingit checkout <branch_name>Switch to a different branch.git checkout feature-logingit checkout -b <branch_name>Create a new branch and switch to it immediately.git checkout -b bugfix-navbargit merge <branch_name>Merge changes from another branch into your current branch.git merge feature-logingit branch -d <branch_name>Delete a local branch (only if it has been fully merged).git branch -d feature-logingit branch -D <branch_name>Force delete a local branch (even if not merged).git branch -D experimental-featuregit branch -m <old_branch_name> <new_branch_name>Rename a branch.git branch -m main master
Working with Remotes
git remote -vList all remote repositories configured for your local repository.git remote -vgit remote add <remote_name> <repository_url>Add a new remote repository.git remote add origin https://github.com/user/repo.gitgit fetch <remote_name>Download commits and objects from a remote repository.git fetch origingit pull <remote_name> <branch_name>Fetch from and integrate with a remote branch.git pull origin maingit push <remote_name> <branch_name>Push your local branch commits to a remote repository.git push origin maingit push -u <remote_name> <branch_name>Push your local branch and set the upstream tracking branch.git push -u origin feature-logingit push <remote_name> --delete <branch_name>Delete a branch on the remote repository.git push origin --delete feature-login
Undoing Changes
git reset <commit>Reset the current branch to a specified commit. Be cautious with this command as it can discard history.--soft: Moves HEAD to the commit, staging area and working directory are unchanged.--mixed: Moves HEAD to the commit, staging area is reset, working directory is unchanged. (This is the default).--hard: Moves HEAD to the commit, resets staging area and working directory to match the commit. This discards all subsequent changes.git reset --hard HEAD~1 # Discard the last commit and its changes git reset --soft HEAD~2 # Move HEAD back two commits, keep changes stagedgit revert <commit>Create a new commit that undoes the changes introduced by a specified commit. This is safer for shared history.git revert abc1234git clean -nSee what untracked files would be removed.git clean -ngit clean -fRemove untracked files from the working directory.git clean -fgit clean -fdRemove untracked files and directories from the working directory.git clean -fd
Stashing Changes
git stashSave your uncommitted local changes (both staged and unstaged) so you can switch branches or work on something else.git stashgit stash listList all stashes.git stash listgit stash apply [stash@{n}]Re-apply the changes from a stash (the stash remains in the list).git stash apply stash@{2}git stash pop [stash@{n}]Re-apply the changes from a stash and remove it from the stash list.git stash popgit stash drop [stash@{n}]Remove a stash from the list.git stash drop stash@{1}git stash clearRemove all stashes.git stash clear
Tagging Releases
git tagList all tags.git taggit tag <tag_name>Create a lightweight tag at the current commit.git tag v1.0.0git tag -a <tag_name> -m "Tag message"Create an annotated tag with a message.git tag -a v1.0.1 -m "Release version 1.0.1"git tag -d <tag_name>Delete a tag.git tag -d v1.0.0git push origin <tag_name>Push a specific tag to the remote.git push origin v1.0.1git push origin --tagsPush all local tags to the remote.git push origin --tags
Common Patterns
- Creating a new branch, making changes, committing, and pushing:
git checkout -b new-feature # ... make changes ... git add . git commit -m "Implement new feature X" git push -u origin new-feature - Pulling changes from remote and merging into current branch:
git checkout main git pull origin main - Rebasing a branch onto the latest main:
git checkout my-feature-branch git fetch origin main git rebase origin/main # Resolve any conflicts if they occur git push --force-with-lease origin my-feature-branch # Use force-with-lease after rebasing - Discarding all local changes:
git reset --hard HEAD git clean -fd - Viewing changes introduced in the last commit:
git show HEAD - Viewing changes for a specific file across all commits:
Example:git log -p -- <file_path>git log -p -- src/app.js - Stashing changes and applying them later:
git stash push -m "Work on login form" # Add a message to the stash # ... do other work ... git stash pop - Finding which commit introduced a bug (Binary Search):
git bisect start git bisect bad HEAD # Mark current commit as bad git bisect good <commit_hash_before_bug> # Mark an older commit as good # Git will checkout a commit in the middle. Test it. git bisect good # If the bug is NOT present git bisect bad # If the bug IS present # Repeat until Git pinpoints the commit git bisect reset # Exit bisect mode
Gotchas
git pullvsgit fetch:git pullfetches and merges, potentially creating merge commits.git fetchonly downloads changes, giving you a chance to review before merging.git reset --hardis destructive: It discards committed changes. Be extremely careful, especially on shared branches. Prefergit revertfor undoing published history.- Force pushing (
git push --force): Overwrites the history on the remote. This can cause problems for collaborators. Usegit push --force-with-leasewhich is safer as it checks if the remote branch has been updated by someone else since your last fetch. - Committing sensitive information: Never commit passwords, API keys, or other secrets directly into Git. Use
.gitignoreor environment variables. - Large files: Git is not optimized for large binary files. Consider using Git LFS (Large File Storage).
- Branch naming conventions: While Git allows almost any name, using consistent naming (e.g.,
feature/,bugfix/,hotfix/) improves clarity. - Merge Conflicts: When Git cannot automatically combine changes from different branches, it flags a merge conflict. You must manually edit the conflicted files to resolve them, then
git addandgit committo complete the merge. - Stale
origin/main: If you work on a branch and others push tomain, your localorigin/mainpointer will be outdated. Alwaysgit fetchbefore rebasing or mergingmaininto your branch.