Skip to main content
Version: ACS CC

Git & GitHub

Here, we will cover the essential steps to install Git, set up your GitHub account, and manage your first project. Git is a Version Control System for tracking changes in your code, and GitHub is a cloud platform for hosting and collaborating on your Git projects.

Resources

  1. Pro Git book
  2. Git documentation
  3. Github documentation

Prerequisites

You'll need two things to get started: the Git software on your computer and a GitHub account.

Install Git

Follow the steps for your operating system to install the Git command-line tools.

You can install Git using your distribution's package manager.

sudo apt-get update
sudo apt-get install git

After installing, open your terminal (or Git Bash on Windows) and run git --version. If it was installed correctly, you should see an output similar to this:

git version 2.34.1

Create a GitHub Account

If you don't already have one, go to GitHub official website and sign up for a free account. This will be where you'll host your remote repositories.

First-Time Configuration

Before you make your first commit, you need to tell Git who you are. This information will be attached to every commit you create.

Run these two commands in your terminal, replacing the dummy text with your own name and email.

git config --global user.name "Your Name"
git config --global user.email "you@example.com"
info

Use the same email address you used to sign up for GitHub. This links your commits to your GitHub profile.

Setting Up an SSH Key

When you clone, push, or pull, you need to authenticate with GitHub. You can use HTTPS (which prompts for your username and password/token) or SSH.

SSH keys are a more secure and convenient way to authenticate. You generate a "key pair" (a private key that stays on your computer and a public key you give to GitHub). GitHub can then verify your identity without you ever typing a password.

Check for Existing Keys

First, check if you already have an SSH key pair.

ls -al ~/.ssh
info

If you see files named id_rsa and id_rsa.pub, or id_ed25519 and id_ed25519.pub, you can skip this part.

Generate a New SSH Key

If you don't have a key, generate a new one. Ed25519 is the recommended algorithm.

ssh-keygen -t ed25519 -C "your_email@example.com"
info
  • When prompted to "Enter a file in which to save the key," press Enter to accept the default location.

  • You'll be asked to "Enter passphrase." This is an optional password for your key itself. It adds another layer of security. Pressing Enter skips it.

Add Your SSH Key to GitHub

Now you need to give your public key (.pub file) to GitHub.

  1. Copy the key to your clipboard.

  2. Go to GitHub:

    • Click your profile picture in the top-right corner and go to Settings.
    • In the "Access" menu on the left, click SSH and GPG keys.
    • Click the New SSH key button.
    • Give it a Title (e.g., "My laptop").
    • Paste your copied key into the "Key" field.
    • Click Add SSH key.

Test Your Connection

Run the following command in your terminal:

ssh -T git@github.com

You may see a warning about the authenticity of the host that looks something like this:

The authenticity of host 'github.com (140.82.113.3)' can't be established.
ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

You may see a warning about the authenticity of the host. Type yes. If everything worked, you'll see a message like: Hi YourUsername! You've successfully authenticated...

From now on, when you clone a repository, make sure to use the SSH URL, not the HTTPS one. git@github.com:YourUsername/existing-project.git

The Basic Git Workflow

This is the core loop you'll use most of the time. We'll cover two main scenarios: creating a new project and working on an existing one.

Creating a New Project (Local-First)

Use this when you're starting a brand-new project on your computer.

Initialize a Repository

First, create a folder for your project, cd into it, and then run git init.

# Create a new directory and move into it
mkdir my-first-project
cd my-first-project

# Tell Git to start tracking this folder
git init

This creates a hidden .git folder in your directory. This is where Git stores all its tracking information.

The Add & Commit Loop

This is how you create "save points".

  1. Create a file. Let's make a README.md file.
echo "Hello, Git!" > README.md
  1. Check the status. Run git status to see what Git knows about.
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md

Git sees the new file but isn't tracking it yet (it's "untracked").

  1. Stage your changes. Before you commit, you must "stage" your changes. This is like putting files in a box to be saved. Use git add to stage them.
