KEMBAR78
Git Github Notes | PDF | Version Control | Software
0% found this document useful (0 votes)
17 views38 pages

Git Github Notes

The document provides an overview of version control systems, particularly focusing on Git and GitHub. It explains the importance of version control, types of systems, benefits of using Git, and basic Git operations including installation, configuration, and file lifecycle management. Additionally, it covers how to stage and commit changes, view commit history, and the fundamental commands necessary for effective version control.

Uploaded by

vision satya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views38 pages

Git Github Notes

The document provides an overview of version control systems, particularly focusing on Git and GitHub. It explains the importance of version control, types of systems, benefits of using Git, and basic Git operations including installation, configuration, and file lifecycle management. Additionally, it covers how to stage and commit changes, view commit history, and the fundamental commands necessary for effective version control.

Uploaded by

vision satya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 38

Git & Github Notes

Module 1: Introduction to Version Control


What is Version Control?

Version Control (also known as Revision Control or Source Control) is a system that records changes to a file or
set of files over time so that you can recall specific versions later. It's an essential tool for any software
development project, but it can be used to track changes to any type of file (e.g., documents, websites, design
assets).
Imagine you're working on a document, and you save multiple copies with names like
document_final.docx , document_final_v2.docx , document_final_really_final.docx . This quickly becomes messy and makes it difficult to

track what changes were made in each version, or to revert to an older, working version if something goes wrong.
Version control solves this problem by providing a structured way to manage these changes.
Key aspects of version control include:

Tracking Changes: It keeps a detailed history of every modification made to your files.

Collaboration: It allows multiple people to work on the same project simultaneously without overwriting each
other's work.

Reversion: You can easily revert to previous versions of your files or the entire project.

Branching and Merging: It enables developers to work on separate features or bug fixes in isolation (branches)
and then integrate those changes back into the main project (merging).
Types of Version Control Systems

There are three main types of Version Control Systems (VCS):


1.
Local Version Control Systems (LVCS):
◦ In a local VCS, all versioning information is stored directly on your local machine.

How it works: Tools like RCS (Revision Control System) keep patches (the differences between files) in a special
format on disk. You can then recreate any file's state at any point in time by adding up all the patches.

Pros: Simple to set up and use for individual projects.

Cons: High risk of data loss if your local machine fails. No collaboration features.
2.
Centralized Version Control Systems (CVCS):
◦ CVCS use a single central server to store all versioned files, and clients check out files from that central place.

Examples: CVS, Subversion (SVN), Perforce.

How it works: Developers "check out" files from the central repository, make changes, and then "check in" their
changes back to the server.

Pros: Easier to manage permissions, and everyone can see what everyone else is doing. A single point of truth for
the project.

Cons: Single point of failure (if the central server goes down, no one can collaborate or save versioned changes).
Requires a constant network connection.
3.
Distributed Version Control Systems (DVCS):
◦ In a DVCS, every client has a full copy of the entire repository, including its complete history.

Examples: Git, Mercurial, Bazaar.

Git & Github Notes 1


How it works: When you clone a repository, you get the full history. This means you can work offline, commit
changes locally, and then synchronize with other repositories when you have a network connection.

Pros: No single point of failure (if one server goes down, any of the client repositories can be copied back to the
server to restore it). Faster operations (most operations are local). Excellent for collaboration and
branching/merging. Allows for more flexible workflows.

Cons: Initial clone can take longer due to downloading the entire history.
Benefits of using Git

Git is by far the most popular Distributed Version Control System (DVCS) today, and for good reason. Here are its
key benefits:
1.
Distributed Nature:

Resilience: Every developer has a full copy of the repository. If the central server fails, any developer's local
repository can be used to restore the project.

Offline Work: Developers can commit changes locally even without an internet connection and push them later.

Speed: Most operations (like committing, branching, merging) are performed locally, making them incredibly fast
compared to CVCS.
2.
Powerful Branching and Merging:

Easy Branching: Git makes it incredibly easy and cheap to create branches. This encourages developers to work
on new features or bug fixes in isolated environments without affecting the main codebase.

Robust Merging: Git's merging capabilities are highly sophisticated, making it efficient to integrate changes from
different branches back into the main line of development, even in complex scenarios.
3.
Data Integrity:
◦ Git uses a cryptographic hash (SHA-1) for every commit, ensuring that the history cannot be altered without
Git detecting it. This provides strong data integrity.
4.
Performance:
◦ As mentioned, local operations are very fast. Git is designed for performance, even with very large
repositories and extensive histories.
5.
Community and Ecosystem:

Vast Community Support: Being the most popular VCS, Git has a massive community, meaning abundant
resources, tutorials, and support available online.

Rich Tooling: There's a vast ecosystem of tools and platforms built around Git, such as GitHub, GitLab, Bitbucket,
various GUIs, and integrations with IDEs.
6.
Flexibility in Workflows:
◦ Git doesn't enforce a specific workflow, allowing teams to adopt various strategies like GitFlow, GitHub Flow,
or simple feature branching, depending on their needs.
7.
Open Source:
◦ Git is open-source, meaning it's free to use and has a transparent development process.

Module 2: Git Basics


This module will guide you through the fundamental steps of setting up Git on your system and performing basic
version control operations.

Git & Github Notes 2


Installing Git
Before you can use Git, you need to install it on your operating system.

Windows
1. Download the Git Installer: Go to the official Git website and download the latest installer for Windows.

2. Run the Installer: Double-click the downloaded .exe file to start the installation wizard.

3. Follow the Prompts:

Accept the GNU General Public License.

Choose your installation location (default is usually fine).

Select components (defaults are generally recommended, including Git Bash and Git GUI).

Choose your default editor (e.g., Vim, Notepad++, VS Code).

