Git Basics

Using Git for version control and collaborating with your teammates is a fundamental part of this course. Git enables you to manage your code efficiently and share it professionally.

Key Benefits of Git

  1. Version Control: Track code changes and revert to previous versions when needed
  2. Team Collaboration: Share code and conduct peer reviews seamlessly
  3. Easy Submission: Submit assignments via repository links instead of large zip files
  4. Professional Portfolio: Add your Git repositories to your resume to showcase your work
  5. Open Source Experience: Gain practical experience in open source development
  6. Cloud Backup: Maintain a secure backup of your code (GitHub offers unlimited storage for public repositories)

Core Git Concepts

In this section, you'll learn essential Git operations including:

  1. Basic Operations:
  • Adding files to staging
  • Committing changes
  • Pushing code to GitHub
  1. Branch Management:
  • Creating feature branches
  • Working with pull requests
  • Merging and rebasing code to the main branch

Make Your First Commit

Tip

If you are on macOS, the Git client is already installed. You can check by running git --version in your terminal.
On Windows, you can download Git from the official website: Git for Windows

We are going to use Fork, a GUI client for Git, to manage our repositories. You can download Fork from the official website: Fork However, you can still use the command line to interact with Git if you prefer. But Fork provides a more user-friendly interface for beginners.

Download the Fork client from the official website and install it on your machine.

Open your terminal (or git bash on Windows) and run git --version to check if Git is installed.

Go to GitHub.

Click on your Avatar and click the Settings menu.

Click on the Developer settings menu.

Click on the Personal access tokens > Tokens (Classic) or go to this link

Click the top right corner Generate new token button, and then click on the Generate new token (classic) button.

You must select the repo scope to access your repositories. Otherwise, you won't be able to push your code to GitHub. You are advised to select the workflow scope as well to enable GitHub Actions and set expiration to 90 days or less to keep your account secure.

Copy your GitHub token on the screen. Note, you won't be able to see it again.

Open your terminal/git bash and run

git config --global credential.helper store

To store your credentials in the cache.

Run

git config --global user.name "Your Name"
git config --global user.email "YOUR EMAIL"

Keep in mind, use your GitHub assigned email, not your real email! You can go to this link and copy the email from Email section. It should end with @users.noreply.github.com.

Create a new repository on GitHub, let's name it git-tutorial.

Clone the repository to your local machine by running

git clone [repository-url]

Replace the [repository-url] with the URL of your repository.

Create a readme.md file in the repository and add some content.

Open the repository in Fork

You will find the readme.md file is in the Unstaged section. Click on the file or cmd+a to select all files and click on the Stage button.

Add a commit message and click on the Commit button.

And now you can see your commit in the Commits section. Click on the Push button to push your code to GitHub.

Warning

You may be ask to enter your personal access token you generated earlier.

And lastly, click the Push button to push your code to GitHub.

And now you can find your repository on GitHub with the readme.md file you created. If you have any question on Authentication Failed error, you can check this link for more information.

Git Commit History

Git repositories are structured like trees, where each commit represents a node connected to its parent commit(s). This creates a branching history that tracks how your codebase evolves over time. We will guide you step by step to visualize the main concepts of Git.

Branches and Main Branch

Just like a tree, a Git repository consists of branches that represent different versions of your codebase.

Usually, it represents different features or bug fixes that you are working on.

Some open source project may also have some release branches to keep track of the stable versions. For example, release/1.0, release/2.0.

The main branch (historically called "master", now commonly "main") serves as the primary branch

Each branch is a pointer to a specific commit

Multiple branches can diverge from main to develop different features independently

Every commit stores:

  • A snapshot of all tracked files
  • Author information
  • Timestamp
  • Commit message
  • Reference to parent commit(s)

Since it stores the reference to the parent commit(s), it means

We have the ability to (hard) reset to any previous commit.

Warning

Hard reset: This operation is irreversible and will remove all the commits after the selected commit.
Use this operation with caution.

Or check out to any previous commit to see the code at that time.

Branches are essential in Git to manage different versions of your codebase. It enables us to:

  • Create feature branches for new development
  • Merge completed features back to main
  • Delete obsolete branches to maintain cleanliness
  • Use tags to mark important versions/releases

But managing branches can be tricky and lead to conflicts if not done correctly.

Merge and Rebase

Merge and rebase are two essential operations in Git. They help you combine changes from different branches and maintain a clean commit history. Below are some best practices to follow:

Rebase is a powerful operation that allows you to integrate changes from one branch to another by moving, or rebasing, the commits to the target branch.

It will produce a linear commit history, making it easier to understand.

Note

Main branch is in purple color and feature branch is in rose color.

And just like the name suggests, it will rebase your commits on top of the main branch. You can see from the diagram, the commit C is originally on the same level as D, but after the rebase, it is the child of D.

Squash and rebase is a very popular operation in open source projects.

Unlike regular rebase, squash and rebase will combine all the commits in your feature branch into a single commit.

Usually, the squashed commit message will be a summary of all the changes in the feature branch. And links to the original pull request.

This operation is very useful when you have a lot of small commits in your feature branch. And you want to keep the main branch clean.

Merge is another operation that combines changes from different branches.

It will create a new commit that combines the changes from the source branch to the target branch.

For example, suppose we have commits A, B, and C in the main branch.

And we have commits A', B', and C' in the feature branch.

After merging the feature branch into the main branch, we will have a new commit M that combines the changes from both branches.

The benefit of merge is that it preserves the history of both branches.

Which also means users can see the complete history of the changes. And it is easier to track down the changes.

However, in a large project, the commit history can be very messy.

It is almost impossible to track down the changes in the commit history.

And that's why rebase is preferred in most open source projects.

In GitHub, you can also add branch protection rules to require a linear commit history.

Which will prevent users from merging the feature branch if it has a messy commit history.

Best Practices

  1. Work on a Feature Branch: Always work on a feature branch and create a pull request to merge your changes. Avoid pushing directly to the main branch.

  2. Limit Pull Request Size: Each pull request should not exceed 500 lines of changes. If it does, consider splitting it into smaller, more manageable pull requests.

  3. Commit and Merge Frequently: Commit your changes often and merge frequently to minimize the risk of conflicts.

  4. Use Conventional Commits: Write meaningful commit messages following the Conventional Commits standard, such as:

  • feat: add new feature
  • fix: resolve bug
  1. Prefer Rebase Over Merge: Rebase helps maintain a clean and linear commit history. Use it whenever possible, especially for integrating changes from main into your feature branch.

Was this page helpful?