# Stage the README.md file
git add README.md
note

What is the "Staging Area"?

  1. Working Directory: Your actual project folder where you edit files.
  2. Staging Area (or "Index"): An intermediate area. When you git add a file, you are not saving it yet. You are simply adding a "snapshot" of that file (as it is right now) to the staging area.
  3. Repository (.git folder): The permanent history of commits.
tip

To remove a file from the staging area (the opposite of git add), you can run:

git reset HEAD <file>

This removes the file from the Staging Area but leaves your changes in your Working Directory, so you haven't lost any work.

  1. Commit your changes. Now, you "commit" (save) everything currently in the staging area.
git commit -m "Initial commit: Add README file"
info

A commit requires a message (using the -m flag) to describe the change.

You've just made your first commit! You can see your project's history by running git log.

note

What does a commit do?

Think of a commit as taking a permanent snapshot of your project at a specific moment in time

  • Permanent Storage: It takes the prepared files from the Staging Area and permanently stores that exact snapshot in the Repository (.git folder).
  • A Point in History: Git assigns a unique identifier (a "hash") to this snapshot, allowing you to go back to this exact state later if you make a mistake.
  • Documentation: The message you include creates a logbook of why changes were made, making it easier for you and your teammates to understand the project's evolution.

Working on an Existing Project (Remote-First)

This is the most common scenario. You're joining a project that already exists on GitHub.

Clone the Repository

You "clone" the remote repository, which downloads a full copy of the project and its Git history to your computer.

  1. Go to the project's page on GitHub.
  2. Click the green < > Code button.
  3. Copy the SSH URL (if you set up an SSH key) or the HTTPS URL.
  4. Run git clone [URL] in your terminal.
# Use the SSH URL (recommended)
git clone git@github.com:YourUsername/existing-project.git

# Or, use the HTTPS URL
git clone https://github.com/YourUsername/existing-project.git

# This creates a folder named 'existing-project', so move into it
cd existing-project
info

This automatically sets up the connection to the remote repository (which Git calls origin).

Working with GitHub

Now let's connect your local commits to the GitHub.

Create a Remote Repository on GitHub

If you started from a local repository, your project exists only locally. You need to create a matching empty repository on GitHub.4

  1. On GitHub, click the + icon in the top-right and select New repository.
  2. Give it the same name as your local folder (e.g., my-first-project).
  3. Do NOT check "Add a README file," "Add .gitignore," or "Choose a license." We want an empty project, since we already have our own files.
  4. Click Create repository.

Connect and Push Your Commits

Before we link everything together, it helps to understand exactly where your code lives right now.

note

Local vs. Remote Repositories

  • Local: This is the repository sitting right on your own computer. All the git add and git commit commands you've run so far have only saved changes locally. If your computer were to break right now, that project history would be lost.
  • Remote: This is a version of your project hosted securely on the internet (like on GitHub). It acts as a backup and a central hub. When you want to share your work or collaborate with teammates, you upload (or "push") your local commits to this remote repository.

GitHub will now show you a page with some commands. We want the "push an existing repository from the command line" section.

  1. Add the remote. This tells your local repo where origin (GitHub) is. Copy the command from GitHub (use the SSH version if you set it up).
# For SSH
git remote add origin git@github.com:YourUsername/my-first-project.git
# For HTTPS
# git remote add origin https://github.com/YourUsername/my-first-project.git
  1. Rename your branch. By default, Git might call your main branch master. GitHub's standard is main. Let's rename it.
git branch -M main
  1. Push your code. "Push" means "upload" your local commits to the origin remote's main branch.
git push -u origin main
info

The -u flag sets the "upstream" tracking. You only need to do this once per branch.

warning

If you used HTTPS, you'll be prompted for your GitHub username and password/token!

Now, refresh your GitHub page. You'll see your README.md file is there!

Pulling and Pushing Changes

