Introduction
Hey everyone! Welcome to the series on Git. Let's get started! This series is not about memorizing every single command available in Git. Instead, we will focus on understanding the workflow and some behind-the-scenes details of how Git works. This will be a balance of theory and practical exercises. I highly recommend following along by typing these commands yourself—it enhances the learning experience. Let's dive in!
Setup and Overview
We will primarily use the terminal for this series, although Git is available on GUI platforms as well. Understanding commands will improve your performance in GUIs too. On one screen, we have our browser for occasional reference, and on the other, our handwritten notes for a structured approach.
Git and GitHub are often confused, but they serve different purposes. Git is the software we use for version control, while GitHub is a service that hosts Git repositories. Other similar services include Bitbucket and GitLab.
Initializing a Repository
To start using Git, we need to create and initialize a repository.
Create a directory for your project. For example:
mkdir git_example cd git_example
Initialize the Git repository in this directory:
git init
Verify Git is tracking this directory by checking the status:
git status
Understanding Basic Git Commands
Let's start with some essential Git commands.
Check Git Version
git --version
This command checks the installed version of Git.
Initialize Git in a Directory
git init
This command initializes a new Git repository in your directory. Run this command once per project.
Check Git Status
git status
This command checks the current status of the repository, including any changes that need to be committed.
Git Workflow
The typical Git workflow involves the following steps:
Working Directory: Where you make changes to your files.
Staging Area: Where you place files you want to commit.
Repository: Where the history of all your commits is stored.
What is Git?
Git is a software tool used for tracking changes in code and coordinating work among multiple people. GitHub is a service that hosts Git repositories. Git itself can be used with or without services like GitHub.
Installation
To get started, you'll need:
Git: Download it from git-scm.com.
Terminal: I recommend using Warp (available for Mac and Linux, with Windows in development).
Code Editor: Visual Studio Code.
Checking Git Version
After installation, open your terminal and check the Git version with:
git --version
Initializing a Repository
Let's create and initialize a Git repository:
Create Folders:
mkdir gitone gittwo gitthree
Navigate to a Folder and Initialize Git:
cd gitone git init
Check Git Status:
git status
Key Concepts
Repository (Repo): A folder tracked by Git.
Commit: A checkpoint in your code's history.
Staging Area: A place where changes are reviewed before being committed.
Basic Workflow
Add Files to Staging Area:
git add <file-name> # Or to add all files: git add .
Commit Changes:
git commit -m "Initial commit"
Hidden .git Folder
When you initialize a Git repository, a hidden .git
folder is created to track your files. Never manually alter this folder.
We are currently in a folder named gitone
. To check if it’s already initialized with Git, use the command:
git status
This command tells us if the repository is initialized and whether we need to initialize it.
Initializing the Repository
If the repository is not initialized, you can initialize it using:
git init
This command sets up a new Git repository.
Creating Files
Let’s create a couple of files in our directory:
touch testone.txt testtwo.txt
These files will now appear in your directory. If you run git status
again, you’ll see:
Untracked files:
(use "git add <file>..." to include in what will be committed)
testone.txt
testtwo.txt
This output indicates that the files are not yet tracked by Git.
Adding Files to the Staging Area
To start tracking a file, you use the git add
command. Let’s add testone.txt
:
git add testone.txt
If you run git status
again, you’ll see:
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: testone.txt
This output shows that testone.txt
is now in the staging area, ready to be committed.
Committing Changes
To commit the changes, we use the git commit
command. It’s crucial to provide a message with each commit to describe what the commit does. For example:
git commit -m "Add testone.txt"
This command commits the changes with the message "Add testone.txt". If you omit the -m
flag, Git will open the default text editor for you to write the commit message.
Configuring Git
Git uses configuration settings to store your identity. If you haven’t configured it yet, you can do so using the following commands:
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
These commands set your name and email globally for all repositories on your machine.
Exploring Git Log
To see the commit history, you can use:
git log
This command shows detailed information about each commit, including the commit ID, author, date, and commit message. For a more concise view, use:
git log --oneline
This command gives a brief overview of the commit history.
Recap and Next Steps
In this video, we covered:
Initializing a Git repository
Creating and adding files to the staging area
Committing changes with a message
Configuring Git with your name and email
Viewing the commit history
Git Configuration
Setting Up Your Global Configuration
Git requires your name and email address to associate commits with you. You can configure these settings globally or locally:
Global Configuration:
git config --global user.name "Your Name" git config --global user.email "your.email@example.com"
Local Configuration:
git config --local user.name "Your Name" git config --local user.email "your.email@example.com"
Setting Your Default Editor
By default, Git uses Vim as the editor for commit messages. You can change this to your preferred editor, such as VS Code:
Configure VS Code as the Default Editor:
git config --global core.editor "code --wait"
Ensure VS Code is installed and the
code
command is available in your path. You can set this up in VS Code by opening the Command Palette (Ctrl+Shift+P) and selectingShell Command: Install 'code' command in PATH
.
Viewing Your Configuration
You can view your Git configuration using:
git config --list
This displays all the settings Git is using.
.gitignore
File
Purpose of .gitignore
The .gitignore
file tells Git which files (or patterns) it should ignore. This is useful for sensitive files like environment variables, API keys, or files that are generated during the build process.
Creating and Using .gitignore
Create a
.gitignore
File:touch .gitignore
Edit
.gitignore
:# Ignore environment files .env # Ignore node_modules directory node_modules/ # Ignore VS Code settings folder .vscode/
Check the Git Status:
git status
You should see that the files listed in
.gitignore
are no longer tracked by Git.
Using a .gitignore
Generator
For different programming languages and environments, you can use a .gitignore
generator:
Search for "gitignore generator" online.
Select the appropriate language/framework and generate a
.gitignore
file.Copy the generated content into your
.gitignore
file.
Git Logs
Viewing Git Logs
Git logs are a powerful way to see the history of commits in your repository. You can view logs in different formats:
Basic Log:
git log
One-Line Log:
git log --oneline
Customized Logs:
git log --pretty=format:"%h - %an, %ar : %s"
Understanding Commit Structure
Each commit in Git is identified by a unique hash and contains metadata such as the author's name, email, date, and commit message. Commits are linked in a chain, where each commit points to its parent commit.
Viewing Commit Hashes:
git log --oneline
Exploring Commit Objects:
ls -la .git/objects
Advanced Concepts
Exploring the .git
Directory
The .git
directory contains all the information about your repository, including configuration, logs, and commit history.
Navigate to the
.git
Directory:cd .git
View the Contents:
ls -la
Explore Hooks: Git hooks are scripts that run automatically on certain events (e.g., before a commit, after a commit). They are stored in the
.git/hooks
directory.
Understanding Git Internals
Git stores each commit as an object in the .git/objects
directory. The structure of each commit includes:
Hash: A unique identifier for the commit.
Parent: The previous commit hash.
Metadata: Information about the commit (author, date, message).
Introduction to Git Branches: A Fun Dive into Git Branching and Collaborative Coding
Setting Up Our Git Environment
We'll begin by setting up a new Git repository from scratch. I'll open up a new folder and initialize it as a Git repository. Let's navigate to our new directory:
cd git_series
mkdir git_branches
cd git_branches
Now, let's initialize this directory as a Git repository:
git init
We'll add a new file, index.html
, to get started:
echo "<!DOCTYPE html><html><head><title>Git Learning</title></head><body><h1>Welcome to Git</h1></body></html>" > index.html
Tracking Changes
Check the status of our repository:
git status
You'll see that index.html
is an untracked file. Let's add and commit this file:
git add index.html
git commit -m "Add index.html"
Understanding Branches
By default, Git creates a master
branch. Let's explore branches with the following command:
git branch
This shows that we're currently on the master
branch. Branches in Git are like parallel timelines, allowing developers to work on different features independently without affecting the main codebase.
Creating a New Branch
Let's create a new branch for a navigation bar feature:
git branch navbar
Now, switch to this new branch:
git checkout navbar
You can see that the branch has changed by checking the status:
git status
Making Changes in the Navbar Branch
Let's add a new file, navbar.html
, in the navbar
branch:
echo "<nav><ul><li>Home</li><li>About</li><li>Contact</li></ul></nav>" > navbar.html
git add navbar.html
git commit -m "Add navbar.html"
Switching Between Branches
Switch back to the master
branch:
git checkout master
Notice that the navbar.html
file is no longer in the directory. This is because it exists only in the navbar
branch. This isolation allows multiple developers to work on different features without interfering with each other.
Branch Pointers and HEAD
The HEAD
in Git points to the current branch reference. When you switch branches, HEAD
updates to point to the new branch:
git checkout navbar
You can verify the current state and branch pointers with:
cat .git/HEAD
Combining Work from Different Branches
To combine work from different branches, you can merge branches. Let's merge the navbar
branch into master
:
First, switch back to master
:
git checkout master
Now, merge the navbar
branch:
git merge navbar
Git Branching and Merging Tutorial
Creating and Switching Branches
To create and switch to a new branch, you can use the following commands:
Using
git branch
andgit checkout
:git branch navbar-footer-bugfix git checkout navbar-footer-bugfix
This creates a new branch named
navbar-footer-bugfix
and switches to it.Using
git switch
(shortcut):git switch -c navbar-footer-bugfix
This command both creates and switches to the
navbar-footer-bugfix
branch in one step.Using
git checkout
with the-b
option:git checkout -b navbar-footer-bugfix
This also creates and switches to the
navbar-footer-bugfix
branch in one step.
Committing Before Switching Branches
Always commit your changes before switching to another branch to avoid losing your work. For example:
git add .
git commit -m "Your commit message"
Merging Branches
Merging branches combines the changes from different branches into a single branch. There are two types of merges:
Fast-Forward Merge:
This type of merge occurs when the target branch has not diverged from the current branch. Git simply moves the pointer forward.
Example:
git checkout master git merge navbar-footer-bugfix
Three-Way Merge:
This occurs when there are changes in both branches that need to be combined. Git will create a new merge commit.
Example:
git checkout master git merge navbar-footer-bugfix
Handling Merge Conflicts
Conflicts happen when the same lines in a file are changed in different branches. Git will prompt you to resolve these conflicts manually.
Example of a Merge Conflict
Assume the master
branch has a change in index.html
:
<!-- master branch -->
<footer>Footer added</footer>
The footer
branch also changes the same line:
<!-- footer branch -->
<footer>Footer was added successfully</footer>
When you merge footer
into master
, a conflict will occur.
Attempt the Merge:
git checkout master git merge footer
Resolve the Conflict: Open the conflicting file,
index.html
. Git will mark the conflicts:<<<<<<< HEAD <footer>Footer added</footer> ======= <footer>Footer was added successfully</footer> >>>>>>> footer
Edit the File: Choose the content you want to keep, remove the conflict markers (
<<<<<<<
,=======
,>>>>>>>
):<footer>Footer was added successfully</footer>
Add and Commit the Resolved File:
git add index.html git commit -m "Resolved merge conflict in index.html"
Deleting Branches
After merging a branch, you can delete it if it’s no longer needed:
Delete a Branch Locally:
git branch -d navbar-footer-bugfix
Force Delete a Branch: If the branch hasn't been merged, you can force delete it using:
git branch -D navbar-footer-bugfix
Visualizing Branches and Merges
Using tools like git log
with the --graph
option or extensions like GitLens in VSCode can help visualize the branching and merging process.
Example:
git log --graph --oneline --all
This command provides a graphical representation of your commit history, showing branches and merges.
Git Diff
The git diff
command is used to show the differences between various states of your repository. A common misconception is that git diff
compares two different files. However, it actually compares different versions of the same file. This could be the same file at different times, such as before and after staging changes, or between two commits.
Key Points:
Comparing Versions: It shows the differences between file versions over time.
Symbols: The
--
and++
symbols indicate lines removed and added, respectively, but they also represent different versions of the same file.Practical Usage: You can compare the working directory to the staging area, or compare two commits or branches.
Git Stash
git stash
is another powerful command that allows you to save your changes temporarily without committing them. This is useful when you need to switch branches or pull updates without committing unfinished work.
Practical Demonstration
Git Diff
Initial Setup:
- Ensure your working directory is clean by running
git status
.
- Ensure your working directory is clean by running
Making Changes:
- Let's modify an
index.html
file by removing some empty spaces and adding anavbar
.
- Let's modify an
<!-- Before -->
<!DOCTYPE html>
<html>
<head>
<title>Look Good Project</title>
</head>
<body>
<h1>Look Good Project</h1>
<!-- Some empty spaces removed -->
</body>
</html>
<!-- After -->
<!DOCTYPE html>
<html>
<head>
<title>Look Good Project</title>
</head>
<body>
<nav>Navbar</nav>
<h1>Look Good Project</h1>
</body>
</html>
Staging the Changes:
- Add the changes to the staging area using
git add index.html
.
- Add the changes to the staging area using
Using Git Diff:
- Run
git diff --staged
to see the changes between your working directory and the staged area.
- Run
git diff --staged
- The output will show differences with
--
symbols for removals and++
symbols for additions. This indicates the transformation of the file from its previous state to the staged state.
Further Changes:
- Modify another part of your file, such as the footer.
<!-- Before -->
<footer>Nice Footer 2024</footer>
<!-- After -->
<footer>Awesome Footer</footer>
Staging and Diff:
- Stage the footer changes and use
git diff --staged
again to see the new changes.
- Stage the footer changes and use
git add footer.html
git diff --staged
Commit the Changes:
- Commit the changes with a meaningful message.
git commit -m "Update index and footer"
Checking Logs and Comparing Commits:
- Use
git log --oneline
to see commit history.
- Use
git log --oneline
- Compare specific commits using their IDs with
git diff
.
git diff <commit-id1> <commit-id2>
This will show you the differences between the two specified commits.
Git Stash
We'll cover git stash
in detail in the next video, where we'll see how to temporarily save changes and retrieve them.
Summary
git diff
: Essential for comparing different versions of files within your Git repository.git stash
: Allows you to temporarily save changes without committing.
Git Workflow: Understanding Branching, Stashing, and Rebasing
In this guide, we'll cover essential Git commands and workflows, focusing on branching, stashing, and rebasing. By the end, you'll understand how to efficiently manage your Git repository, handle changes, and collaborate with others.
1. Git Branching
Branching is a critical feature in Git, allowing you to work on different features or bug fixes independently.
Creating and Switching Branches
To create a new branch and switch to it:
git checkout -b new-branch
Alternatively:
git switch -c new-branch
To switch to an existing branch:
git checkout existing-branch
Alternatively:
git switch existing-branch
Merging Branches
To merge changes from another branch into your current branch:
git merge branch-to-merge
2. Git Diff
git diff
helps you see the changes between commits, branches, or the working directory.
Comparing Commits
git diff commit1 commit2
Comparing Branches
git diff branch1..branch2
The double-dot (..
) notation is preferred for backward compatibility, while space can be used in newer Git versions.
3. Git Stashing
Stashing allows you to save changes temporarily without committing them, enabling you to switch branches without losing your work.
Stashing Changes
git stash
Viewing Stashes
git stash list
Applying Stashes
To apply the most recent stash:
git stash pop
To apply a specific stash:
git stash apply stash@{index}
4. Git Checkout and Restore
git checkout
can be used to view the state of files from previous commits or branches.
Viewing Past Commits
git checkout commit-hash
To go back to the main branch:
git checkout master
Alternatively, use git reflog
to see a history of changes and return to a previous state.
Restoring Files
To restore a file to its state in the last commit:
git restore file-path
5. Git Rebase
Rebasing is used to integrate changes from one branch into another. Unlike merging, which creates a commit for the merge, rebasing rewrites the commit history.
Basic Rebase
To rebase feature-branch
onto main
:
git checkout feature-branch
git rebase main
Example Workflow
Let's walk through an example scenario to demonstrate these concepts:
Branching and Making Changes:
git checkout -b feature-branch # Make changes to files git add . git commit -m "Updated feature"
Stashing and Switching Branches:
git stash git switch main # Make urgent changes on main branch git add . git commit -m "Urgent fix on main"
Returning to the Feature Branch:
git switch feature-branch git stash pop
Rebasing Feature Branch onto Main:
git checkout feature-branch git rebase main
Resolving Conflicts (if any):
# Edit files to resolve conflicts git add resolved-file git rebase --continue
Final Merge:
git switch main git merge feature-branch
Git Workflow: Merging and Rebasing Explained
Introduction
Hi everyone! Welcome back to our Git tutorial series. In this video, we'll dive into a common workflow involving merging and rebasing. Let's get started!
Working with Branches
Checkout to Bugfix Branch:
git checkout bugfix
Bring Code from Main Branch to Bugfix:
- Sometimes, we need to merge changes from the main branch into our current branch to stay updated. Let's do that:
git merge main
- If your main branch is named master, you can interchange 'main' with 'master'.
Commit Messages:
- Merged changes will prompt you for a commit message. Usually, the default message is fine:
Merge main into bugfix
Rebasing: A Cleaner Alternative
- Unlike merging, rebasing repositions the base of your branch, creating a cleaner commit history.
Switch to Bugfix Branch:
git checkout bugfix
Rebase onto Main:
git rebase main
- This integrates changes from the main branch into the bugfix branch, maintaining a linear history.
Handling Conflicts During Rebase
- If there are conflicts, Git will notify you. Here’s how to resolve them:
Resolve Conflicts:
- Open the conflicting file and choose which changes to keep. You can use your editor to do this. In VS Code, you can accept current changes, incoming changes, or both.
Mark Conflicts as Resolved:
git add <filename>
Continue Rebase:
git rebase --continue
- If you want to abort the rebase, use:
git rebase --abort
Rebasing Tips
Always ensure you're on the correct branch before rebasing.
Avoid rebasing commits that have been pushed to shared repositories.
Use rebase to keep your commit history clean, especially when working on feature branches.
Conclusion
Merging and rebasing are powerful tools in Git that help manage your codebase effectively.
Rebasing can seem scary because it rewrites history, but it's a valuable skill for maintaining a clean project history.
Contributing to Open Source: A Step-by-Step Guide
Introduction
Hey everyone, welcome back to another video! Today, we’re concluding our Git and GitHub series by diving into the fascinating world of open source. Many of you are excited about contributing to open source, and some of you see it as a pathway to landing a job. While contributing to open source can certainly boost your credentials, it’s important to understand the ecosystem and approach it correctly.
As someone who maintains several open-source projects, I have firsthand experience in contributing to and managing these projects. Let’s explore how you can effectively contribute to open source.
Understanding Open Source
Open source is not just about making your code public. It’s a philosophy that software should be freely distributed to save other developers time and to contribute to the community. Many developers, including those with full-time jobs, contribute to open source projects in their free time to give back to the community.
However, contributing to open source isn’t about taking these projects for granted. It’s about adding value and collaborating respectfully. Let’s walk through the steps you need to follow to make meaningful contributions to open source projects.
Step-by-Step Roadmap for Contributing
Step 1: Talk
Before you write any code, the first step is to talk to the maintainers of the project. Communication is key. Use the issue tracker on GitHub, join the project's Discord server, or reach out on Slack. Let them know what you want to work on. This prevents duplicating efforts and ensures your contribution is needed.
Step 2: Open an Issue
Once you have communicated with the maintainers, open an issue on the project’s GitHub repository. Describe what you want to work on, whether it’s fixing a bug, adding a feature, or improving documentation. This creates a record of your intention to contribute and allows maintainers to assign the issue to you.
Step 3: Work and Add Value
Contributions should add value to the project. While fixing typos or minor issues in documentation is helpful, try to focus on code contributions. Whether you’re fixing bugs or adding new features, ensure your work genuinely improves the project.
Step 4: Make a Pull Request (PR)
After completing your work, make a pull request. This is a formal request to merge your changes into the project’s main codebase. Be prepared for feedback and iterations. Maintainers might ask you to make changes before they can merge your PR.
Step 5: Iterate
Iterating on your pull request is part of the process. Address feedback, resolve conflicts, and improve your code as requested by the maintainers. Remember, maintainers are busy people with full-time jobs, so be patient while waiting for feedback.
Step 6: Celebrate
Once your pull request is merged, take a moment to celebrate your contribution. Share your achievement on social media, and feel proud of the value you’ve added to the community.
Key Points to Remember
Talk to Maintainers: Always communicate with the project maintainers before starting any work.
Add Value: Focus on making meaningful contributions that improve the project.
Be Patient: Understand that maintainers have other responsibilities and might take time to review your work.
Iterate and Improve: Be open to feedback and willing to make necessary changes to your code.
Celebrate Contributions: Take pride in your contributions and share your achievements.
Example of Making a Pull Request
To illustrate these steps, I’ve created a new GitHub account and an open-source test project. Here’s how you can make a pull request:
Fork the Repository: Fork the project repository to your GitHub account.
Clone Your Fork: Clone the forked repository to your local machine.
Create a New Branch: Create a new branch for your changes.
Make Your Changes: Implement the changes you discussed with the maintainers.
Commit and Push: Commit your changes to the new branch and push them to your GitHub repository.
Open a Pull Request: Navigate to the original repository and open a pull request from your branch.
Conclusion
Contributing to open source is a rewarding experience that allows you to give back to the developer community. By following these steps, you can make meaningful contributions, improve your skills, and potentially open doors to new opportunities. Remember, the key to successful open-source contributions is communication, adding value, and patience.
First, let's understand that open source isn't just about making your source code available on platforms like GitHub or Bitbucket. It's a philosophy that software should be freely distributed, allowing programmers to save time and contribute to the community. Open source projects, regardless of their size, should never be taken for granted. Many full-time software engineers contribute to open source projects in their free time to give back to the community. However, some people abuse this generosity by spamming maintainers with requests or viewing open source as a shortcut to getting a job. This approach is not appropriate and misses the true spirit of open source.
In this video, I'll walk you through how to contribute to open source projects effectively. Here's a roadmap you can follow:
Step 1: Talk
Before contributing, always talk to the project maintainers. You can do this through the project's issues tab, or via platforms like Discord or Slack. Communicating your intention to work on a feature or fix a bug is crucial. This prevents duplication of effort and ensures your contribution is needed. Without talking, open source doesn't work.
Step 2: Open an Issue
Once you’ve discussed your contribution, open an issue on the project’s repository. Describe what you intend to work on, whether it's fixing a bug or adding a feature. Getting the issue assigned to you helps maintainers keep track of who is working on what.
Step 3: Work and Add Value
Focus on contributing meaningful code. While documentation is important, significant contributions to the codebase demonstrate your skills better. Your goal should be to add real value to the project.
Step 4: Make a Pull Request
After completing your work, make a pull request (PR). Be prepared for feedback and be ready to iterate on your code. Maintainers may ask for changes or improvements. This back-and-forth is normal and part of the collaboration process.
Step 5: Celebrate
Once your PR is accepted, celebrate your contribution! Share it on social media and feel proud of your work. Remember, open source is about donating your time and skills without expecting anything in return.
Example Workflow: Adding a Navbar
Let's go through a practical example of contributing to an open source project by adding a navbar. We'll fork a repository, create a new branch, make changes, and submit a PR.
Fork the Repository: Start by forking the repository to your account.
Clone the Repository: Clone the forked repository to your local machine.
git clone <your-fork-url> cd <repository-name>
Create a New Branch: Create a new branch for your feature.
git checkout -b navbar
Make Your Changes: Add the navbar code in your preferred editor.
<!-- navbar.html --> <nav> <ul> <li>Home</li> <li>About Us</li> <li>Contact Us</li> </ul> </nav>
Commit Your Changes: Stage and commit your changes.
git add navbar.html git commit -m "Add navbar feature"
Push Your Branch: Push your branch to your fork.
git push origin navbar
Create a Pull Request: Go to your fork on GitHub and create a pull request from your branch to the original repository’s main branch. Write a detailed description of your changes.
Wait for Review: Maintainers will review your PR. They might ask for changes or give feedback. Respond to feedback and iterate on your code if necessary.
Merge and Celebrate: Once approved, your PR will be merged. Celebrate your contribution!
Open source is a powerful way to contribute to the software community, improve your skills, and potentially gain visibility. Use Git and GitHub daily to become proficient and make valuable contributions. Share your successes and help others learn from your journey.
Huge Thanks to Hitesh Choudhary Sir
Follow me On X(twitter) - @DexterIfti