A complete reference guide to Git and GitHub with all essential commands, concepts, and practical workflows.
- What Is Git & GitHub?
- Why Use Git & GitHub?
- What Can Git & GitHub Do?
- Who Discovered Git & GitHub?
- How Do Git & GitHub Work?
- Understanding Repository Types
- Core Git Concepts
- Essential Git Commands
- Git Workflows
- Common Git Problems and Solutions
- Frequently Asked Questions (FAQ)
- Additional Resources
Git is a distributed version control system. It allows every developer to have a complete copy of the project repository on their local machine. This setup makes it easy to work offline, experiment with new features in branches, and merge changes with the main project.
GitHub is a cloud-based platform that hosts Git repositories. It not only stores your code but also offers collaboration tools such as issue tracking, pull requests, and code reviews. GitHub makes it easier for teams to work together and share their work publicly or privately.
Multiple developers can work on the same project simultaneously without overwriting each other's changes.
Every change is recorded, allowing you to review, revert, or audit modifications over time.
You can create separate branches to develop new features or fix bugs independently and then merge them back into the main codebase.
With distributed copies, your work is backed up, and you can recover previous versions if something goes wrong.
GitHub has a vast ecosystem with tools for continuous integration, deployment, and more, making it an excellent platform for both open-source and private projects.
Track changes in your code, view commit histories, and revert to previous states if necessary.
Facilitate team collaboration with pull requests, code reviews, and issue tracking.
Experiment safely by creating branches for new features or fixes without disturbing the main project.
Work with CI/CD pipelines, automated testing, and deployment tools that integrate directly with GitHub.
Host project documentation, wikis, and even community forums directly on GitHub to support user engagement and developer communication.
Git was created by Linus Torvalds in 2005. He developed it to support the Linux kernel development, aiming for a fast, efficient, and reliable version control system.
GitHub was founded in 2008 by Tom Preston-Werner, Chris Wanstrath, PJ Hyett, and Scott Chacon. It quickly became popular due to its user-friendly interface and robust collaboration features, transforming how developers manage and share code.
With Git, every developer works on a local copy of the entire repository, which includes the full history of changes. This setup allows developers to commit changes locally.
Changes are saved as commits. Developers can create branches to develop features independently. Once tested, these branches can be merged back into the main branch.
GitHub acts as a central hub where developers can push their local changes and pull updates made by others. This exchange keeps everyone in sync.
On GitHub, a developer can open a pull request to propose changes. Team members review the code, discuss improvements, and finally merge the changes once they're approved.
GitHub provides tools to manage bugs, feature requests, and project workflows, ensuring organized and efficient project development.
A local repository resides on your personal computer or workstation. This is where you perform all your work - writing code, making changes, committing updates, and tracking history.
- Contains the complete history of your project including all commits, branches, and files
- Lives in the
.git
directory of your project - Allows you to work offline without internet connection
- Contains your working directory, staging area, and local commit history
A remote repository is hosted on a server (like GitHub, GitLab, or Bitbucket) and serves as a centralized location where team members can share and synchronize their work.
- Facilitates collaboration between multiple developers
- Provides backup and redundancy for your code
- Serves as the official source of the project
- Enables features like pull requests, code reviews, and issue tracking
- Popular remote repository hosts include GitHub, GitLab, and Bitbucket
- Local repositories can be linked to one or more remote repositories
- You push local changes to remote repositories to share them
- You pull changes from remote repositories to update your local copy
- Remote repositories are usually referred to by names like "origin" or "upstream"
HEAD is a special pointer that references the current location in your repository:
- Points to the tip of the current branch you are working on
- Represents the last commit in your current branch
- Acts as a "You are here" marker in your commit history
- When you switch branches, HEAD moves to point to the tip of the new branch
- Can be in a "detached" state when you checkout a specific commit instead of a branch
Example of accessing HEAD:
# See what HEAD points to
cat .git/HEAD
# Move HEAD to a specific commit (detached HEAD state)
git checkout <commit-hash>
# Return HEAD to a branch
git checkout <branch-name>
A branch is an independent line of development within a repository:
- Branches allow multiple developers to work in parallel without interfering with each other
- Each branch is essentially a pointer to a specific commit
- New commits on a branch advance that branch's pointer
- The default branch (typically main or master) represents the primary line of development
- Feature branches, bugfix branches, and release branches are common types of branches
Branch operations:
# Create a new branch
git branch <branch-name>
# Switch to a branch
git checkout <branch-name>
# Create and switch to a new branch in one command
git checkout -b <branch-name>
# List all branches
git branch -a
# Delete a branch
git branch -d <branch-name>
The main branch (traditionally called "master") is the primary branch in a repository:
- Represents the official, production-ready version of the project
- Should always contain stable, working code
- Often protected from direct pushes in collaborative projects
- Changes to main/master typically come through pull requests and code reviews
- May be deployed to production environments automatically
Note: Many repositories now use "main" instead of "master" as the default branch name.
Understanding the relationship between remote and local references:
- Remote branches have the format
<remote-name>/<branch-name>
(e.g.,origin/main
) - Remote-tracking branches are local references that represent the state of branches in remote repositories
- Local branches can track remote branches to simplify pushing and pulling changes
Common remote operations:
# Add a remote repository
git remote add <name> <url>
# List remote repositories
git remote -v
# Fetch updates from a remote without merging
git fetch <remote-name>
# View remote branches
git branch -r
A tracking branch is a local branch that has a direct relationship to a remote branch:
- Automatically knows which remote branch to push to and pull from
- Shows how far ahead or behind the remote branch your local branch is
- Created automatically when you clone a repository or checkout a remote branch
- Enables
git pull
andgit push
without specifying a remote or branch
Setting up tracking:
# Create a new branch that tracks a remote branch
git checkout --track origin/<branch-name>
# Make an existing branch track a remote branch
git branch -u origin/<branch-name>
# Push a local branch and set up tracking
git push -u origin <branch-name>
# 1. Set Up Your Username and Email
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
# 2. Set default editor
git config --global core.editor "code --wait" # For VS Code
# 3. Set default branch name for new repositories
git config --global init.defaultBranch main
# 4. Configure line ending behavior
git config --global core.autocrlf input # For Mac/Linux
git config --global core.autocrlf true # For Windows
# 5. View all configuration settings
git config --list
# Create a file
touch filename.extension
# Create a folder
mkdir foldername
# Enter a folder
cd foldername
# Check the directory currently you are working in
pwd
# See the list of your files
ls
# See hidden files (including .git directory)
ls -a
# Initialize a local Git repository
git init
# Create a local copy of a remote repository
git clone ssh://[email protected]/[username]/[repository-name].git
# Clone a specific branch
git clone -b <branch-name> <repository-url>
# Clone a repository with limited history for faster cloning
git clone --depth=1 <repository-url>
# Check status
git status
# Add a file to the staging area
git add [file-name.txt]
# Add all new and changed files to the staging area
git add -A
git add --all
git add .
# Stage changes in your folder you are currently staying
git add .
# Stage changes all the files except the deleted ones
git add *
# Stage changes of all the files of the specific extension
git add *.extension
# Commit changes
git commit -m "[commit message]"
# Commit changes and skip the staging area (add + commit)
git commit -am "[commit message]"
# Amend the most recent commit message
git commit --amend -m "[new commit message]"
# Remove a file (or folder)
git rm -r [file-name.txt]
# View the remote repository of the currently working file or directory
git remote -v
# Display the commit history, showing author, date, and commit message
git log
# Configure Git settings, such as user name and email
git config
# List branches (the asterisk denotes the current branch)
git branch
# List all branches (local and remote)
git branch -a
# Create a new branch
git branch [branch name]
# Delete a branch
git branch -d [branch name]
# Force delete a branch (even if not fully merged)
git branch -D [branch name]
# Delete a remote branch
git push origin --delete [branch name]
# Create a new branch and switch to it
git checkout -b [branch name]
# Clone a remote branch and switch to it
git checkout -b [branch name] origin/[branch name]
# Rename a local branch
git branch -m [old branch name] [new branch name]
# Switch to a branch
git checkout [branch name]
# Switch to the branch last checked out
git checkout -
# Discard changes to a file
git checkout -- [file-name.txt]
# Merge a branch into the active branch
git merge [branch name]
# Merge a branch into a target branch
git merge [source branch] [target branch]
# Merge with a commit message
git merge [branch name] -m "[commit message]"
# Abort a merge in case of conflicts
git merge --abort
# Stash changes in a dirty working directory
git stash
# Remove all stashed entries
git stash clear
# Apply latest stash to working directory
git stash pop
# Check the current branch
git branch
# Push a branch to your remote repository
git push origin [branch name]
# Push changes to remote repository (and remember the branch)
git push -u origin [branch name]
# Push changes to remote repository (remembered branch)
git push
# Force push changes (use with caution!)
git push --force
# Delete a remote branch
git push origin --delete [branch name]
# Update local repository to the newest commit
git pull
# Pull changes from remote repository
git pull origin [branch name]
# Pull changes with rebase instead of merge
git pull --rebase origin [branch name]
# Add a remote repository
git remote add origin ssh://[email protected]/[username]/[repository-name].git
# Set a repository's origin branch to SSH
git remote set-url origin ssh://[email protected]/[username]/[repository-name].git
# Adds a new remote repository with the specified name and URL
git remote add <name> <repository_url>
# Lists all the remote repositories associated with the current repository
git remote -v
# Remove a remote repository
git remote remove <name>
# View changes
git log
# View changes (detailed)
git log --summary
# View changes (briefly)
git log --oneline
# View changes with graph visualization
git log --graph --oneline --decorate
# View changes for a specific file
git log --follow [file-path]
# Preview changes before merging
git diff [source branch] [target branch]
# View unstaged changes
git diff
# View staged changes
git diff --staged
# View changes between two commits
git diff [commit-id-1] [commit-id-2]
# Show what changed in a specific commit
git show [commit-id]
# See who modified each line of a file
git blame [file-name]
# Unstage your changes in your files
git reset
# Unstage a specific file
git reset [file-name]
# Unstage your committed changes
git reset HEAD^
# Reset to a specific commit (preserves changes as unstaged)
git reset [commit-id]
# Reset to a specific commit (discards all changes)
git reset --hard [commit-id]
# Almost same to the "git reset" but it also gives you the deleted files
git reset --hard
# Reset to remote branch state
git reset --hard origin/[branch-name]
# Delete and stage the changes in your file
git rm filename.extension
# Delete the file forcefully which hasn't been staged
git rm filename.extension -f
# Stage the changes and not to delete the file from working directory
git rm --cached filename.extension
# Delete a folder recursively
git rm -r folder
# Push the local branch to the remote repository
git push origin [branch-name]
# Push all local branches to remote repository
git push --all origin
# Push tags to remote repository
git push --tags
# Download objects and refs from another repository without merging
git fetch
# Fetch from all remotes
git fetch --all
# Fetch from and integrate with another repository or a local branch
git pull
# Fetch and rebase instead of merge
git pull --rebase
# Pull from specific remote and branch
git pull [remote] [branch]
# Save changes to a temporary area (stash)
git stash
# Save changes with a descriptive message
git stash save "Work in progress for feature x"
# List all stashes
git stash list
# Apply the most recent stash without removing it
git stash apply
# Apply a specific stash without removing it
git stash apply stash@{n}
# Apply and remove the most recent stash
git stash pop
# Apply and remove a specific stash
git stash pop stash@{n}
# Remove a specific stash
git stash drop stash@{n}
# Clear all stashes
git stash clear
# Create a branch from a stash
git stash branch [branch-name] stash@{n}
# Show the changes in a stash
git stash show stash@{n}
# Create a lightweight tag
git tag [tag-name]
# Create an annotated tag
git tag -a [tag-name] -m "[tag message]"
# List all tags
git tag -l
# Delete a tag
git tag -d [tag-name]
# Push a specific tag to remote
git push origin [tag-name]
# Push all tags to remote
git push origin --tags
# Cherry-pick a commit from another branch
git cherry-pick [commit-id]
# Rebase current branch onto another branch
git rebase [branch-name]
# Interactive rebase for editing commits
git rebase -i HEAD~[number-of-commits]
# Clean untracked files from working directory
git clean -n # Dry run (shows what would be deleted)
git clean -f # Actually delete files
# Clean untracked files and directories
git clean -fd
# Bisect to find a bug
git bisect start
git bisect bad # Current commit has the bug
git bisect good [commit-id] # Known good commit
# Git will help you find the commit that introduced the bug
- Initialize repository or clone existing repository
- Create a branch for your feature/fix
- Make changes to files
- Stage changes with
git add
- Commit changes with
git commit
- Push changes to remote with
git push
- Create pull request (on GitHub/GitLab/Bitbucket)
- Merge pull request after review
- Create a feature branch from main/master
git checkout -b feature/new-feature main
- Develop the feature with regular commits
git add . git commit -m "Add new feature component"
- Push feature branch to remote
git push -u origin feature/new-feature
- Create pull request for code review
- After approval, merge to main/master
git checkout main git merge feature/new-feature git push
-
Maintain two primary branches:
main
ormaster
(production code)develop
(integration branch)
-
Create feature branches from
develop
git checkout -b feature/new-feature develop
-
Create release branches when preparing a release
git checkout -b release/1.0.0 develop
-
Create hotfix branches from
main
for production fixesgit checkout -b hotfix/critical-bug main
-
Merge flow:
- Features β
develop
- Releases β
main
anddevelop
- Hotfixes β
main
anddevelop
- Features β
# Create a new commit that undoes changes
git revert <commit-hash>
git push
# Find the SHA of the deleted branch tip
git reflog
# Create a new branch at that commit
git checkout -b <branch-name> <sha>
- Run
git status
to see conflicted files - Open conflicted files and resolve conflicts manually
- Look for conflict markers (
<<<<<<<
,=======
,>>>>>>>
) - Stage resolved files with
git add <file>
- Complete the merge with
git commit
# If the merge is not pushed yet
git reset --hard HEAD~1
# If the merge is already pushed
git revert -m 1 <merge-commit-hash>
# Save current work
git stash
# Create or checkout target branch
git checkout <target-branch>
# Apply commits via cherry-pick
git cherry-pick <commit-hash>
# Return to original branch and drop applied commits
git checkout <original-branch>
git reset --hard <hash-before-commits>
A: Git is a version control system that manages your code history locally. GitHub is a cloud-based hosting service for Git repositories, providing collaboration features like pull requests, issues, and code reviews.
A: While command line provides the full power of Git, you can use GUI tools like GitHub Desktop, GitKraken, or SourceTree for most common operations without knowing command line commands.
A: If you haven't pushed the commit, use git reset HEAD~1
to undo the commit but keep changes, or git reset --hard HEAD~1
to completely discard the commit and its changes.
A: It depends on your team size and project needs:
- Small teams: Feature branch workflow
- Larger teams with regular releases: Gitflow
- Continuous deployment: Trunk-based development with feature flags
A:
# Add the original repository as an upstream remote
git remote add upstream https://github.com/original-owner/original-repository.git
# Fetch the changes
git fetch upstream
# Merge the changes into your local branch
git merge upstream/main
A: Merge conflicts happen when Git can't automatically merge changes. To resolve:
- Run
git status
to see conflicted files - Edit the files to resolve conflicts (remove conflict markers)
- Add resolved files with
git add <filename>
- Complete the merge with
git commit
A:
# If not pushed yet, amend the last commit
git rm --cached sensitive-file
git commit --amend
# If already pushed, you'll need BFG Repo-Cleaner or git-filter-repo
# and to force push (requires special handling)
A: A good format is:
feat(component): add login functionality
Implement user authentication with OAuth2.
Resolves: #123
Elements:
- Type: feat, fix, docs, style, refactor, test, chore
- Scope: what part of code is affected
- Short summary (imperative mood)
- Optional detailed description
- Optional references to issues
A:
# Interactive rebase to the commit before the ones you want to squash
git rebase -i HEAD~3 # To squash last 3 commits
# In the editor, change "pick" to "squash" for commits you want to combine
# Save and provide a new commit message
- Official Git Documentation
- GitHub Learning Lab
- Pro Git Book
- Git Cheat Sheet by GitHub
- Interactive Git Branching Tutorial
- Git Flight Rules
- Atlassian Git Tutorials
- Oh Shit, Git!?! - Practical solutions for common Git mistakes
- GitHub Skills - Interactive GitHub learning courses
- Git Visual Cheat Sheet - Visual representation of Git commands
Feel free to contribute to this repository by submitting pull requests or opening issues! π
If you found this guide helpful, consider giving it a β star!