Adjust your PATH environment (the recommended option is "Git from the command line and also from 3rd-
party software").

Choose HTTPS transport backend (use the default "Use the OpenSSL library").

Configure line ending conversions (the default "Checkout Windows-style, commit Unix-style line endings"
is usually best).

Choose your terminal emulator (MinTTY is the default and recommended).

Choose the default behavior for git pull (default is usually fine).

Choose a credential helper (default "Git Credential Manager Core" is recommended).

Enable file system caching and Git's experimental features if desired.

4. Finish Installation: Click "Install" and then "Finish".

5. Verify Installation: Open Git Bash (or Command Prompt/PowerShell) and type git --version . You should see the
installed Git version.

macOS
1. Using Homebrew (Recommended):

If you don't have Homebrew installed, open your Terminal and run:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Once Homebrew is installed, install Git by running:

brew install git

2. Using the Official Installer:

Go to the official Git website and download the macOS installer.

Run the .pkg file and follow the on-screen instructions.

3. Xcode Command Line Tools: Git is also included with Xcode Command Line Tools. If you have Xcode
installed, you can install the tools by running:

xcode-select --install

4. Verify Installation: Open Terminal and type git --version . You should see the installed Git version.

Linux (Debian/Ubuntu)
1. Open Terminal: Open your terminal application.

2. Update Package List:

Git & Github Notes 3


sudo apt update

3. Install Git:

sudo apt install git

4. Verify Installation:

git --version

You should see the installed Git version.

Linux (Fedora)
1. Open Terminal: Open your terminal application.

2. Install Git:

sudo dnf install git

3. Verify Installation:

git --version

You should see the installed Git version.

Git Configuration
After installing Git, you should configure your user name and email address. These details will be associated with
your commits and are important for identifying who made which changes.

git config --global user.name "Your Name"


This command sets your name globally for all your Git repositories.

-global : This flag indicates that the configuration should apply to all repositories on your system. If you omit -

global , the configuration will only apply to the current repository.

"Your Name" : Replace this with your actual name.

Example:

git config --global user.name "Alice Smith"

git config --global user.email "your.email@example.com"


This command sets your email address globally for all your Git repositories.

-global : Applies the configuration globally.

: Replace this with your actual email address. It's common practice to use the same email
"your.email@example.com"

address you use for services like GitHub.

Example:

git config --global user.email "alice.smith@example.com"

You can verify your configuration by running:

Git & Github Notes 4


git config --list

Initializing a Git Repository


To start tracking changes in a project, you need to initialize a Git repository in your project directory.

git init
This command creates a new, empty Git repository in the current directory. It creates a hidden .git directory,
which contains all the necessary files for Git to track your project's history.
Steps:

1. Navigate to your project directory: Open your terminal or command prompt and use the cd command to
navigate to the root directory of your project.

cd /path/to/your/project

2. Initialize the repository:

git init

You will see a message like: Initialized empty Git repository in /path/to/your/project/.git/

Now, your project directory is a Git repository, and Git can start tracking its changes.

Checking Status
The git status command is one of the most frequently used Git commands. It shows you the state of your working
directory and the staging area.

git status
This command tells you:

Which files are untracked (new files that Git isn't yet monitoring).

Which files are modified but not yet staged for commit.

Which files are staged and ready to be committed.

Which branch you are currently on.

Example Output (initial state after git init and creating a file):
Let's say you create a file named index.html in your project directory.

git status

Output:

On branch master

No commits yet

Untracked files:
(use "git add <file>..." to include in what will be committed)
index.html

nothing added to commit but untracked files present (use "git add" to track)

This output indicates that index.html is a new file that Git hasn't started tracking yet.

Git & Github Notes 5


Staging and Committing Changes
The core workflow in Git involves staging changes and then committing them.

Staging Area (Index): This is an intermediate area where you prepare changes before committing them. You
can selectively add changes from different files to the staging area.

Commit: A commit is a snapshot of your repository at a specific point in time. It's a record of the changes
you've made, along with a message describing those changes.

git add <file>


This command adds changes from the specified file(s) to the staging area.

<file> : The name of the file you want to add to the staging area.

Examples:

Add a single file:

git add index.html

Add multiple specific files:

git add style.css script.js

Add all changes in the current directory (including new files and modifications):

git add .

Add all changes to tracked files (but not untracked new files):

git add -u

Example Output (after git add index.html ):

git status

Output:

On branch master

No commits yet

Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: index.html

Now, index.html is in the staging area, ready for the next commit.

git commit -m "message"


This command records the staged changes as a new commit in the repository's history.

: This flag allows you to provide a short, descriptive message for your commit directly on the
m "message"

command line. This message is crucial for understanding the purpose of the changes in the future.

Example:

Git & Github Notes 6


git commit -m "Initial commit: Add basic HTML structure"

Example Output (after git commit ):

[master (root-commit) b123456] Initial commit: Add basic HTML structure


1 file changed, 10 insertions(+)
create mode 100644 index.html

Now, your changes are permanently saved in the Git history as a commit. If you run git status again, it will show:

On branch master
nothing to commit, working tree clean

This indicates that all your changes have been committed, and your working directory matches the latest commit.

Module 3: Working with Git


This module delves into more advanced Git operations, including understanding the file lifecycle, viewing commit
history, undoing changes, and removing files.

File Lifecycle in Git


Understanding the lifecycle of a file in Git is crucial for effective version control. A file in your Git repository can be
in one of four main states:

1. Untracked: These are new files that Git has not yet seen or been told to manage. They are not part of your
repository's history. When you run git status , untracked files appear under "Untracked files."

Action: To move an untracked file to the "staged" state, you use git add <file> .

2. Unmodified: These files are unchanged since your last commit. They are identical to the version in your last
commit.

Action: If you modify an unmodified file, it moves to the "modified" state.

3. Modified: These files have been changed since your last commit, but the changes have not yet been added to
the staging area. When you run git status , modified files appear under "Changes not staged for commit."

Action: To move a modified file's changes to the "staged" state, you use git add <file> .

4. Staged (or Index): These files contain changes that have been marked to be included in the next commit.
When you run git status , staged files appear under "Changes to be committed."

Action: To record the staged changes permanently in the repository's history, you use git commit -m "message" .
After a commit, the file moves back to the "unmodified" state.

Here's a simplified flow:

Untracked -- (git add) --> Staged


Modified -- (git add) --> Staged
Staged -- (git commit) --> Unmodified
Unmodified -- (edit file) --> Modified

Viewing Commit History


Git keeps a detailed log of all commits, allowing you to review the project's history.

git log

Git & Github Notes 7


This command displays the commit history. By default, it shows commits in reverse chronological order (most
recent first), along with their commit hash, author, date, and commit message.

Common Options:

git log : Shows the full commit history.

git log --oneline : Shows each commit on a single line, displaying a shortened commit hash and the commit
message. Useful for a concise overview.

git log --oneline


# Example Output:
# a1b2c3d Initial commit: Add basic HTML structure
# e4f5g6h Add CSS styling

git log --graph --oneline --decorate : Shows a textual graphical representation of the commit history, especially useful
for visualizing branches and merges.

git log -p : Shows the patch (diff) introduced by each commit. This lets you see the exact changes (lines
added/removed) for each commit.

git log --author="Your Name" : Filters commits by a specific author.

git log --since="2 weeks ago" : Filters commits by date.

git log <filename> : Shows the commit history for a specific file.

Example:

git log

Output (example):

commit b123456789abcdef0123456789abcdef01234567
Author: Alice Smith <alice.smith@example.com>
Date: Wed Jul 10 09:00:00 2024 +0530

Initial commit: Add basic HTML structure

commit a987654321fedcba987654321fedcba987654321
Author: Alice Smith <alice.smith@example.com>
Date: Wed Jul 10 09:30:00 2024 +0530

Add navigation bar to index.html

git show <commit_hash>


This command shows the details of a specific commit, including its metadata (author, date, message) and the full
diff (changes) introduced by that commit.

: The full or partial (first few characters) hash of the commit you want to inspect. You can get this
<commit_hash>

hash from git log .

Example:

git show b123456

This would show you the changes made in the commit with the hash starting with b123456 .

Undoing Changes

Git & Github Notes 8


Git provides powerful tools to undo changes at various stages. This can be complex, so proceed with caution and
understand the implications of each command.

git restore <file> (or git checkout <file> )


This command is used to discard changes in your working directory. It essentially reverts a file to its last
committed or staged state.

: (Recommended modern command) Discards changes in the working directory for a specific file,
git restore <file>

reverting it to the state in the staging area or the last commit if not staged.

: Unstages a file, moving it from "Changes to be committed" back to "Changes not staged
git restore --staged <file>

for commit" (modified state). The working directory changes remain.

: (Older command, still widely used) Does the same as


git checkout -- <file> git restore <file> . The - is important to
distinguish the file from a branch name.

Use Cases:

You've made changes to index.html and want to discard them and revert to the last committed version:

git restore index.html


# or
git checkout -- index.html

You've git add ed style.css but then realized you don't want to commit those changes yet (you want to unstage
it):

git restore --staged style.css

Caution: git restore and git checkout -- <file> will overwrite your local changes, so make sure you don't need them
before running these commands.

git reset
The git reset command is more powerful and can be used to uncommit changes, move the HEAD pointer, and
modify the staging area. It's often used to "undo" commits.
Important Modes:

git reset --soft <commit_hash> :

Moves the HEAD pointer to the specified commit.

Keeps all changes in the staging area.

Keeps changes in the working directory.

Useful for combining multiple small commits into one larger commit before pushing.

git reset --mixed <commit_hash> (Default):

Moves the HEAD pointer to the specified commit.

Unstages all changes (moves them to the working directory).

Keeps changes in the working directory.

Useful for undoing a commit and then re-staging/re-committing with different changes.

git reset --hard <commit_hash> :

DANGEROUS! Moves the HEAD pointer to the specified commit.

Discards all changes in the staging area.

Discards all changes in the working directory.

Permanently deletes all uncommitted changes and reverts your project to the exact state of the
specified commit. Use with extreme caution, as you can lose work.

Use Cases:

Git & Github Notes 9


You just made a commit, but realized you forgot to include a file or made a typo in the message. You want to
"uncommit" it but keep the changes to re-commit:

git reset HEAD~1


# This is equivalent to `git reset --mixed HEAD~1`
# HEAD~1 refers to the commit directly before the current HEAD.

After this, your changes will be in the "modified" state, and you can git add and git commit again.

You want to completely wipe out all local changes and revert to a specific commit:

git reset --hard <commit_hash>

Caution: Avoid using git reset --hard on commits that have already been pushed to a shared remote repository, as it
can cause significant problems for collaborators.

Removing Files
Git provides a specific command for removing files from your repository while also removing them from your
working directory.

git rm <file>
This command removes a file from your working directory and stages the deletion for the next commit.

Use Cases:

You want to delete old_script.js from your project and record this deletion in Git:

git rm old_script.js

After running this, old_script.js will be deleted from your file system, and git status will show "deleted:
old_script.js" under "Changes to be committed". You then need to commit this change:

git commit -m "Remove old_script.js"

: This command removes the file from Git's tracking (staging area and future commits) but
git rm --cached <file>

keeps the file in your working directory. This is useful if you accidentally added a file that should not be
version-controlled (e.g., a large binary or a configuration file).

git rm --cached sensitive_data.txt

After this, sensitive_data.txt will remain in your directory but will no longer be tracked by Git. You might then add it
to your .gitignore file.

Important Note: If you simply delete a file using your operating system's file explorer ( rm file.txt or del file.txt ), Git will
detect it as a "deleted" file when you run git status . You would then need to git add <file> (or git add . ) to stage the
deletion, and then git commit it. Using git rm combines these steps.

Module 4: Branching and Merging


Branching and merging are core concepts in Git that enable developers to work on different features or bug fixes
in parallel without interfering with the main codebase.

What is a Branch?

Git & Github Notes 10


In Git, a branch is essentially a lightweight, movable pointer to one of your commits. When you create a new
branch, you are creating a new line of development. This allows you to:

Isolate Work: Develop new features or fix bugs in isolation from the main project.

Experiment: Try out new ideas without risking the stability of your main codebase.

Collaborate: Allow multiple developers to work on different parts of a project simultaneously.

By default, when you initialize a Git repository, you are on the master (or main in newer Git versions) branch. This is
typically considered the main, stable line of development.

Creating and Switching Branches


git branch <branch_name>
This command creates a new branch. It simply creates a new pointer to the current commit you are on, but it does
not switch you to that new branch.

<branch_name> : The name you want to give to your new branch.

Example:

# First, ensure you are on the branch you want to base your new branch off (e.g., master)
git checkout master

# Create a new branch called 'feature/add-login'


git branch feature/add-login

To see a list of all local branches and identify which one you're currently on, use:

git branch

Output (example):

feature/add-login
* master

The asterisk ( * ) indicates your current branch.

git checkout <branch_name>


This command is used to switch to an existing branch. When you switch branches, your working directory is
updated to reflect the files and history of the target branch.

<branch_name> : The name of the branch you want to switch to.

Example:

# Switch to the 'feature/add-login' branch


git checkout feature/add-login

Output:

Switched to branch 'feature/add-login'

Combined action (create and switch):


You can create a new branch and immediately switch to it using a shortcut:

git checkout -b <new_branch_name>

Git & Github Notes 11


This is equivalent to git branch <new_branch_name> followed by git checkout <new_branch_name> .

Example:

# Create and switch to a branch named 'bugfix/fix-header'


git checkout -b bugfix/fix-header

git switch <branch_name> (Modern Git)


The git switch command was introduced in Git 2.23 as a more intuitive and safer alternative to git checkout for
switching branches. It separates the concerns of switching branches from restoring files.

git switch <branch_name> : Switches to an existing branch.

git switch -c <new_branch_name> : Creates a new branch and switches to it.

Example:

# Switch to an existing branch


git switch feature/add-login

# Create a new branch and switch to it


git switch -c another-feature

It's generally recommended to use git switch for branch operations and git restore for file operations, as they provide
clearer intent.

Merging Branches
After working on a feature or bug fix in a separate branch, you'll eventually want to integrate those changes back
into another branch (often master or main ). This process is called merging.

git merge <source_branch>


This command integrates changes from the <source_branch> into your current branch.
Steps for merging:

1. Switch to the target branch: First, switch to the branch you want to merge changes into. This is typically your
master or main branch.

git checkout master

2. Perform the merge: Now, merge the changes from your feature branch into master .

git merge feature/add-login

Merge Scenarios:

Fast-Forward Merge: If the target branch (e.g., master ) has not had any new commits since the feature branch
was created, Git simply moves the master pointer forward to the tip of the feature branch. This is a "fast-
forward" merge, and no new merge commit is created.

# Example Output for Fast-Forward Merge:


Updating a1b2c3d..e4f5g6h
Fast-forward
src/login.js | 10 ++++++++++
1 file changed, 10 insertions(+)

Git & Github Notes 12


Three-Way Merge (Recursive Merge): If both the target branch and the feature branch have diverged (i.e.,
new commits have been made on the target branch since the feature branch was created), Git performs a
three-way merge. It finds a common ancestor of the two branches and then creates a new "merge commit"
that combines the changes from both branches.

# Example Output for Three-Way Merge:


Merge made by the 'recursive' strategy.
index.html | 2 +-
style.css | 5 +++--
2 files changed, 4 insertions(+), 3 deletions(-)

Git will open your configured text editor to allow you to write a commit message for the merge commit (it
provides a default message). Save and close the editor to complete the merge.

Resolving Merge Conflicts


Merge conflicts occur when Git cannot automatically reconcile changes between two branches that are being
merged. This typically happens when the same lines of code in the same file have been modified differently on
both branches.
When a conflict occurs, Git will stop the merge process and tell you which files have conflicts.
How to Resolve Merge Conflicts:

1. Identify Conflict Markers: Open the conflicted files in your text editor. Git inserts special "conflict markers" to
show you the conflicting sections:

<<<<<<< HEAD
This is the content from the current branch (where HEAD is pointing).
=======
This is the content from the branch you are merging from.
>>>>>>> feature/add-login

<<<<<<< HEAD : Marks the beginning of the conflicting change from your current branch.

======= : Separates the changes from the two branches.

>>>>>>> <branch_name> : Marks the end of the conflicting change from the incoming branch.

2. Manually Edit the File: Carefully review the conflicting sections. You need to decide which changes to keep,
combine, or discard. Delete the conflict markers ( <<<<<<< , ======= , >>>>>>> ) and edit the code to the desired
final state.
Example Resolution:
Original conflict:

<div class="header">
<h1>Welcome</h1>
<<<<<<< HEAD
<p>Your personal dashboard</p>
=======
<p>Login to your account</p>
>>>>>>> feature/add-login
</div>

Resolved (e.g., keeping both lines):

<div class="header">
<h1>Welcome</h1>
<p>Your personal dashboard</p>
<p>Login to your account</p>

Git & Github Notes 13


</div>

3. Stage the Resolved File: After editing and saving the file, you need to tell Git that you've resolved the conflict
for that file by adding it to the staging area:

git add <conflicted_file_name>

Repeat this for all conflicted files.

4. Commit the Merge: Once all conflicts are resolved and staged, complete the merge by creating a new
commit. Git will often pre-populate a merge commit message; you can accept it or modify it.

git commit -m "Merge branch 'feature/add-login' into master, resolved conflicts"

If you run git status during a conflict, it will guide you through the process, showing "Unmerged paths" and
instructions.

Deleting Branches
Once a feature branch has been merged into its target branch and is no longer needed, you can delete it to keep
your repository clean.

git branch -d <branch_name>


This command deletes the specified branch locally. It's a "safe" delete because Git will only allow you to delete
the branch if it has been fully merged into its upstream branch (or the current branch if no upstream is set).

d : Short for -delete .

Example:

# Ensure you are not on the branch you want to delete


git checkout master

# Delete the 'feature/add-login' branch


git branch -d feature/add-login

Output:

Deleted branch feature/add-login (was a1b2c3d).

git branch -D <branch_name>


This command is used for a "force" delete. It deletes the branch regardless of whether it has been merged or not.
Use this with caution, as you can lose unmerged work.

D : Short for -delete --force .

Example:

# Force delete the 'experimental-feature' branch (even if not merged)


git branch -D experimental-feature

Remember that deleting a local branch does not delete it from any remote repositories (like GitHub). You would
need to push the deletion to the remote as well ( git push origin --delete <branch_name> ).

Git & Github Notes 14


Module 5: GitHub Basics
This module introduces GitHub, a popular platform for hosting Git repositories, and covers the essential Git
commands for interacting with remote repositories.

What is GitHub?
GitHub is a web-based platform that provides hosting for software development and version control using Git. It's
more than just a place to store your code; it's a powerful collaboration platform that offers:

Remote Repository Hosting: A central place to store your Git repositories, making them accessible to others
and providing a backup.

Collaboration Tools: Features like pull requests, issue tracking, project management boards, and wikis that
facilitate team collaboration.

Code Review: Streamlined processes for reviewing code changes before they are merged.

Open Source Community: The largest open-source community in the world, allowing developers to discover,
contribute to, and learn from millions of projects.

Continuous Integration/Deployment (CI/CD): Integration with various CI/CD tools (including GitHub Actions)
to automate testing and deployment.

While Git is the version control system, GitHub is a service that uses Git to host and manage projects.

Creating a GitHub Account


1. Go to GitHub: Open your web browser and navigate to github.com.

2. Sign Up: Click on the "Sign up" button (usually in the top right corner).

3. Enter Details: Follow the prompts to enter your email address, create a password, and choose a username.

4. Verify Account: GitHub will send a verification email to the address you provided. Click the verification link in
the email.

5. Personalize (Optional): You might be asked a few questions about your experience and how you plan to use
GitHub. You can answer these or skip them.

Once your account is created, you'll have access to your GitHub dashboard.

Creating a Repository on GitHub


A repository (often shortened to "repo") on GitHub is where your project's files and their entire revision history
are stored.

1. Sign in to GitHub: Go to github.com and sign in to your account.

2. New Repository:

On your GitHub dashboard, look for the "New" button (often a green button with a plus icon) in the left
sidebar under "Repositories" or in the top right corner of the page. Click it.

3. Repository Name:

Enter a Repository name (e.g., my-first-website , my-project ). Choose a short, memorable name.

4. Description (Optional):

Add a brief Description of your project.

5. Public or Private:

Choose if your repository should be Public (anyone can see it) or Private (only you and people you
explicitly share with can see it). For personal projects or learning, Public is often fine.

6. Initialize with a README (Optional but Recommended):

Check the "Add a README file" box. A README file is a plain text file that provides basic information about
your project.

7. Add .gitignore (Optional but Recommended):

Git & Github Notes 15


Select a .gitignore template if your project is for a specific language (e.g., "Node", "Python", "Java"). This
file tells Git which files or directories to ignore (e.g., temporary files, build artifacts, sensitive data).

8. Choose a License (Optional):

Select a software license if you plan to share your code.

9. Create Repository: Click the "Create repository" button.

Your new repository will now be created on GitHub, and you'll be redirected to its page.

Cloning Repositories
Cloning is the process of creating a local copy of a remote Git repository. When you clone a repository, you
download its entire history, including all branches and commits.

git clone <repository_url>


This command downloads a remote repository to your local machine.

: The URL of the Git repository you want to clone. You can find this on the GitHub repository page
<repository_url>

by clicking the "Code" button (usually green) and copying the HTTPS or SSH URL.

Steps:

1. Navigate to your desired directory: Open your terminal or command prompt and cd into the directory where
you want to store your local copy of the repository.

cd /path/to/your/development/folder

2. Clone the repository: Copy the HTTPS URL from your GitHub repository (e.g., https://github.com/your-username/your-

repo.git ).

git clone https://github.com/your-username/your-repo.git

This will create a new directory named your-repo (or whatever the repository name is) in your current location,
containing all the files and the .git history.

Connecting Local Repo to GitHub


If you've already initialized a local Git repository ( git init ) and now want to connect it to an empty repository you've
created on GitHub, you need to tell your local repository where the remote GitHub repository is located.

git remote add origin <repository_url>


This command adds a new remote repository to your local Git configuration.

origin : This is a conventional name given to the primary remote repository. You could name it something else,
but origin is the standard.

<repository_url> : The HTTPS or SSH URL of your empty GitHub repository.

Steps:

1. Navigate to your local repository:

cd /path/to/your/local/project

2. Add the remote:

git remote add origin https://github.com/your-username/your-repo.git

You can verify that the remote was added by running git remote -v .

git push -u origin main (or git push -u origin master )

Git & Github Notes 16


This command pushes your local commits to the remote repository for the first time and sets up the upstream
tracking.

git push : Pushes your local changes to the remote.

u : Short for -set-upstream . This flag tells Git to remember that your local main (or master ) branch is associated
with the main (or master ) branch on the origin remote. After this, you can simply use git push and git pull without
specifying origin main .

origin : The name of your remote repository (as defined with git remote add ).

main (or master ): The name of the local branch you want to push, and the name of the remote branch you want
to push to. Newer Git versions default to main , older ones to master . Check your local branch name with git
branch .

Example:

git push -u origin main

This will push all your local commits from your main branch to the main branch on GitHub.

Pushing and Pulling


These are the fundamental commands for synchronizing your local repository with a remote repository.

git push
This command uploads your local commits to the remote repository. You use this after you've made new commits
locally and want to share them with others or back them up on GitHub.

If you've already used git push -u origin main (or master ), you can simply use:

git push

If you haven't set up upstream tracking, or if you want to push a specific branch, you would use:

git push origin <branch_name>

Example:

# After making new commits on your 'main' branch


git push

git pull
This command downloads changes from the remote repository and automatically merges them into your current
local branch. It's a combination of git fetch and git merge . You use this to get the latest changes that others have
pushed to the remote.
Example:

# To get the latest changes from the remote 'main' branch


git pull origin main
# Or, if upstream tracking is set up
git pull

git fetch
This command downloads changes from the remote repository but does not automatically merge them into your
local branch. It updates your local copy of the remote's branches (e.g., origin/main ), allowing you to inspect
changes before merging them.

Git & Github Notes 17


Use Cases:

You want to see what changes have occurred on the remote without immediately integrating them into your
working directory.

You want to review changes from a remote branch before deciding to merge them.

Example:

git fetch origin

After git fetch , you can compare your local branch with the remote tracking branch (e.g., git diff main origin/main ) or
merge manually ( git merge origin/main ).

Module 6: Collaboration with GitHub


GitHub is designed for collaboration. This module explores how developers work together on projects using
GitHub's powerful features.

Forking Repositories
Forking is a fundamental concept in GitHub collaboration, especially in the open-source world. When you "fork" a
repository, you create a personal copy of that repository on your GitHub account.

Why Fork?

Contribution without Direct Access: It allows you to contribute to a project without needing write access
to the original (upstream) repository. You make changes in your fork, and then propose those changes
back to the original.

Personal Experimentation: You can experiment with a project without affecting the original codebase.

Independent Development: You can use a fork as a starting point for your own project, even if you don't
intend to contribute back to the original.

How to Fork:

1. Go to the GitHub page of the repository you want to fork.

2. In the top right corner of the page, click the "Fork" button.

3. GitHub will create a copy of the repository under your account.

Workflow with Forks:

1. Fork the upstream repository to your GitHub account.

2. Clone your forked repository to your local machine: git clone https://github.com/your-username/forked-repo.git

3. Add the original repository as an "upstream" remote: This allows you to fetch changes from the original
project to keep your fork up-to-date.

cd forked-repo
git remote add upstream https://github.com/original-owner/original-repo.git

4. Make changes in your local fork, commit them, and push to your fork: git push origin your-feature-branch

5. Create a Pull Request from your fork to the original repository.

Pull Requests
A Pull Request (PR) is the heart of collaboration on GitHub. It's a mechanism for you to propose changes from one
branch (often a feature branch in your fork) to another branch (often the main / master branch in the original
repository).

What a Pull Request Does:

Proposes Changes: It formally proposes a set of changes.

Git & Github Notes 18


Facilitates Code Review: It provides a dedicated space for discussion and code review. Reviewers can
comment on specific lines of code, suggest improvements, or ask questions.

Tracks Progress: It acts as a record of the proposed changes, their discussion, and their eventual
integration.

Triggers CI/CD: PRs can automatically trigger automated tests and checks (e.g., via GitHub Actions) to
ensure code quality.

How to Create a Pull Request:

1. Push your changes to a branch in your forked repository (or directly to a branch in the original repo if you
have write access).

2. Go to your forked repository on GitHub.

3. GitHub will often show a prominent "Compare & pull request" button if it detects new pushes. Click it.

4. Alternatively, navigate to the "Pull requests" tab and click "New pull request."

5. Select the base and compare branches:

Base repository/branch: This is the repository and branch you want your changes to go into (e.g.,
original-owner/original-repo 's main branch).

Head repository/branch: This is your repository and branch that contains the changes you want to
propose (e.g., your-username/forked-repo 's your-feature-branch ).

6. Add a title and description: Provide a clear, concise title and a detailed description of your changes, why
they were made, and any relevant context.

7. Create pull request: Click the "Create pull request" button.

Code Review Process


Once a Pull Request is opened, the Code Review Process begins. This is where other developers (often
maintainers of the original repository) examine your proposed changes.

Steps in Code Review:

1. Discussion: Reviewers and the PR author discuss the proposed changes. This can involve questions,
clarifications, and suggestions for improvement.

2. Comments: Reviewers can add comments directly to specific lines of code or general comments on the
PR.

3. Suggestions: Reviewers can suggest specific code changes directly within the PR interface, which the
author can apply with a single click.

4. Automated Checks: GitHub Actions or other CI/CD tools may run automated tests, linting, and other
checks. The results are displayed on the PR.

5. Approval/Changes Requested: Reviewers can approve the PR (signifying it's ready to merge) or request
changes.

6. Iteration: The PR author makes requested changes, pushes new commits to the same branch, and the
review process continues until the PR is approved.

7. Merge: Once approved and all checks pass, the PR can be merged into the base branch.

Best Practices for Code Review:

Keep PRs small: Smaller PRs are easier and faster to review.

Clear descriptions: Provide thorough explanations of your changes.

Respond promptly: Address comments and questions from reviewers in a timely manner.

Be constructive: Reviewers should provide helpful and actionable feedback.

GitHub Issues and Projects


GitHub provides tools for tracking work, bugs, and features.

GitHub Issues

Git & Github Notes 19


Issues are a way to track tasks, enhancements, bugs, or any other work that needs to be done on a project. They
serve as a central place for discussions and decisions related to specific items of work.

Key Features of Issues:

Description: A detailed description of the issue.

Comments: A thread for discussion among collaborators.

Labels: Categorize issues (e.g., bug , enhancement , documentation , help wanted ).

Assignees: Assign issues to specific team members.

Milestones: Group issues into larger goals or release cycles.

Linked Pull Requests: Issues can be linked to PRs, so you can see which code changes address a specific
issue.

How to Use Issues:

1. Go to the "Issues" tab in your repository.

2. Click "New issue."

3. Provide a clear title and detailed description.

4. Add labels, assignees, and milestones as needed.

GitHub Projects (Projects Beta)


GitHub Projects (formerly "Projects" or "Project Boards") are flexible, spreadsheet-like boards that help you
organize and track your work. They are highly customizable and can be used for agile workflows (Kanban, Scrum)
or simple task management.

Key Features of Projects:

Custom Fields: Define custom fields to track additional data (e.g., priority, status, estimated effort).

Views: Create different views (table, board, roadmap) to visualize your work in various ways.

Filtering and Grouping: Filter and group items based on fields.

Automations: Automate common tasks, like moving issues to a "Done" column when a linked PR is
merged.

Items: Projects can include issues, pull requests, and draft issues (simple notes).

How to Use Projects:

1. Go to the "Projects" tab in your repository or organization.

2. Click "New project."

3. Choose a template or start from scratch.

4. Add issues, pull requests, or draft issues to your project.

5. Organize items into custom fields and views.

GitHub Actions (Basic CI/CD Intro)


GitHub Actions is a powerful, built-in CI/CD (Continuous Integration/Continuous Deployment) platform that allows
you to automate workflows directly within your GitHub repository.

What is CI/CD?

Continuous Integration (CI): The practice of frequently merging code changes into a central repository. CI
pipelines automatically build and test the code every time changes are pushed, helping to catch
integration issues early.

Continuous Deployment (CD): The practice of automatically deploying code changes to production (or
staging) environments after they pass CI tests.

How GitHub Actions Work:

Workflows are defined in YAML files ( .github/workflows/your-workflow.yml ) in your repository.

A workflow consists of one or more jobs.

Git & Github Notes 20


Each job consists of a series of steps.

Steps can run commands, use actions (reusable pieces of code from the GitHub Marketplace), or run
scripts.

Workflows are triggered by events (e.g., push to a branch, pull_request opened, issue_comment created,
schedule ).

Common Use Cases for GitHub Actions:

Automated Testing: Run unit tests, integration tests, and end-to-end tests on every push or pull request.

Code Linting/Formatting: Automatically check code style and formatting.

Build Automation: Compile code, build Docker images, or create deployable artifacts.

Deployment: Automatically deploy applications to cloud providers (AWS, Azure, GCP) or other hosting
services.

Notifications: Send notifications to Slack, email, etc., on workflow status.

Static Site Generation: Build and deploy static websites (e.g., using Jekyll, Hugo, Next.js).

Basic Workflow Example ( .github/workflows/ci.yml ):

name: CI Pipeline

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
build-and-test:
runs-on: ubuntu-latest # The type of machine to run the job on

steps:
- name: Checkout code
uses: actions/checkout@v4 # Action to checkout your repository code

- name: Set up Node.js


uses: actions/setup-node@v4
with:
node-version: '20' # Specify the Node.js version

- name: Install dependencies


run: npm install # Command to install project dependencies

- name: Run tests


run: npm test # Command to run your project's tests

This simple workflow will run whenever code is pushed to main or a pull request is opened targeting main . It
checks out the code, sets up Node.js, installs dependencies, and runs tests.

Module 7: Advanced Git


This module delves into more advanced Git concepts and commands that can help streamline your workflow and
handle more complex scenarios.

Git Stash

Git & Github Notes 21


The git stash command is incredibly useful when you're in the middle of working on something, but you need to
switch branches or pull in urgent changes without committing your current, unfinished work. It temporarily
shelves (or stashes) changes you've made to your working directory that you don't want to commit yet.

How it works:

It records the current state of your working directory and index (staging area) but then reverts your
working directory to match the HEAD commit.

This allows you to switch branches, pull, or perform other Git operations without committing incomplete
work.

Your stashed changes are stored in a stack and can be reapplied later.

Common Commands:

git stash save "message" (or git stash ): Stashes your current changes with an optional message. If no message is
provided, Git creates a default message.

# Stash changes with a message


git stash save "WIP: started new feature"

# Simple stash (no message)


git stash

git stash list : Shows a list of all stashes you've created.

git stash list


# Example Output:
# stash@{0}: On main: WIP: started new feature
# stash@{1}: On dev: temporary bugfix

: Applies the stashed changes back to your working directory. By default, it applies
git stash apply [stash@{n}]

the most recent stash ( stash@{0} ). The stash remains in the stash list.

# Apply the most recent stash


git stash apply

# Apply a specific stash


git stash apply stash@{1}

git stash pop [stash@{n}] : Applies the stashed changes and then immediately drops (removes) it from the stash
list. This is often preferred if you're sure you won't need the stash again.

# Apply and drop the most recent stash


git stash pop

git stash drop [stash@{n}] : Deletes a specific stash from the list without applying it.

# Drop the most recent stash


git stash drop

# Drop a specific stash


git stash drop stash@{1}

git stash clear : Removes all stashes from the list.

Rebase vs Merge

Git & Github Notes 22


Both git rebase and git merge are used to integrate changes from one branch into another. However, they do so in
fundamentally different ways, leading to different commit histories.

git merge
How it works: git merge combines the changes from two branches by creating a new merge commit. This
merge commit has two parent commits, one from each of the merged branches.

Commit History: It preserves the exact history of both branches, showing exactly when and where the merge
occurred. The history is non-linear, as it shows parallel development.

When to use:

When you want to preserve the complete, accurate history of your project, including all merges and
parallel development.

When working on public or shared branches (e.g., main / master ), as rebasing shared history can cause
issues for collaborators.

Example:

# Assume you are on 'main' and want to merge 'feature-branch'


git checkout main
git merge feature-branch

git rebase
How it works: git rebase moves or "replays" a series of commits from one branch onto another. Instead of
creating a merge commit, it rewrites the commit history of the feature branch to appear as if development
happened directly on top of the target branch.

Commit History: It creates a linear history, making it look like all development happened sequentially. The
original commits on the feature branch are effectively discarded and new commits with different hashes are
created.

When to use:

When you want a clean, linear commit history, especially for personal feature branches before merging
them into a shared branch.

To incorporate upstream changes into your feature branch without creating unnecessary merge commits.

For "cleaning up" your commits (e.g., squashing multiple small commits into one) using git rebase -i

(interactive rebase).

Example:

# Assume you are on 'feature-branch' and want to rebase onto 'main'


git checkout feature-branch
git rebase main

This command takes all the commits on feature-branch that are not on main , and reapplies them one by one onto the
tip of main .
Key Difference Summary:

Feature git merge git rebase

Commit History Non-linear, preserves merge points Linear, rewrites history of rebased branch

Merge Commit Creates a new merge commit Does not create a merge commit (unless conflicts)

Safety Safer for shared/public branches Can be dangerous on shared branches (rewrites history)

Clarity Shows actual development history (parallel work) Creates a cleaner, sequential-looking history

Rule of Thumb:

Never rebase commits that have been pushed to a public/shared repository.

Rebase your private feature branches onto main / master to keep your history clean before merging.

Git & Github Notes 23


Merge main / master into your feature branches if you want to preserve history or if you're not comfortable with
rebasing.

Cherry Pick
The git cherry-pick command allows you to pick a specific commit from one branch and apply it to another branch.
This is useful when you only need a few specific changes from a branch, rather than merging the entire branch.

How it works: It takes the changes introduced by a single commit and creates a new commit with those same
changes on your current branch. The new commit will have a different hash than the original.

When to use:

To backport a bug fix from a development branch to a release branch.

To apply a specific feature from one branch to another without bringing over all other commits.

To fix a mistake that was committed to the wrong branch.

Example:

1. Find the commit hash you want to cherry-pick (e.g., using git log --oneline ). Let's say the commit hash is abcdef1 .

2. Switch to the branch where you want to apply the commit:

git checkout release-branch

3. Cherry-pick the commit:

git cherry-pick abcdef1

If there are conflicts, resolve them, git add the resolved files, and then git cherry-pick --continue .

Git Tags
Git tags are pointers to specific points in your repository's history. They are typically used to mark release points
(e.g., v1.0 , v2.0-beta ). Unlike branches, tags are fixed and do not move.

Types of Tags:

Lightweight Tags: Simple pointers to a commit, like a branch that never moves. They are just a name and
a commit hash.

Annotated Tags: Full objects in the Git database. They contain the tagger's name, email, and date, and
can have a tagging message. They are also signed with GPG for verification. Annotated tags are generally
recommended for releases.

Common Commands:

git tag : Lists all existing tags.

git tag
# Example Output:
# v1.0
# v1.1-beta

git tag -a <tag_name> -m "message" : Creates an annotated tag.

git tag -a v1.0 -m "Release version 1.0"

git tag <tag_name> : Creates a lightweight tag.

git tag v1.0-lw

Git & Github Notes 24


git show <tag_name> : Shows information about a specific tag.

git show v1.0

git push origin <tag_name> : Pushes a specific tag to the remote repository. Tags are not pushed by default with
git push .

git push origin v1.0

git push origin --tags : Pushes all local tags to the remote repository.

git tag -d <tag_name> : Deletes a local tag.

git tag -d v1.0-lw

git push origin --delete <tag_name> : Deletes a tag from the remote repository.

git push origin --delete v1.0

Working with .gitignore


The .gitignore file is a plain text file that tells Git which files or directories to ignore when tracking changes in your
repository. This is crucial for keeping your repository clean and avoiding committing unnecessary or sensitive
files.

Why use .gitignore ?

Avoid committing temporary files: (e.g., .DS_Store on macOS, Thumbs.db on Windows).

Exclude build artifacts: (e.g., build/ , dist/ , target/ directories).

Ignore dependency directories: (e.g., node_modules/ , vendor/ ).

Prevent committing sensitive information: (e.g., API keys, configuration files with credentials).

Ignore IDE-specific files: (e.g., .idea/ , .vscode/ ).

How to create and use .gitignore :

1. Create a file named .gitignore in the root directory of your Git repository.

2. Add patterns to the file, one per line, specifying what to ignore.

.gitignore Patterns:

Blank lines: Ignored.

Lines starting with # : Comments.

file.txt : Ignores file.txt in the same directory as .gitignore or any subdirectory.

/file.txt : Ignores file.txt only in the same directory as .gitignore .

folder/ : Ignores the folder directory and all its contents anywhere in the repository.

.log : Ignores all files ending with .log .

!important.log : Negates a previous ignore rule. If .log is ignored, but important.log should be tracked, use this.

foo/**/bar : Matches bar in foo/bar , foo/a/bar , foo/a/b/bar , etc. (double asterisk for matching zero or more
directories).

Example .gitignore file:

Git & Github Notes 25


# Ignore compiled output directories
/build/
/dist/
/target/

# Ignore node_modules for Node.js projects


node_modules/

# Ignore log files


*.log
npm-debug.log*

# Ignore macOS specific files


.DS_Store

# Ignore Windows specific files


Thumbs.db

# Ignore sensitive configuration files


config.js
.env

# Ignore IDE specific files


.idea/
.vscode/

# Keep a specific file within an ignored directory


!/build/important_asset.js

Important: If a file is already tracked by Git (i.e., it's already in a commit), adding it to .gitignore will not stop Git
from tracking it. You need to untrack it first:

git rm --cached <file_name>


git add .gitignore
git commit -m "Untrack file and add to .gitignore"

Module 8: Real-World Workflow


This module explores common Git workflows used in professional development environments, focusing on how
teams collaborate effectively and manage releases.

Git Flow vs GitHub Flow


Two popular branching models guide how teams use Git for collaboration: Git Flow and GitHub Flow. Both aim to
streamline development, but they differ significantly in their complexity and approach.

Git Flow
Git Flow is a more complex, highly structured branching model introduced by Vincent Driessen. It defines a strict
set of rules for branching and merging, making it suitable for projects with scheduled release cycles and hotfixes.

Key Branches:

master (or main ): Always reflects production-ready code.

develop : Integrates all the completed feature branches and serves as the main development branch.

Git & Github Notes 26


feature/* : Branches created off develop for developing new features.

release/* : Branches created off develop to prepare for a new production release (bug fixes, final touches).

hotfix/* : Branches created off master to quickly fix critical bugs in production.

Workflow Summary:

1. develop branch is created from master .

2. feature branches are created from develop .

3. Features are merged back into develop .

4. When a release is planned, a release branch is created from develop .

5. Bug fixes and final changes are made on the release branch.

6. The release branch is merged into both master (tagged with the version number) and develop .

7. If a critical bug is found in production, a hotfix branch is created from master .

8. The hotfix is merged into both master (tagged) and develop .

Pros:

Clear separation of concerns for different types of development (features, releases, hotfixes).

Well-suited for projects with distinct release cycles.

Provides a structured approach for large teams.

Cons:

Can be overly complex for smaller teams or projects with continuous delivery.

Requires more branch management.

Can lead to longer-lived branches and potential merge conflicts.

GitHub Flow
GitHub Flow is a simpler, lightweight, and continuous delivery-oriented branching model. It's designed for
projects that deploy frequently and prioritize simplicity.

Key Branches:

master (or main ): The only long-lived branch, always deployable.

feature/* (or any descriptive branch name): Short-lived branches created off master for any new work
(features, bug fixes, experiments).

Workflow Summary:

1. Create a new, descriptive branch from master for any new work.

2. Commit changes to this branch regularly.

3. Open a Pull Request (PR) when you need feedback or think the work is ready to merge.

4. Review the code, run automated tests, and discuss changes in the PR.

5. Deploy the branch to a staging environment for testing.

6. Merge the branch into master only after it's been reviewed, tested, and is ready for production.

7. Immediately deploy master to production.

Pros:

Simple and easy to understand.

Promotes continuous integration and continuous delivery.

Fewer long-lived branches, reducing merge complexities.

Ideal for web applications and projects with rapid deployment cycles.

Cons:

Might be too simplistic for projects with very strict release schedules or complex versioning requirements.

Relies heavily on automated testing and deployment.

Git & Github Notes 27


Choosing a Flow:
Git Flow: Choose if you have distinct release cycles, need strict versioning, and manage complex projects
with multiple teams.

GitHub Flow: Choose if you prioritize continuous delivery, have a smaller team, or work on web applications
that deploy frequently.

Feature Branch Workflow


The Feature Branch Workflow is a core component of both Git Flow and GitHub Flow, emphasizing isolated
development for new features or bug fixes.

Concept: All new development (features, bug fixes, experiments) should occur in dedicated branches rather
than directly on the master or develop branch.

Steps:

1. Create a new branch: From your main development branch ( master or develop ), create a new branch for
your feature. Use a descriptive name (e.g., feature/user-profile , bugfix/login-issue ).

git checkout master # or develop


git checkout -b feature/new-feature-name

2. Develop and Commit: Work on your feature, making regular, small, and descriptive commits to your
feature branch.

# Make changes to files


git add .
git commit -m "Implement part of new feature X"

3. Push to Remote (Optional, but recommended for collaboration): Regularly push your feature branch to
the remote repository.

git push origin feature/new-feature-name

4. Keep up-to-date (Optional, but recommended): Periodically pull or rebase changes from the main
development branch into your feature branch to avoid large merge conflicts later.

git checkout feature/new-feature-name


git pull origin master # or git rebase master

5. Open a Pull Request: Once the feature is complete and tested locally, open a Pull Request to merge your
feature branch back into the main development branch.

6. Code Review and Merge: Participate in code review, address feedback, and once approved, merge the
feature branch.

7. Delete the feature branch: After merging, delete the local and remote feature branch to keep the
repository clean.

git branch -d feature/new-feature-name


git push origin --delete feature/new-feature-name

Benefits:

Isolation: Prevents unstable code from affecting the main codebase.

Collaboration: Multiple developers can work on different features simultaneously.

Code Review: Provides a natural point for code review before integration.

Git & Github Notes 28


Experimentation: Allows for trying out ideas without impacting stable code.

Release Management
Release management in Git refers to the process of preparing, stabilizing, and deploying new versions of your
software. The approach varies depending on your chosen Git workflow.

With Git Flow:

A dedicated release branch is created from develop .

Only bug fixes and minor changes directly related to the release are allowed on this branch.

Once stable, the release branch is merged into master (and tagged) and back into develop .

This provides a clear "hardening" period for releases.

With GitHub Flow:

There is no dedicated release branch.

The master branch is always considered deployable.

New features are merged into master as soon as they are ready and tested.

Deployment typically happens directly from master .

Versioning (e.g., v1.0.0 ) is usually handled by creating Git tags on master at the point of deployment.

Common Release Practices (regardless of flow):

Semantic Versioning: Use MAJOR.MINOR.PATCH (e.g., 1.2.3 ) to indicate changes.

MAJOR : Breaking changes.

MINOR : New features (backward compatible).

PATCH : Bug fixes (backward compatible).

Git Tags: Always tag the commit that represents a release in master (or main ).

git tag -a v1.0.0 -m "Release version 1.0.0"


git push origin v1.0.0

Release Notes/Changelog: Document the changes, new features, and bug fixes included in each release.
This can be generated from commit messages or manually curated.

Automated Testing: Ensure robust CI/CD pipelines run all necessary tests before a release.

Hotfixes
Hotfixes are urgent bug fixes applied directly to production code to resolve critical issues without waiting for the
next planned release cycle.

With Git Flow:

A hotfix branch is created directly from master .

The fix is implemented and committed to this branch.

The hotfix branch is then merged into both master (and tagged) and develop . This ensures the fix is in
production and also integrated into the ongoing development.

# On master
git checkout master
git checkout -b hotfix/critical-bug-fix

# Implement fix, commit


git add .
git commit -m "Hotfix: Fix critical login error"

# Merge into master and tag


git checkout master

Git & Github Notes 29


git merge hotfix/critical-bug-fix
git tag -a v1.0.1 -m "Hotfix release v1.0.1"
git push origin master v1.0.1

# Merge into develop


git checkout develop
git merge hotfix/critical-bug-fix
git push origin develop

# Delete hotfix branch


git branch -d hotfix/critical-bug-fix
git push origin --delete hotfix/critical-bug-fix

With GitHub Flow:

A new branch is created directly from master for the hotfix.

The fix is implemented, committed, and a Pull Request is opened.

After review and automated tests, the hotfix branch is merged into master and immediately deployed.

Since master is always deployable, a hotfix is essentially just a high-priority feature branch.

# On master
git checkout master
git checkout -b hotfix/critical-bug-fix

# Implement fix, commit, push


git add .
git commit -m "Hotfix: Fix critical login error"
git push origin hotfix/critical-bug-fix

# Open PR on GitHub, get it reviewed, merge into main, and deploy


# Delete branch after merge
git branch -d hotfix/critical-bug-fix
git push origin --delete hotfix/critical-bug-fix

Key Principles for Hotfixes:

Speed: Prioritize getting the fix to production quickly.

Minimal Changes: Only include the necessary changes for the fix.

Testing: Even for hotfixes, adequate testing is crucial.

Integration: Ensure the fix is integrated back into all relevant development branches.

Module 9: Security and Best Practices


This module focuses on important security considerations and best practices for using Git and GitHub effectively
and securely.

Using SSH with GitHub


When interacting with remote Git repositories like GitHub, you can use either HTTPS or SSH. While HTTPS is
simpler to set up initially (using your GitHub username and password or a personal access token), SSH offers a
more secure and convenient way to authenticate.

What is SSH?
SSH (Secure Shell) is a cryptographic network protocol for secure data communication. In the context of Git, it
provides a secure channel over an unsecured network by using public-key cryptography.

Git & Github Notes 30


How SSH works with GitHub:

1. You generate an SSH key pair on your local machine: a private key (kept secret on your computer) and a
public key (which you upload to GitHub).

2. When you connect to GitHub using SSH, your local machine uses your private key to prove your identity.

3. GitHub uses your public key to verify that you are who you claim to be.

4. This eliminates the need to enter your username and password (or personal access token) every time you
interact with the remote repository.

Benefits of SSH:

Security: More secure than password-based authentication, especially against brute-force attacks.

Convenience: No need to type credentials repeatedly.

Automation: Easier to use in scripts and automated workflows.

Steps to Set Up SSH:

1. Check for existing SSH keys:

ls -al ~/.ssh

Look for files like id_rsa.pub or id_ed25519.pub .

2. Generate a new SSH key (if needed):

ssh-keygen -t ed25519 -C "your_email@example.com"


# Or for older systems: ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

Follow the prompts (you can press Enter for default location and no passphrase, though a passphrase
adds an extra layer of security).

3. Start the SSH agent and add your private key:

eval "$(ssh-agent -s)"


ssh-add ~/.ssh/id_ed25519 # Or id_rsa

4. Copy your public key:

cat ~/.ssh/id_ed25519.pub # Or id_rsa.pub

Copy the entire output, starting with ssh-ed25519 (or ssh-rsa ) and ending with your email.

5. Add the SSH key to your GitHub account:

Go to GitHub.com, click your profile photo, then "Settings".

In the sidebar, click "SSH and GPG keys".

Click "New SSH key" or "Add SSH key".

Give it a descriptive title (e.g., "My Laptop").

Paste your copied public key into the "Key" field.

Click "Add SSH key".

6. Test your SSH connection:

ssh -T git@github.com

You should see a message like: Hi <your-username>! You've successfully authenticated, but GitHub does not provide shell access.

Git & Github Notes 31


7. Update your remote URL (if cloning via HTTPS):
If you previously cloned a repository using HTTPS, you'll need to change its remote URL to use SSH.

cd /path/to/your/repo
git remote set-url origin git@github.com:your-username/your-repo.git

Commit Signing
Commit signing allows you to cryptographically sign your Git commits and tags, ensuring their authenticity and
integrity. This verifies that the commit was indeed created by you and that its content hasn't been tampered with
since it was signed.

Why Sign Commits?

Verification: Others can verify that a commit truly came from you.

Trust: Increases trust in open-source projects or collaborative environments.

Integrity: Detects if a commit's content or metadata has been altered.

Compliance: Some organizations or projects may require signed commits for auditing or security policies.

How it works:
You use a GPG (GNU Privacy Guard) key to sign your commits. Your public GPG key is then uploaded to
GitHub (similar to SSH keys). When you push a signed commit, GitHub verifies the signature against your
public key.

Steps to Set Up Commit Signing (using GPG):

1. Install GPG:

macOS: brew install gpg

Linux (Debian/Ubuntu): sudo apt install gnupg

Windows: Download Gpg4win from gpg4win.org.

2. Generate a GPG key:

gpg --full-generate-key

Follow the prompts (choose RSA and RSA , default key size 3072 or 4096 , set an expiration, and provide your
real name and email address that matches your Git config). Remember your passphrase!

3. List your GPG keys and get your GPG key ID:

gpg --list-secret-keys --keyid-format LONG

Look for a line like sec rsa3072/0xYOURGPGKEYID 2024-07-10 [SC] and copy the 0xYOURGPGKEYID part.

4. Configure Git to use your GPG key:

git config --global user.signingkey 0xYOURGPGKEYID

5. Tell Git to sign all commits by default (optional but recommended):

git config --global commit.gpgsign true

Alternatively, sign individual commits with git commit -S -m "Your message" .

6. Export your GPG public key:

Git & Github Notes 32


gpg --armor --export 0xYOURGPGKEYID

Copy the entire output, including -----BEGIN PGP PUBLIC KEY BLOCK----- and -----END PGP PUBLIC KEY BLOCK----- .

7. Add your GPG key to GitHub:

Go to GitHub.com, click your profile photo, then "Settings".

In the sidebar, click "SSH and GPG keys".

Click "New GPG key" or "Add GPG key".

Paste your copied public GPG key into the "Key" field.

Click "Add GPG key".

8. Make a signed commit:

git add .
git commit -m "My first signed commit" # If commit.gpgsign is true
# Or: git commit -S -m "My first signed commit"

You will be prompted for your GPG passphrase.

9. Push your commit:

git push

On GitHub, you should now see a "Verified" badge next to your signed commit.

Writing Good Commit Messages


Good commit messages are crucial for understanding project history, debugging, and collaborating effectively.
They serve as a concise record of why a change was made, not just what was changed.

Key Principles for Good Commit Messages:

1. Subject Line (First Line):

Concise: Keep it under 50-72 characters.

Imperative Mood: Use the imperative mood ("Add feature," not "Added feature" or "Adds feature").

Capitalize First Letter:

No Period: Do not end with a period.

Prefix (Optional): Consider a prefix like feat: , fix: , docs: , chore: , refactor: (e.g., feat: Add user authentication ).

2. Blank Line: Always include a blank line between the subject and the body. This is important for Git tools
like git log --oneline .

3. Body (Optional):

Explain Why and How: Elaborate on the motivation for the change, the problem it solves, and any
significant implementation details.

Wrap at 72 characters: For readability in various Git tools.

Use Bullet Points: For lists of changes or reasons.

Reference Issues/PRs: Link to relevant issue trackers (e.g., Fixes #123 , Closes #456 ).

Example of a Good Commit Message:

feat: Implement user profile page

Adds a new user profile page accessible at /profile.


This page displays user's name, email, and a list of their recent activities.

Git & Github Notes 33


- Created `UserProfile.js` component.
- Added `/profile` route to `App.js`.
- Implemented API call to fetch user data.

Resolves #789

Bad Commit Messages to Avoid:

fix bug (Too vague)

updates (No context)

asdfasdf (Meaningless)

Forgot to add file (Should be part of a meaningful commit)

Avoiding Common Mistakes


Even experienced Git users can make mistakes. Understanding and avoiding these common pitfalls can save you
a lot of headaches.

1. Force Pushing ( git push --force or f ):

What it does: Overwrites the remote branch's history with your local history, even if your local history is
different (e.g., after a git rebase ).

Danger: If others have pulled the old history, force pushing will cause their local repositories to diverge,
leading to difficult merge conflicts and potentially lost work for them.

When to use (with extreme caution): Only on branches that are strictly your own and no one else is
working on, or after coordinating carefully with your team. Use -force-with-lease for a safer force push, which
fails if the remote branch has new commits you haven't seen.

Avoid: Force pushing to master / main or any shared branch.

2. Committing Large Files:

Problem: Git is optimized for tracking changes in text files. Committing large binary files (e.g., images,
videos, archives, compiled executables) can bloat your repository size, slow down operations ( clone ,
fetch ), and make history difficult to manage.

Solution: Use Git LFS (Large File Storage) for large files. Git LFS replaces large files in your repository with
small pointer files, while the actual file content is stored on a remote Git LFS server.

Also: Use .gitignore to prevent large build artifacts or temporary files from being committed in the first
place.

3. Committing Sensitive Information:

Problem: Accidentally committing API keys, passwords, private certificates, or other sensitive data. Once
committed, even if you delete the file in a subsequent commit, the sensitive data remains in the
repository's history.

Solution:

Use .gitignore to prevent sensitive files (e.g., .env files) from being committed.

Use environment variables for credentials in your applications.

If you accidentally commit sensitive data, you must use tools like git filter-repo (or the older git filter-branch )
to rewrite the history and remove the sensitive data permanently. This is a complex operation and
requires force pushing.

Never: Store credentials directly in your code.

4. Not Pulling/Fetching Regularly:

Problem: Working on an outdated local branch can lead to large and complex merge conflicts when you
finally try to integrate your changes.

Solution:

git pull frequently to get the latest changes from the remote.

Git & Github Notes 34


Consider git pull --rebase on your feature branches to keep your history linear.

Before starting new work, always git pull on your main development branch.

5. Committing Directly to master / main :

Problem: Bypasses code review, automated tests, and can introduce unstable or breaking changes
directly into your production-ready branch.

Solution: Always work on feature branches (or bugfix branches) and use Pull Requests for all changes
that merge into master / main . This is a cornerstone of collaborative workflows like GitHub Flow.

6. Ignoring Error Messages:

Problem: Git provides helpful messages. Ignoring them can lead to unexpected behavior or difficult-to-
diagnose issues later.

Solution: Read Git's output carefully. If you encounter an error or a warning, try to understand it before
proceeding. Git often suggests the next steps or commands to resolve the situation.

By understanding and applying these security measures and best practices, you can ensure a more secure,
efficient, and collaborative Git workflow.

Module 10: Bonus Topics (Optional)


This module covers additional, optional topics that can further enhance your Git and GitHub experience,
particularly for specific use cases.

GitHub Pages (Static Website Hosting)


GitHub Pages is a free static site hosting service directly integrated with GitHub. It allows you to host websites
directly from a GitHub repository, making it an excellent choice for personal portfolios, project documentation,
blogs, or simple web pages.

How it works:

You push your static website files (HTML, CSS, JavaScript, images) to a specific branch (usually gh-pages

or main / master in a /docs folder) in your GitHub repository.

GitHub automatically builds (if using Jekyll) and deploys your site.

Your site becomes accessible at a URL like your-username.github.io/your-repo-name or your-username.github.io (for a


user/organization site).

Key Features:

Free Hosting: No cost for hosting static sites.

Custom Domains: You can use your own custom domain name.

Jekyll Support: Built-in support for Jekyll, a static site generator, allowing you to write content in
Markdown.

HTTPS Support: All GitHub Pages sites are served over HTTPS.

Setting up GitHub Pages:

1. Create a Repository: Create a new public repository (or use an existing one).

2. Add your site files: Push your HTML, CSS, JS, and other static assets to your repository.

3. Configure Pages:

Go to your repository on GitHub.

Click on "Settings" (usually near the top right).

In the left sidebar, click "Pages".

Under "Build and deployment", choose your source branch (e.g., main or gh-pages ) and optionally a
folder (e.g., /docs or /root ).

Click "Save".

Git & Github Notes 35


4. Wait for Deployment: GitHub will then build and deploy your site. You'll see a link to your live site on the
Pages settings page once it's ready.

GitHub CLI
The GitHub CLI (Command Line Interface) is a command-line tool that brings GitHub's features directly to your
terminal. It allows you to interact with GitHub without leaving your command line, streamlining many common
workflows.

Why use GitHub CLI?

Efficiency: Perform common GitHub tasks (creating PRs, managing issues, reviewing code) without
switching to a web browser.

Automation: Easily integrate GitHub operations into scripts.

Consistency: Provides a consistent interface for interacting with GitHub.

Common Commands:

gh auth login : Authenticate with your GitHub account.

gh repo clone <owner>/<repo> : Clone a repository.

gh pr create : Create a new pull request.

gh pr status : View the status of your current pull requests.

gh pr checkout <PR_number> : Check out a pull request locally.

gh pr merge : Merge a pull request.

gh issue create : Create a new issue.

gh issue list : List issues.

gh issue view <issue_number> : View an issue.

gh release create <tag_name> : Create a new GitHub release.

gh gist create <file> : Create a new GitHub Gist.

Installation:

macOS (Homebrew): brew install gh

Linux (Debian/Ubuntu):

sudo apt update


sudo apt install gh

Windows (Winget): winget install --id GitHub.cli

Refer to the official GitHub CLI documentation for detailed installation instructions for your OS.

Git Submodules
Git submodules allow you to embed one Git repository inside another Git repository as a subdirectory. This is
useful when your project depends on a specific version of an external project, and you want to keep that
dependency separate but still track it within your main repository.

When to use Submodules:

When your project has a strong dependency on an external library or component that is managed in its
own Git repository.

When you want to track a specific version of that dependency (not just the latest).

When you want to keep the dependency's history separate from your main project's history.

How Submodules Work:

The parent repository stores a reference to a specific commit in the submodule's repository, not the actual
files.

Git & Github Notes 36


When you clone a repository with submodules, you get an empty directory for the submodule. You need to
explicitly initialize and update the submodules.

Common Commands:

git submodule add <repository_url> <path> : Adds a new submodule. This clones the submodule into the specified
path and adds an entry to your .gitmodules file.

git submodule add https://github.com/example/my-library lib/my-library

git submodule init : Initializes your local configuration file, copying the mapping from the .gitmodules file.

git submodule update : Fetches all data from the submodule project and checks out the commit specified in the
superproject.

Often combined: git submodule update --init --recursive (for nested submodules).

git clone --recurse-submodules <repository_url> : Clones the main repository and all its submodules in one go.

git submodule foreach git pull origin main : To update all submodules to their latest main branch (be careful, this can
change the superproject's state).

git rm <path_to_submodule> : Removes a submodule. You'll also need to remove its entry from .gitmodules and
.git/config .

Considerations/Drawbacks:

Complexity: Submodules can add complexity to your workflow, especially for new team members.

Version Management: You must explicitly update the submodule reference in the parent repository when
the submodule changes.

Branching: Working with branches across submodules can be tricky.

Alternatives: For many cases, package managers (npm, Composer, Maven, pip) or monorepo tools might
be simpler alternatives.

Working with Large Files (Git LFS)


As briefly mentioned in Module 9, Git LFS (Large File Storage) is an open-source Git extension for versioning
large files. Instead of storing large files directly in your Git repository, Git LFS stores pointers to them in your
repository, while the actual file content is stored on a remote Git LFS server.

Why use Git LFS?

Avoid Repository Bloat: Keeps your Git repository small and fast, as large binaries are not stored directly
in the Git history.

Faster Operations: git clone , git fetch , and other operations become much faster because you're only
downloading small pointers initially.

Better Performance: Git is optimized for text diffs; LFS handles binaries efficiently.

Collaboration: Makes it feasible to collaborate on projects that include large assets (e.g., game
development, design, data science).

How Git LFS Works:

1. You install Git LFS on your system.

2. You tell Git LFS which file types to track (e.g., .psd , .mp4 , .zip ).

3. When you commit a file that matches a tracked pattern, Git replaces the file's content with a small
"pointer" file in your Git repository.

4. The actual large file is uploaded to the Git LFS server (e.g., GitHub's LFS server).

5. When someone clones or checks out a branch, Git LFS automatically downloads the actual large files
when needed.

Steps to Use Git LFS:

1. Install Git LFS:

macOS (Homebrew): brew install git-lfs

Git & Github Notes 37


Linux (Debian/Ubuntu): sudo apt install git-lfs

Windows: Download from git-lfs.github.com or use a package manager.

2. Initialize Git LFS for your repository:

git lfs install

Run this once per machine.

3. Track file types: Tell Git LFS which file extensions or patterns to track. This adds entries to your .gitattributes

file.

git lfs track "*.psd"


git lfs track "assets/*.mp4"

4. Check .gitattributes : Verify that the tracking rules are added.

# .gitattributes example
*.psd filter=lfs diff=lfs merge=lfs -text
assets/*.mp4 filter=lfs diff=lfs merge=lfs -text

5. Add and Commit: Stage and commit your files as usual. Git LFS will handle the large files automatically.

git add .
git commit -m "Add large PSD file"

6. Push:

git push

Git LFS will push the large files to the LFS server.

Important Notes:

Git LFS files are only stored on the LFS server, not directly in the .git directory.

If you're migrating an existing repository with large files, you'll need to use git lfs migrate to rewrite history
and convert existing large files to LFS pointers.

GitHub provides a certain amount of free Git LFS storage and bandwidth; exceeding this may incur costs.

Git & Github Notes 38

You might also like