Git by Example
-
Basic Concepts:
- Version Control: Tracks file changes over time.
- Repository (Repo): Folder tracked by Git.
- Commit: Snapshot of repo at a specific point.
-
Importance in Software Development:
- Tracks history, enables collaboration, manages changes.
-
Basic Commands:
- Init:
git init
mkdir MyProject; cd MyProject; git init
- Clone:
git clone [URL]
git clone https://github.com/user/repo.git
- Status:
git status
git status
- Add:
git add [file]
orgit add .
git add myfile.txt
- Commit:
git commit -m "message"
git commit -m "Initial commit"
- Init:
Git Setup and Configuration
-
Configuring User Information:
- Set your name:
git config --global user.name "Your Name"
git config --global user.name "John Doe"
- Set your email:
git config --global user.email "your_email@example.com"
git config --global user.email "john@example.com"
- Set your name:
-
Checking Configuration:
- View all settings:
git config --list
- Get a specific setting:
git config user.name
- View all settings:
-
Global vs Local Configuration:
- Global: Applies to all repositories on your system.
- Local: Applies to the specific repository.
- Set local config:
git config user.name "Local Name"
-
Help and Documentation:
- General help:
git help
- Command-specific help:
git help [command]
git help commit
- General help:
Git Basic Operations
-
Initializing a New Repository:
git init
mkdir NewProject; cd NewProject; git init
-
Cloning an Existing Repository:
git clone [URL]
git clone https://github.com/user/repo.git
-
Checking Status:
git status
git status
-
Adding Changes to Staging:
- Add a specific file:
git add [file]
- Add all changes:
git add .
git add index.html
- Add a specific file:
-
Committing Changes:
git commit -m "Commit message"
git commit -m "Initial commit"
-
Pulling Changes from Remote:
git pull [remote] [branch]
git pull origin main
-
Pushing Changes to Remote:
git push [remote] [branch]
git push origin main
-
Viewing Commit History:
git log
- For a concise view:
git log --oneline
Git Branching and Merging
-
Listing Branches:
git branch
git branch
-
Creating a New Branch:
git branch [branch-name]
git branch feature-x
-
Switching Branches:
git checkout [branch-name]
git checkout feature-x
- For newer versions of Git:
git switch [branch-name]
-
Merging a Branch:
- Merge into the current branch:
git merge [branch-name]
git merge feature-x
- Merge into the current branch:
-
Deleting a Branch:
git branch -d [branch-name]
git branch -d feature-x
-
Resolving Merge Conflicts:
- Manually edit files with conflicts, then
git add [file]
andgit commit
- Manually edit files with conflicts, then
-
Stashing Changes:
- Stash changes:
git stash
- Apply stashed changes:
git stash apply
- List stashes:
git stash list
- Drop a stash:
git stash drop
- Stash changes:
Git Working with Remotes
-
Viewing Remote Repositories:
git remote -v
git remote -v
-
Adding a Remote Repository:
git remote add [remote-name] [URL]
git remote add origin https://github.com/user/repo.git
-
Fetching Changes from Remote:
git fetch [remote-name]
git fetch origin
-
Pulling Changes from Remote:
git pull [remote-name] [branch]
git pull origin main
-
Pushing Changes to Remote:
git push [remote-name] [branch]
git push origin main
-
Removing a Remote:
git remote remove [remote-name]
git remote remove origin
-
Renaming a Remote:
git remote rename [old-name] [new-name]
git remote rename origin github
Git Advanced Features
-
Stashing Changes:
- Stash changes:
git stash
- Apply stashed changes:
git stash apply
- List stashes:
git stash list
- Drop a stash:
git stash drop
git stash; git stash apply
- Stash changes:
-
Rebasing:
- Rebase current branch:
git rebase [base-branch]
- Interactive rebase:
git rebase -i [base-branch]
git rebase main
- Rebase current branch:
-
Interactive Rebasing for Cleaning Up History:
- Start interactive rebase:
git rebase -i HEAD~[number]
- Squash commits, reword messages, etc.
git rebase -i HEAD~3
- Start interactive rebase:
-
Cherry-Picking Commits:
- Apply specific commit to current branch:
git cherry-pick [commit-hash]
git cherry-pick 4a2b6f
- Apply specific commit to current branch:
-
Using Reflog to Recover Lost Commits:
- View reflog:
git reflog
- Recover lost commit:
git checkout [commit-hash]
git reflog; git checkout 4a2b6f
- View reflog:
-
Working with Submodules:
- Add submodule:
git submodule add [URL] [path]
- Initialize submodule:
git submodule init
- Update submodule:
git submodule update
git submodule add https://github.com/user/repo.git libs/repo
- Add submodule:
Git Undoing Changes
-
Reverting Unstaged Changes:
- Revert changes in a specific file:
git checkout -- [file]
git checkout -- myfile.txt
- Revert changes in a specific file:
-
Uncommitting Last Commit (Keep Changes):
git reset --soft HEAD~1
git reset --soft HEAD~1
-
Uncommitting & Deleting Changes:
git reset --hard HEAD~1
git reset --hard HEAD~1
-
Reverting a Commit:
- Create a new commit that undoes all changes made in a specific commit:
git revert [commit-hash]
git revert 4a2b6f
- Create a new commit that undoes all changes made in a specific commit:
-
Resetting a File to a Specific Commit:
git checkout [commit-hash] -- [file]
git checkout 4a2b6f -- myfile.txt
-
Cleaning Untracked Files:
- Remove untracked files:
git clean -f
- To also remove directories:
git clean -fd
git clean -fd
- Remove untracked files:
Git Viewing Commit History
-
Viewing the Commit Log:
- Basic log:
git log
git log
- Basic log:
-
Viewing a Concise Commit Log:
- One line per commit:
git log --oneline
git log --oneline
- One line per commit:
-
Viewing the Log for a Specific File:
git log -- [file]
git log -- README.md
-
Viewing Changes Over Time:
- Show changes:
git log -p
git log -p
- Show changes:
-
Filtering the Log:
- By author:
git log --author="[name]"
- By date:
git log --since="2023-01-01"
- By commit message:
git log --grep="[keyword]"
git log --author="John"
- By author:
-
Viewing a Graph of Commits:
git log --graph
git log --graph
-
Viewing Stats for Each Commit:
git log --stat
git log --stat
Git Tagging
-
Listing Tags:
git tag
git tag
-
Creating a Lightweight Tag:
git tag [tag-name]
git tag v1.0
-
Creating an Annotated Tag:
git tag -a [tag-name] -m "Tag message"
git tag -a v1.1 -m "Release version 1.1"
-
Showing Tag Information:
git show [tag-name]
git show v1.0
-
Deleting a Tag:
git tag -d [tag-name]
git tag -d v1.0
-
Pushing Tags to Remote:
- Push a specific tag:
git push [remote] [tag-name]
- Push all tags:
git push [remote] --tags
git push origin v1.0
- Push a specific tag:
-
Checking Out Tags:
git checkout [tag-name]
git checkout v1.0
Git Branching Strategies
-
Git Flow:
- A robust branching model for managing larger projects.
- Main branches:
master
,develop
- Supporting branches: Feature, Release, Hotfix
- Start a feature:
git checkout -b feature/new-feature develop
-
Feature Branch Workflow:
- Every new feature is developed in a dedicated branch.
- Merge feature branches into
main
ordevelop
after review. - Merge a feature:
git checkout develop; git merge feature/new-feature
-
Forking Workflow:
- Each contributor has their own server-side repository.
- Changes are integrated by issuing pull requests.
- Fork a project on GitHub, clone, and work in your repository.
-
Pull Request Workflow:
- Similar to the Forking Workflow but within the same repository.
- Contributors push branches and create pull requests for review.
- Push a branch:
git push origin feature/new-feature
-
Trunk-Based Development:
- Developers work on short-lived branches merged into
trunk
ormain
. - Emphasizes continuous integration and delivery.
- Merge to trunk frequently:
git checkout main; git merge feature/new-feature
- Developers work on short-lived branches merged into
Git Collaboration and Workflow
-
Cloning a Repository for Collaboration:
git clone [URL]
git clone https://github.com/user/project.git
-
Updating Your Local Repository:
- Fetch and merge changes:
git pull [remote] [branch]
git pull origin main
- Fetch and merge changes:
-
Working on a New Feature:
- Create and switch to a new branch:
git checkout -b feature-branch
git checkout -b feature/login
- Create and switch to a new branch:
-
Making Changes and Committing:
- Make changes,
git add .
, andgit commit -m "Add feature"
- Make changes,
-
Pushing Changes:
- Push your branch:
git push origin feature-branch
git push origin feature/login
- Push your branch:
-
Creating a Pull Request:
- Push your branch and create a pull request via the repository’s website.
-
Reviewing Changes:
- Review code changes in the pull request.
- Provide feedback or approve the changes.
-
Merging the Pull Request:
- Once approved, merge the pull request.
- Delete the feature branch if necessary.
-
Keeping Your Branch Up to Date:
- Regularly merge changes from the main branch:
git checkout feature-branch; git merge main
- Regularly merge changes from the main branch:
-
Handling Merge Conflicts:
- Resolve conflicts manually in the affected files.
- After resolving,
git add .
andgit commit
-
Code Reviews:
- Participate in code reviews for quality assurance.
-
Using Issue Trackers:
- Utilize issue trackers for managing tasks and bugs.
Git Troubleshooting and Best Practices
-
Common Issues and Solutions:
- Merge Conflicts: Manually resolve conflicts in files, then
git add
andgit commit
. - Detached HEAD: Reattach by checking out to a branch, e.g.,
git checkout main
. - Lost Commits: Recover using
git reflog
andgit checkout [commit-hash]
.
- Merge Conflicts: Manually resolve conflicts in files, then
-
Best Practices for Commit Messages:
- Keep the first line under 50 characters.
- Use the imperative mood in the subject line.
- Include a detailed description if necessary.
-
Branching Best Practices:
- Use clear branch names (e.g.,
feature/add-login
,bugfix/resolve-crash
). - Delete branches after merging.
- Use clear branch names (e.g.,
-
Keeping a Clean History:
- Squash commits when merging feature branches.
- Avoid merging with unresolved conflicts.
-
Regularly Syncing with Remote:
- Frequently pull changes from the main branch to avoid large merge conflicts.
-
Using .gitignore:
- Ignore files that don’t need to be tracked (e.g., logs, system files).
- Create a
.gitignore
file with entries like*.log
,node_modules/
.
-
Handling Large Files:
- Use Git Large File Storage (LFS) for tracking large files.
-
Security Practices:
- Regularly update Git to the latest version.
- Be cautious with Git hooks and third-party tools.
-
Collaboration Etiquette:
- Communicate clearly and frequently with your team.
- Respect the project’s contribution guidelines.
-
Using Git with Docker:
- Manage Dockerfile and docker-compose.yml in Git.
- Integrate with Docker Hub for automated image builds.
-
Git and Code Review Tools:
- Integrate with platforms like GitHub, GitLab, Bitbucket for pull requests and code reviews.
- Use code review tools for automated code quality checks.
-
Security Integrations:
- Integrate security scanning tools to check code for vulnerabilities on commit or push.
-
Git in Cloud Environments:
- Use Git with cloud providers like AWS, Azure, and GCP for source code management in cloud projects.
Git Internals and Advanced Concepts
-
Understanding Git Objects:
- Git stores data as objects: blobs, trees, commits, and tags.
- Explore objects in
.git/objects
.
-
The .git Directory:
- Contains all Git metadata and object database.
- Key subdirectories:
objects/
,refs/
,hooks/
,info/
,logs/
.
-
Git References:
- Refs are pointers to commits (e.g., branches, tags).
- Located in
.git/refs/
.
-
The HEAD File:
- Points to the current branch reference.
- Found in
.git/HEAD
.
-
Index File:
- The staging area is represented by the index file in
.git/index
.
- The staging area is represented by the index file in
-
Git Plumbing and Porcelain Commands:
- Plumbing commands: Low-level (e.g.,
git cat-file
,git update-index
). - Porcelain commands: User-friendly (e.g.,
git add
,git commit
).
- Plumbing commands: Low-level (e.g.,
-
Git Hooks for Custom Scripts:
- Automate tasks with scripts in
.git/hooks/
. - Pre-commit hooks for linting.
- Automate tasks with scripts in
-
Working with Git’s Garbage Collection:
- Clean up and optimize repository with
git gc
.
- Clean up and optimize repository with
-
Exploring the Commit Graph:
- Use
git log --graph
for a visual representation of the commit history.
- Use
-
Advanced Merging and Rebase Strategies:
- Use strategies like
ours
,theirs
,octopus
for complex merges. - Interactive rebasing for sophisticated history rewriting.
- Use strategies like
-
Bare Repositories:
- Repositories without a working directory (e.g., server-side repos).
- Created with
git init --bare
.
-
Git Attributes:
- Customize Git’s behavior on a per-path basis with
.gitattributes
.
- Customize Git’s behavior on a per-path basis with
-
Git Submodules and Subtrees:
- Manage dependencies or component-based development.
- Submodules link to other repositories; subtrees merge project into subdirectories.
Git for Large Repositories and Performance Optimization
-
Handling Large Files with Git LFS (Large File Storage):
- Install Git LFS:
git lfs install
- Track large files:
git lfs track "*.psd"
git lfs track "*.zip"
- Install Git LFS:
-
Partial Clone and Shallow Clone:
- Shallow clone (limited history):
git clone --depth 1 [URL]
- Partial clone (specific paths):
git clone --filter=blob:none --sparse [URL]
git clone --depth 1 https://github.com/large/repo.git
- Shallow clone (limited history):
-
Sparse Checkout:
- Initialize sparse-checkout:
git sparse-checkout init
- Set the patterns:
git sparse-checkout set [directory]
git sparse-checkout set src/images
- Initialize sparse-checkout:
-
Optimizing Git Operations:
- Garbage collection:
git gc
- Prune objects:
git prune
- Repack objects:
git repack
- Garbage collection:
-
Using Bitmapped Indexes:
- Enable bitmapped index for faster fetches:
git config --global pack.useBitmaps true
- Enable bitmapped index for faster fetches:
-
Repository Maintenance:
- Regularly run
git maintenance start
for automated maintenance tasks.
- Regularly run
-
Dealing with Repository Bloat:
- Identify large files in history: Use tools like
git-sizer
orBFG Repo-Cleaner
. - Remove unnecessary large files from history.
- Identify large files in history: Use tools like
-
Network and Transfer Optimizations:
- Use protocol version 2 for more efficient data transfer:
git config --global protocol.version 2
- Use protocol version 2 for more efficient data transfer:
-
Filesystem Monitor (fsmonitor) Integration:
- Speed up Git commands in large repositories by integrating with a filesystem monitor.
- Tags:
- devops
- development