Git Workflow and Project Management
A Guide for Students
1 Git Workflow and Project Management

1.1 Setting Up Your Git Identity
Before you start working on a project, it’s a good practice to set up your global Git configuration. This tells Git who you are when you make commits. The information you set here will be associated with every commit you make on your computer.
Configure Your Name and Email
You should set your user.name and user.email to match your GitHub account.
- Open your terminal or Git Bash.
- Set your global username:
git config --global user.name "Your Name"- Set your global email address:
git config --global user.email "your_email@example.com"Your email should match the one associated with your GitHub account.
To verify your settings, you can run:
git config --global --list1.2 Managing Your Repository and Code Updates
Git tracks your code locally, but to keep your local repository in sync with the remote repository on GitHub, you need to manage code updates.
Pulling Updates from GitHub
The git pull command is the most common way to get changes from the remote repository. It’s a combination of two commands: git fetch and git merge.
git pull: Fetches all new changes from the remote repository and automatically merges them into your current local branch. This is the simplest way to update your code.
git pull origin mainFetching vs. Pulling
Sometimes, you may want to see what changes are on the remote repository without immediately merging them. This is where git fetch is useful.
git fetch: Downloads the latest changes from the remote repository but does not merge them into your local branch. This allows you to inspect the changes first.git merge: Merges the changes you just fetched into your local branch.
A typical workflow might be:
# Step 1: Fetch changes
git fetch origin
# Step 2: See what has changed
git diff main origin/main
# Step 3: Merge the changes after you've reviewed them
git merge origin/mainStaging and Committing Changes
Understanding how to stage and commit your changes is fundamental to using Git effectively. These steps allow you to carefully select which modifications you want to save as a single, coherent snapshot in your project’s history.
The Staging Area (Index)
The staging area, also known as the “index,” is a crucial intermediate step between your working directory (where you make changes) and your repository (where Git stores your project’s history).
- Purpose: It allows you to build up a set of changes that you want to commit together. You can add parts of files, entire files, or multiple files to the staging area.
- Benefit: This gives you fine-grained control over what goes into each commit, enabling you to create logical and atomic commits. For example, you might make several changes, but only want to commit the bug fix now and save the new feature for a separate commit.
Adding Changes to the Staging Area
To prepare your changes for a commit, you use the git add command.
- Stage a specific file:
git add path/to/your/file.txt- Stage all changes in the current directory and its subdirectories:
git add .- Stage specific changes within a file (interactive staging):
git add -p path/to/your/file.txtThis command allows you to review changes hunk by hunk and decide whether to stage each one.
Committing Changes
Once your changes are in the staging area, you can record them permanently in your repository’s history using the git commit command. Each commit represents a snapshot of your project at a specific point in time, along with a message describing the changes.
- Commit staged changes with a message:
git commit -m "Your descriptive commit message here"A good commit message is concise, descriptive, and explains why the change was made, not just what was changed. To maintain a consistent and readable project history, it’s highly recommended to follow the Conventional Commits specification.
Conventional Commits provide a set of rules for creating an explicit commit history, which makes it easier to write automated tools on top of it. The structure of a conventional commit message looks like this:
<type>(optional scope): <description>
[optional body]
[optional footer(s)]Type: This is a mandatory prefix that describes the nature of the change. Common types include: * feat: A new feature * fix: A bug fix * docs: Documentation only changes * style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc.) * refactor: A code change that neither fixes a bug nor adds a feature * perf: A code change that improves performance * test: Adding missing tests or correcting existing tests * build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm) * ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs) * chore: Other changes that don’t modify src or test files * revert: Reverts a previous commit
Scope (Optional): This provides additional contextual information. For example, feat(parser): add ability to parse arrays.
Description: A short, imperative tense description of the change.
Body (Optional): A longer description providing more context about the change.
Footer(s) (Optional): Used for referencing issues (e.g., Closes #123) or indicating breaking changes (e.g., BREAKING CHANGE: ...).
Example:
feat(authentication): add user login functionality
This commit introduces the user login feature, allowing users to authenticate
with their credentials. It includes form validation and integration with
the backend authentication API.
Closes #45Squashing Commits for a Cleaner History
Sometimes, during development, you might make several small commits that, when viewed together, represent a single logical change. “Squashing” commits allows you to combine these multiple commits into one, resulting in a cleaner, more readable project history. This is particularly useful before merging a feature branch into main.
- How to squash commits (interactive rebase): To squash the last
Ncommits, you’ll usegit rebase -i HEAD~N. For example, to squash the last 3 commits:
git rebase -i HEAD~3This command will open an interactive editor (usually your default text editor) showing a list of the last 3 commits.
pick 0a1b2c3 Commit message 1
pick d4e5f67 Commit message 2
pick 7g8h9i0 Commit message 3
# Rebase 1234567..7g8h9i0 onto 1234567 (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase afterwards with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the one specified by -m)
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented outTo squash, change pick to squash (or s) for the commits you want to merge into the previous one. Keep pick for the first commit in the sequence you want to preserve.
For example, to combine “Commit message 2” and “Commit message 3” into “Commit message 1”:
pick 0a1b2c3 Commit message 1
squash d4e5f67 Commit message 2
squash 7g8h9i0 Commit message 3Save and close the editor. Git will then open another editor for you to combine or edit the commit messages of the squashed commits into a single, coherent message.
Squashing commits rewrites history. Avoid squashing commits that have already been pushed to a shared remote repository, as this can cause conflicts for collaborators.
Pushing Your Changes
Once you’ve committed your changes to your local repository, you need to “push” them to the remote repository on GitHub. This makes your changes available to others and updates your online repo.
git push: Uploads your local commits to the remote repository.
git push origin main1.3 Working with Branches
Branches are essential for managing different versions of a project. The main branch is the primary line of development. When you work on a new feature or fix a bug, you should do so in a separate branch to keep the main branch clean and stable.
Common Branching Commands
- Create a new branch and switch to it:
sh git checkout -b new-feature-branch - Switch back to the
mainbranch:sh git checkout main - Merge your branch into the
mainbranch: First, switch to the branch you want to merge into (in this case,main).sh git checkout mainThen, merge your feature branch:sh git merge new-feature-branch - Delete a branch:
sh git branch -d new-feature-branch