Class 35: Version Control with Git & GitHub
In any software development project, especially when working in a team, managing changes to your codebase is critical. This is where Version Control Systems (VCS) come into play. Today, we'll focus on the most popular distributed VCS: Git, and its most widely used hosting platform: GitHub.
Introduction to Version Control Systems (VCS)
-
What is VCS?
A system that records changes to a file or set of files over time so that you can recall specific versions later. It helps track who made what changes, when, and why.
-
Why is it essential for software development?
- Tracking Changes: Keeps a history of every modification, allowing you to see what changed between versions.
- Collaboration: Enables multiple developers to work on the same codebase simultaneously without overwriting each other's work.
- Reverting to Previous States: Easily undo mistakes or roll back to an earlier, stable version of your code.
- Branching & Merging: Allows developers to work on new features or bug fixes in isolation without affecting the main codebase until they are ready.
- Accountability: Provides a clear record of who made which changes.
-
Types of VCS:
- Centralized VCS (CVCS): (e.g., SVN, Perforce) All versioned files are stored on a central server. Clients check out files from this central place.
- Distributed VCS (DVCS): (e.g., Git, Mercurial) Clients don't just check out the latest snapshot of the files; they fully mirror the entire repository, including its full history. This means every clone is a full backup of all the data.
Introduction to Git
Git is a free and open-source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.
The Three States of Git:
Git manages your project files through three main states:
-
Working Directory:
This is where you're currently working. It contains the actual files you're editing.
-
Staging Area (Index):
A temporary area where you prepare changes before committing them. You "stage" files that you want to include in your next commit.
-
Local Repository (.git directory):
This is where Git stores all the history of your project. When you "commit" changes, they are permanently recorded in your local repository.

Basic Git Commands (Local Repository)
Let's go through the essential Git commands for local operations.
1. git init
: Initialize a new Git repository.
This command creates a new .git
subdirectory in
your current directory, which contains all the necessary Git
repository files.
cd my-project
git init
2. git status
: Check the status of your working
directory.
Shows which files are untracked, modified, or staged for commit.
git status
3. git add <file>
/ git add .
:
Stage changes.
Moves changes from the Working Directory to the Staging Area.
git add index.html # Stage a specific file
git add css/ # Stage all files in a directory
git add . # Stage all changes in the current directory and subdirectories
4. git commit -m "message"
: Record staged changes.
Takes the staged snapshot and stores it permanently in your local repository. The message should be descriptive.
git commit -m "Add initial HTML structure for homepage"
5. git log
: View commit history.
Shows a list of all commits in the current branch, including commit hash, author, date, and commit message.
git log
git log --oneline # Concise view
6. git diff
: Show changes.
Compares changes between various Git states.
-
git diff
: Shows changes in the working directory that are not yet staged. -
git diff --staged
: Shows changes in the staging area that are not yet committed. -
git diff <commit1> <commit2>
: Shows changes between two specific commits.
7. git restore
: Unstage files, discard changes.
Used to undo changes.
-
git restore --staged <file>
: Unstages a file (moves it from Staging Area back to Working Directory). -
git restore <file>
: Discards changes in the working directory (reverts file to its last committed state). Use with caution, as this loses unstaged changes!
8. .gitignore
: Excluding files from version
control.
A plain text file where each line specifies a pattern for files
or directories that Git should ignore (e.g.,
node_modules/
, .env
files, build
artifacts).
# .gitignore example
node_modules/
.env
build/
dist/
*.log
Git Branching and Merging
Branches are fundamental to Git and enable parallel development.
-
Why branches?
Branches allow you to isolate development work. You can create a new branch for a new feature or bug fix, work on it independently, and then merge it back into the main codebase when it's complete and stable. The
main
(ormaster
) branch typically represents the stable, deployable version of your code. -
git branch <branch_name>
:Creates a new branch.
git branch feature/new-auth
-
git checkout <branch_name>
:Switches to a different branch. You can also use
git switch <branch_name>
(newer command).git checkout feature/new-auth # Or: git switch feature/new-auth
To create and switch in one go:
git checkout -b <branch_name>
orgit switch -c <branch_name>
. -
git merge <branch_name>
:Integrates changes from one branch into your current branch.
# Assuming you are on the 'main' branch git merge feature/new-auth
-
Resolving merge conflicts:
Conflicts occur when Git cannot automatically merge changes (e.g., two branches modified the same lines in the same file). Git will pause the merge, and you'll have to manually edit the conflicting files, choose which changes to keep, and then stage and commit the resolution.
-
git branch -d <branch_name>
:Deletes a local branch (only if it has been merged). Use
-D
to force delete (even if not merged).git branch -d feature/new-auth
Introduction to GitHub (Remote Repository)
While Git manages your local repository, GitHub is a web-based platform that provides hosting for Git repositories. It's the most popular platform for collaborative development and open-source projects.
1. Creating a new repository on GitHub:
Go to github.com, log in, and click "New repository". Follow the
prompts. You'll get a URL (e.g.,
https://github.com/your-username/your-repo.git
).
2. git remote add origin <url>
: Connecting
local repo to remote.
This command tells your local Git repository where its remote
counterpart is located. origin
is the conventional
name for the main remote repository.
git remote add origin https://github.com/your-username/your-repo.git
3. git push origin <branch_name>
: Uploading
local commits to remote.
Sends your committed changes from your local branch to the remote repository.
git push origin main # Push changes from local 'main' to remote 'main'
git push -u origin main # The first time, use -u to set upstream tracking
4. git pull origin <branch_name>
: Downloading
and integrating remote changes.
Fetches changes from the remote repository and automatically merges them into your current local branch.
git pull origin main
5. git clone <url>
: Copying a remote
repository locally.
Downloads an entire repository, including all its history and branches, from a remote server to your local machine.
git clone https://github.com/your-username/your-repo.git
Collaborative Workflow with GitHub
GitHub provides powerful features for team collaboration.
-
Forking and Cloning:
- Forking: Creating your own copy of a repository on GitHub. Useful for contributing to open-source projects where you don't have direct write access.
- Cloning: Downloading a copy of a repository (either your own fork or the original) to your local machine.
-
Pull Requests (PRs):
The core of GitHub's collaborative workflow. A PR is a request to merge changes from one branch (or fork) into another. It initiates a discussion and code review process.
- Developer creates a feature branch, makes changes, commits.
- Pushes feature branch to GitHub.
-
Opens a Pull Request from feature branch to
main
. - Team members review code, provide feedback.
-
Once approved, PR is merged into
main
.
-
Code reviews:
A critical practice where other developers examine your code changes before they are merged. Best practices include: providing constructive feedback, keeping PRs small, and focusing on quality and maintainability.
-
Issues:
GitHub's issue tracker is used to track tasks, bugs, feature requests, and other development work. Issues can be linked to pull requests.
Reverting Changes
Sometimes you need to undo commits. Git offers a few ways:
-
git revert <commit_hash>
:Undoes a commit by creating a new, "inverse" commit that reverses the changes of the specified commit. This is safer for shared history because it doesn't rewrite history.
git revert HEAD~1 # Revert the second-to-last commit
-
git reset <commit_hash>
:Moves the HEAD pointer and optionally the branch pointer to a specified commit, effectively rewriting history. Use with extreme caution on shared branches, as it can cause problems for collaborators.
git reset --hard HEAD~1 # Discard last commit and all changes
Git and GitHub are indispensable tools for any modern developer. Mastering them will significantly improve your workflow, collaboration, and code quality. In the next class, we'll begin to explore how to deploy your web applications to the cloud.