Now that your local and remote repos are connected, your new workflow looks like this:

  1. Pull Changes (Fetch & Merge): Before you start working, always get the latest changes from the remote.
# Fetches changes from 'origin' and merges them into your current branch
git pull
info

If you're working with a team, do this often!

  1. Add & Commit: Make your local changes as normal.
echo "Another line" >> README.md
git add README.md
git commit -m "Update README"
  1. Push Changes: Upload your new commits to GitHub.
# Since we already set the upstream with -u, we can just run:
git push

Branching, Merging, and Rebasing

This is the real power of Git, allowing for collaboration and safe development.

The main branch should always contain stable, working code. You should never work directly on main. Instead, you create a branch to work on your new feature.

Branching: Working in Parallel

A branch is a lightweight movable pointer to one of your commits. When you create a branch, you're creating a new, independent timeline of commits.

  1. Create and switch to a new branch: The most common workflow is to create a new branch and immediately switch to it. The -b flag does both.
# Make sure you are on main and it's up to date
git checkout main
git pull

# Create a new branch named 'my-new-feature' and switch to it
git checkout -b my-new-feature
info

This is a shortcut for git branch my-new-feature followed by git checkout my-new-feature.

  1. Do your work: Now, you are on the my-new-feature branch. You can add and commit changes here as much as you want. Your main branch will remain untouched and stable.
# ... edit some files ...
git add .
git commit -m "Implement amazing new feature"
  1. Push your branch to GitHub: The first time you push a new branch, you need to set its upstream.
git push -u origin my-new-feature

Merging: Combining Your Work

Once your feature is complete and tested, you'll want to combine it back into the main branch. This is called merging.

A merge takes the changes from your feature branch and integrates them into main, creating a special merge commit that ties the two histories together.

# 1. Switch back to the main branch
git checkout main

# 2. Make sure main is up-to-date with the remote
git pull origin main

# 3. Merge your feature branch into main
git merge my-new-feature

Your main branch now contains all the work from my-new-feature.

note

If you and another person both changed the exact same lines in the exact same file (one on main, one on your branch), Git won't know which change to keep. This is a merge conflict.

Git will stop the merge and mark the file(s) as "conflicted." You must manually open the file, delete the lines you don't want, and save the correct version. Then, you git add the fixed file and run git commit to finalize the merge.

Rebasing: An Alternative to Merging

Rebasing is the other primary method for integrating changes from one branch to another. While a merge creates a new "merge commit" that ties two commit histories together, rebase achieves integration by rewriting your branch's history.

How to rebase: Let's say main has new commits since you started your branch. You want to "catch up" to main before you merge.

# 1. Switch to your feature branch
git checkout my-new-feature

# 2. "Rebase" your branch on top of main
git rebase main

Git will "rewind" your branch, pull in the latest changes from main, and then "replay" your commits one by one on top. You may have to solve conflicts, but you do it for each commit, one at a time.

Your feature branch now looks like it was started from the very latest version of main. Now, merging it is simple:

git checkout main
git merge my-new-feature # This will be a "fast-forward" merge, no merge commit
warning

Never rebase a branch that other people are using (like main or any shared branch).

Rebasing rewrites history (it changes the commit IDs). If you rebase a shared branch, you are changing the "truth" of the project, and it will cause massive problems for everyone else who tries to pull or push.

Only rebase your own local branches that nobody else is working on.

Undoing commits

While rebase is for replaying history, git reset is for erasing it. It is a powerful command that moves the HEAD pointer (a symbolic reference to the branch you’re currently on) to a different commit, and optionally, modifies your Staging Area and Working Directory.

git reset has three primary modes:

  • --soft: Moves HEAD only. The Staging Area and Working Directory are untouched.
  • --mixed (default): Moves HEAD and resets the Staging Area. The Working Directory is untouched.
  • --hard: Moves HEAD, resets the Staging Area, and resets the Working Directory.

Let's say we just make two commits, C3 and C4 and we want to undo them.

