This section outlines what you will learn from this tutorial and what practical outcomes you should achieve. You can use these goals as a checklist while progressing through each part.
The objective of this training module is to enhance your understanding of Git and version control. After completing this module, you should be able to:
This section introduces the core ideas behind version control, Git, and GitHub before hands-on practice. It builds the background knowledge needed to understand the workflows taught later.
Use these subsection links to jump directly to the concept you want to review in this introduction block.
What is Version Control? | Types of VCS | What is Git? | What is GitHub?
In this module, we will explore Git and GitHub, two essential tools in modern software engineering. Understanding these tools is crucial for effective version control and collaboration in software development.
Before we delve deeper into Git and GitHub, it's important to understand what version control is.
Version control is a system that tracks changes to files over time, allowing you to retrieve specific versions at a later date. A Version Control System (VCS) enables you to:
Common version control models include Local VCS, Centralized VCS, and Distributed VCS. Modern software teams typically use distributed systems such as Git.
Git is a distributed version control system that helps track changes in your code over time.
Think of the changes as a stream of snapshots, each representing the state of your project
at a specific point.
A Git repository contains a hidden .git folder within the project directory,
which stores all the version history and metadata.
GitHub is a website and cloud-based service designed to help you save and manage your code and projects. It is the most commonly used platform for hosting repositories, allowing you to share your code online with others. Additionally, GitHub can serve as a valuable tool for showcasing your work, acting as a developer's resume.
With this foundation, in this module, you will learn a complete workflow: setting up Git, creating and cloning repositories, making meaningful commits, working with branches, resolving basic merge conflicts (self-learn), and collaborating using pull requests.
By mastering Git and GitHub, you will enhance your ability to manage projects effectively and collaborate with others in the software development process.
This section teaches the setup steps required before you start Git practice. You will create accounts, install tools, configure identity settings, and verify access for remote collaboration.
Use these subsection links to go straight to the setup task you need on your current device.
Create GitHub Account | Install Git | Configure Git | SSH Setup
In this workshop, we will use Git and Visual Studio Code (VSCode) to complete our practice.
We will use https://github.com/HKUST-CRS/crs as the demonstration repository.
Visit github.com and sign up for a free account.
Git is the command-line tool that powers GitHub. To install it on your system:
This path shows how to install Git using the official installer on Windows. It helps you complete setup with VS Code as the default editor.
.exe file and click Next
until you reach the page where you can choose the default editor.
This path shows how to install Git with Homebrew on macOS. It prepares your machine for terminal-based Git commands used throughout the module.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install git
Open VSCode and launch the terminal by pressing Ctrl + ` (or use the macOS
terminal directly).
Set up your identity in Git by entering the following commands:
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
In VSCode, open the terminal using Ctrl + ` and type:
ssh-keygen -t ed25519 -C "your_email@example.com"
Press "Enter" repeatedly until you see a confirmation message. This will create the SSH key in the default directory for later use.
Next, retrieve the SSH key by typing:
cat ~/.ssh/id_ed25519.pub
Copy the displayed key and add it as a new SSH key in your GitHub account.
To test your setup, run the following command in the terminal:
ssh -T git@github.com
When prompted, type "yes" to confirm the connection. If the setup is successful, you will see a success message.
This section teaches the daily Git command flow from repository creation to commit history inspection. You will learn the key operations used in almost every software project.
Use these subsection links to jump to the exact Git operation you want to practice or revise.
Getting a Local Repository | Basic Workflow | Stage and Unstage | Removing from Staging | Commit Files | Commit History | Commit Object
Practice the essential daily Git command workflow.
As mentioned earlier, a Git project contains a hidden .git folder.
If you want to make your folder a Git project, initialize a repository from the project root.
Open terminal in VSCode and run:
git init
The Basic Workflow of a Git Project has three local stages: Modified, Staged, and Committed.
git add, you prepare your changes to be committed. This is the "staging area" or "index"
where you curate which changes you want to commit.
git commit -m "message", your changes create a snapshot in the project's
version history that can be retrieved at any time.
Example: create a hello_world.py file, then add it to staging.
print("Hello world")
hello_world.py
Click the + icon in Source Control to stage changes.
+ button
# Replace hello_world.py with your target file
git add hello_world.py
# Or stage all files
git add .
# Remove from staging area
git reset hello_world.py
Removing files from the staging area keeps your edits in the working directory while taking them out of the next commit. It is useful when you accidentally staged the wrong file or when you want to split one large change into smaller commits. In practice, unstaging helps you keep each commit focused, readable, and easier for teammates to review.
- button
git reset hello_world.py
Committing staged changes creates a permanent snapshot in your local Git history. Each commit becomes a checkpoint you can inspect, share, and recover from if needed. Writing clear commit messages also improves collaboration because reviewers can quickly understand intent, impact, and scope.
# Check what changed
git status
# Save a snapshot
git commit -m "commit message"
If you want to learn how to safely undo a commit after it is pushed, you can learn from here.
Viewing commit history lets you inspect your repository timeline so you can understand how the project evolved over time. It helps you trace when a change was introduced, who made it, and how branches were merged. You will also use commit history to find commit hashes for tasks such as revert, reset, comparison, or checkout.
Click on the Source Control icon in the left sidebar and look for the GRAPH section. This displays a visual timeline of all your commits with branches, showing:
Use the git log command to view commit history:
# View commit history with details
git log
# View commit history in one-line format (compact)
git log --oneline
# View commit history with author and date
git log --oneline --graph --all --decorate
A commit object stores a pointer to the snapshot, a pointer to the previous commit, author information, and commit message. For example, we make one more commit:
The snapshot stores the data state at that commit.
Always write clear, descriptive commit messages. Future you and your collaborators will thank you.
Use these subsection links to move directly to the branch workflow step you want to learn, from creating branches to merging them safely.
Creating and Switching Branches | Switching Between Branches | Branch Divergence | Merge Branch
Branching creates isolated lines of development so you can build features, fixes, or experiments without
risking the stability of the main branch. Instead of editing everything directly on main,
teams create branches for focused work and merge only after validation. This workflow reduces conflicts,
improves review quality, and keeps release history cleaner.
A branch is a movable pointer to a commit, and HEAD marks your current working branch.
Because pointers move forward as you commit, Git can manage multiple parallel timelines efficiently. This
model makes collaboration safer and allows you to switch context without losing progress.
HEAD pointer
Creating and switching branches starts a new line of work from your current commit and moves your workspace to that branch. It is the standard way to start a task so all related edits remain grouped in one reviewable unit. Keeping work on dedicated branches also makes pull requests clearer and reduces the chance of mixing unrelated changes.
In VSCode: Branch → Create Branch → [type branch name]
feature in VSCode
git branch feature # create new branch
git checkout feature # switch to feature branch
# Or create and switch in one command
git checkout -b feature
The new branch points to the same commit as HEAD at creation time.
HEAD
After a commit on feature, the feature pointer moves while
master/main stays where it was.
feature branch in VSCode
feature moved; master/main unchanged
Switching branches changes your active branch so your files reflect another line of development. It is useful when you need to pause one task, fix something urgent, and then return later. Switching branches smoothly helps you manage multiple tasks while keeping each timeline organized.
feature to master in VSCode
git checkout main
# or, if your default branch name is master
git checkout master
Branch divergence happens when separate branches receive different commits and their histories split into parallel lines. Divergence is normal in collaborative work and simply means each branch has progressed independently. Once both lines contain valuable updates, you merge them to create a single integrated history.
For example, commit on master/main while
feature stays unchanged.
master branch in VSCode
Merging combines changes from one branch into another, usually from a feature branch
back into main or master. During merge, Git attempts to integrate both histories
while preserving commit context and authorship. After a successful merge, completed work becomes part of
the shared codebase and is ready for team use.
master)
feature into master
git checkout master # target branch
git merge feature # source branch
feature into master
If you want to learn how to solve merge conflicts after merging branches, you can learn from here.
Use these subsection links to jump to the exact remote workflow you need, such as setup, sync, cloning, or pull requests.
Remote Repository | Set Up an Empty GitHub Repo | Adding Remote Origins | Git Clone | Removing Remote Origins | Push Your Work | Sync from Repository | Pull (Fetch + Merge) | Fork on GitHub | Pull Request Workflow
This section explains how local Git repositories connect to GitHub for collaboration, backup, and team workflows. A remote repository acts as a shared source of truth so team members can exchange commits, review code, and recover work if devices fail. You will learn how to publish branches, synchronize updates, and keep local and remote history aligned.
A remote repository is the online copy of your project, usually hosted on platforms like GitHub. Your local repository is where you edit and commit, while the remote repository is where you publish work for backup and collaboration. In a typical workflow, you push local commits to the remote and fetch or pull updates made by others.
Remote branches are denoted as:
<remote-name>/<branch-name>
The default remote name is usually origin.
In this section, we will teach you about two common ways to start working with a GitHub
repository: git remote add and git
clone. Use git remote add when your code already exists locally and you want
to connect it to a remote repository on GitHub, or use git clone when the code already
exists on a remote repository and you want to download it to your local machine.
This subsection teaches you how to create an empty repository on GitHub so your local project can connect to it as a remote destination. You will create the repository, choose visibility, and copy the repository URL for later remote configuration and push operations.
If you already have local files, create the repository as an empty remote first. This avoids extra initial commits from GitHub that may complicate your first push and pull.
Remember: If your project already exists locally, do not select "initialize repository" options (README, .gitignore, or license) at this stage.
my-first-repo).
Make your repository private for assignment work.
Then copy the repository link:
Remember to set up SSH in Git (from the Installation section).
Adding a remote origin links your local repository to a remote repository URL, commonly
named origin. Once the remote is configured, Git knows where to send your commits and where
to retrieve updates from collaborators. You can manually add your own origin when a
repository was created locally with git init and is not yet connected to GitHub.
In VS Code: Remote → Add Remote
Then add the link and press Enter:
Then type remote name (origin) and press Enter:
origin)
# replace <remote-name> with your remote name
# replace <github-link> with your URL
git remote add <remote-name> <github-link>
# Check remotes
git remote -v
Git clone creates a full local copy of an existing remote repository, including files,
commits, and branch history. When you clone from GitHub, Git automatically creates a remote named
origin that points to that repository URL, so you usually do not need to add it manually
afterward. After cloning, you can open the folder in VS Code, create your own branch, and start work
immediately.
First, get the clone URL from GitHub:
Press Command+Shift+P and run Git Clone.
Then paste repository URL:
And select destination folder:
# change <remote-url> to target repository URL
git clone <remote-url>
This subsection shows how to detach an existing remote from your local repository. Use it when a remote URL is outdated, incorrect, or no longer needed.
In VS Code: Remote → Remove Remote
# replace <remote-name> with your remote name
git remote remove <remote-name>
Pushing uploads your local commits to the remote repository so others can review or
build on your changes. The first push usually connects your local branch to a matching remote branch using
upstream tracking. After that link is set, later pushes are faster and typically require only
git push.
In VS Code: Publish Branch
# replace <remote-name> with your remote name
# replace <branch-name> with your branch name
# you don't need --set-upstream on later pushes
git push --set-upstream <remote-name> <branch-name>
# Later push only
git push
Syncing from the repository brings remote updates into your local environment so your branch stays current with shared work. Syncing often helps you catch conflicts early, before your own branch drifts too far from the remote. As a good habit, sync before coding sessions and again before opening a pull request.
Use fetch to download remote updates:
# replace <remote-name> with your remote name
git fetch <remote-name>
This downloads the updated remote branch:
Then you can sync (merge) origin/master to master:
origin/master to master
You can also use merge from <remote-name>/<branch-name> to
<branch-name>; it does the same sync effect.
git merge <remote-name>/<branch-name> <branch-name>
Pull combines fetch and merge into one command to quickly
update your current branch. It is convenient for day-to-day work because it reduces two steps into one and
keeps your local branch current. Even so, you should still read incoming changes carefully, especially
when syncing critical branches.
git pull <remote-name>
# This does fetch and merge together
A fork creates your own copy of someone else's repository under your GitHub account.
A Pull Request (PR) lets you propose your changes, discuss them with reviewers, and merge safely into the target branch after approval.
Pull Request checklist: clear title, concise description, testing notes, and reviewer-friendly commits. After opening the pull request, wait for reviewers to do code review. Once it is approved, a maintainer (or authorized teammate) will merge the pull request.
Always fetch/pull before starting new work to ensure you have the latest changes from collaborators.
This section teaches the complete COMP 4900 submission workflow from forking to pull request delivery. Follow these steps in order to ensure your contribution is valid and ready for grading.
Use these subsection links to jump to the stage of the assignment process you are currently working on.
Task Overview | Task Instructions | Task Success and Submit | Verification | Troubleshooting | Deadline
Complete this COMP 4900 contribution task by following the standard open-source workflow and keeping your pull request link for Canvas submission:
Original repository: HKUST-COMP4900-2026S-Task
Before you start: Make sure you have a GitHub account and your Git installed.
add-my-student-info.
Refer to Creating and Switching Branches.
Data/student.json and add or update your record with all required fields:
name, student ID, ITSC email, and GitHub username. Keep JSON syntax valid (quotes, commas,
and brackets).
Refer to Basic Workflow of a Git Project to review the edit -> stage ->
commit process.
Data/student.json, create a commit, and push your branch to your fork.
Refer to Stage and Unstage Files,
Commit a file from staging area to repository, and
Push Your Work.
After opening your pull request, the GitHub Actions bot should confirm success with messages such as "Your pull request is valid for the submission" and "Your submission has been synced to the Google Spreadsheet." You can check your submission status in this tracking spreadsheet. Then refer to the image and copy your PR link from the browser address bar before submitting on Canvas.
Use this checklist to confirm your submission workflow is complete and correct. Completing every item reduces validation failures before deadline.
Data/student.json.
If push/pull fails, check git remote -v, branch name, and authentication settings. If your
auto-validation fails, read the bot reply in the pull request, fix the reported issue, and push updates
to the same branch.
Please submit your pull request link before the assignment deadline on Canvas. Always follow the deadline shown on Canvas as the final source of truth.
This section provides follow-up references for revision and self-learning after the workshop. Use it to quickly revisit commands, read official documentation, and explore advanced Git topics.
Use these subsection links to jump directly to summaries, official references, or advanced topics for deeper study.
Tutorial Slide | Essential Commands Summary | Official Documentation | Quick Reference | Other Git Operation | Resolve Merge Conflict | Use Git Revert | Want to Learn More?
The Slide is here.
This subsection groups the most common Git commands by task type. Use it as a fast reference when you need syntax during practice.
These commands create or connect repositories so your project can be tracked by Git and linked to GitHub.
git init
git clone <url>
git remote add origin <url>
These commands are the day-to-day cycle for checking changes, staging work, committing snapshots, and syncing with remote.
git status
git add <file>
git commit -m "message"
git push
git pull
These commands create, switch, merge, and clean up branches so feature work can be isolated and integrated safely.
git branch
git checkout -b <branch>
git merge <branch>
git branch -d <branch>
These commands keep your local and remote repositories aligned by downloading, uploading, and checking remote connections.
git fetch
git pull
git push
git remote -v
These are the authoritative sources for Git and GitHub behavior. Use them when you need deeper explanations or edge-case guidance.
These links provide printable cheat sheets for quick command lookup. They are useful during labs, assignments, and exams.
This subsection introduces additional Git operations you may need after the basics. It focuses on common recovery and history-management tasks.
Merge conflicts happen when two branches change the same lines differently. A common case is editing the
same file in both master/main and a feature branch.
master branch content
When you merge branches with conflicting edits, Git stops and asks you to resolve:
git checkout master
git merge wrong
Open the conflicted file and choose the final content in the Merge Editor. You can accept current,
incoming, or both changes, then click Complete Merge.
Terminal workflow after editing conflict markers:
# 1) Check conflicted files
git status
# 2) Resolve markers in file: <<<<<<< ======= >>>>>>>
# 3) Stage resolved file(s)
git add <file>
# 4) Complete merge
git commit
If you decide to stop the merge process:
git merge --abort
Use git revert to safely undo changes from an earlier commit. Unlike git reset,
it does not rewrite history; it creates a new commit that reverses the target changes.
# 1) Inspect history and copy target commit hash
git log --oneline
# 2) Revert one commit by hash
git revert <commit-hash>
# 3) Revert the latest commit
git revert HEAD
# 4) Revert a merge commit (choose mainline parent, usually 1)
git revert -m 1 <merge-commit-hash>
After revert, run git status and git log --oneline to verify the new revert
commit, then push as usual.
These resources help you continue beyond the workshop with advanced Git workflows and collaboration patterns. Explore them when you want deeper practical skills.
No changes have been made.
Because I want to use my own slide :3