Our history looks like this: C1---C2---C3---C4 <-- my-feature (HEAD)

You want to go back to commit C2. You can specify the target commit by its hash or, more commonly, relative to HEAD. HEAD~2 means "two commits before HEAD."

# This will move the my-feature branch pointer back to C2
git reset HEAD~2

Now, the results will depend on what option we choose:

git reset --soft HEAD~2
  • HEAD: The branch pointer moves to C2.
  • Staging Area: Unchanged. It still contains the changes from C4.
  • Working Directory: Unchanged. Your files are exactly as they were at C4.

Result: All your changes from C3 and C4 are now staged and ready to be re-committed as a single, new commit. This is great for squashing local commits.

warning

Never use git reset --hard on a branch that has been pushed and shared with others, because it rewrites public history and removes commits!

Forking: Contributing to Other Projects

So far, we've discussed working on repositories you own or have explicit permission to modify. But what if you want to contribute to an open-source project, or a repository where you don't have "write" access? That's where forking comes in.

A fork is a personal copy of someone else's project that lives entirely on your own GitHub account.

note

What is the difference between Cloning and Forking?

  • Cloning downloads a repository directly to your local computer. If you don't have permission to the original GitHub repo, you won't be able to git push your changes back up.
  • Forking creates a copy of the repository on GitHub's servers under your account. Because you own this copy, you have full permission to push changes to it.

The Forking Workflow

Here is the standard process for contributing to a project using a fork:

  1. Fork the Repository:

    • Go to the GitHub page of the project you want to contribute to.
    • Click the Fork button in the top-right corner.
    • Select your account as the destination. You now have a complete copy of the project at github.com/YourUsername/the-project.
  2. Clone Your Fork - Now, bring your personal copy down to your local computer to work on it.

  3. Add the "Upstream" Remote - Your local project knows about your fork on GitHub (which it calls origin). However, it also needs a connection to the original repository so you can pull in new updates that the maintainers make while you're working. We typically call this original remote upstream.

# Add the original repository as a remote named 'upstream'
git remote add upstream git@github.com:OriginalOwner/the-project.git

# Verify your remotes (you should see both origin and upstream)
git remote -v
  1. Syncing with Upstream - Before starting new work, always ensure your local copy is caught up with the original project.
# Fetch the latest changes from the original repo
git fetch upstream

# Make sure you are on your local main branch
git checkout main

# Merge the upstream changes into your local main branch
git merge upstream/main
  1. Make Changes and Push
  2. Open a Pull Request - Go to your fork's page on GitHub. You'll see a prompt suggesting you open a "Pull Request." This time, the PR will propose merging the code from your fork's branch into the original repository's main branch. Once submitted, the project maintainers can review your code, request changes, and ultimately merge your contribution!

Pull Requests: The GitHub Workflow

In a team, you almost never merge directly on your own computer. Instead, you use Pull Requests (PRs) on GitHub.

A Pull Request is a formal request to merge your branch into another (e.g., merge my-new-feature into main).

  1. Push your feature branch to GitHub.
git push -u origin my-new-feature
danger

To overwrite the remote history with your new, rewritten local history, you must use a force push.

git push --force origin my-feature

You should ONLY force push to a feature branch that you and only you are working on.

A much safer (and highly recommended) alternative is git push --force-with-lease:

git push --force-with-lease origin my-feature

This command will only push if nobody else has updated the remote.

  1. Go to GitHub. You will see a green button to "Compare & pull request." Click it.
  2. Fill out the PR: Give it a title and a description of your changes. This is where you can tag teammates for a code review.
  3. Discuss and Review: Your team can now look at your changes, leave comments, and request fixes.
  4. Merge: Once approved, a team member (or you) can click the green "Merge" button on the GitHub website. This performs the merge on the remote and keeps a record of the discussion.
info

This workflow (Branch -> Push -> Pull Request -> Review -> Merge) is the foundation of modern software collaboration.