Programming ยท ยท 8 min read

Comprehensive Git and GitHub Tutorial

Comprehensive Git and GitHub Tutorial
Git & GitHub - A Comprehensive Tutorial

What is Git?

Git is a distributed version control system that has become essential for software engineers and developers worldwide. It allows you to track changes in your codebase, collaborate with others, and maintain different versions of your project.

Key benefits of using Git:

  1. Version Control: Keep track of all changes made to your code over time.
  2. Collaboration: Easily work with others on the same project without conflicts.
  3. Branching: Create separate lines of development for new features or experiments.
  4. Backup: Store your code securely on remote servers.
  5. Open Source: Contribute to and benefit from the vast ecosystem of open-source projects.

Real-world example: Imagine you're working on a web application. You want to add a new feature, but you're not sure if it will work well. With Git, you can:

  1. Create a new branch for the feature
  2. Develop and test the feature without affecting the main codebase
  3. If it works, merge it back into the main branch
  4. If it doesn't, discard the branch without any impact on your stable code

This workflow allows for safe experimentation and easy collaboration with team members.

Installing Git

Windows

  1. Download the installer from the official Git website.
  2. Run the installer and follow the installation wizard.

Open Command Prompt or Git Bash to verify the installation:

git --version

macOS

Verify the installation:

git --version

Install Git using Homebrew:

brew install git

Install Homebrew if you haven't already:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Linux (Ubuntu/Debian)

Verify the installation:

git --version

Install Git:

sudo apt install git

Open Terminal and update your package index:

sudo apt update

After installation, configure your Git identity:

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

Basic Git Commands

Git Init

To initialize a new Git repository in your project directory:

cd /path/to/your/project
git init

This creates a new .git subdirectory in your project folder, which contains all the necessary metadata for the repository.

Example scenario:

mkdir my_new_project
cd my_new_project
git init
echo "# My New Project" > README.md
git add README.md
git commit -m "Initial commit: Add README"

Git Status

To check the status of your repository:

git status

This command shows you which files have been modified, which are staged for commit, and which are untracked.

Example output:

On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   src/main.py

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        docs/

Git Add

To stage changes for commit:

# Stage a specific file
git add filename.txt

# Stage all changed files
git add .

# Stage all files with a specific extension
git add *.js

# Interactively stage parts of files
git add -p

The -p option allows you to interactively choose which changes to stage, which is useful for creating clean, logical commits.

Git Commit

To commit your staged changes:

git commit -m "Your descriptive commit message"

For more detailed commit messages, omit the -m flag to open your default text editor:

git commit

Best practices for commit messages:

  • Keep the subject line concise (ideally under 50 characters)
  • Use the imperative mood (e.g., "Fix bug" instead of "Fixed bug")
  • Describe what was changed and why
  • Separate subject from body with a blank line
  • Wrap the body at 72 characters

Example of a good commit message:

Implement user authentication

- Add login and registration forms
- Set up JWT token-based authentication
- Create protected routes for authenticated users
- Update tests to cover new authentication flow

Closes #123

Working with Remote Repositories

Git Remote

To connect your local repository to a remote GitHub repository:

git remote add origin https://github.com/username/repository.git

To view your remote repositories:

git remote -v

To change the URL of an existing remote:

git remote set-url origin https://github.com/new-username/new-repository.git

Git Push

To upload your local commits to GitHub:

git push -u origin main

The -u flag sets up tracking, so you can simply use git push in the future.

For force pushing (use with caution):

git push --force origin feature-branch

Git Pull

To fetch and merge changes from the remote repository:

git pull origin main

This is equivalent to running git fetch followed by git merge.

To pull changes with rebasing instead of merging:

git pull --rebase origin main

Git Clone

To download a remote repository to your local machine:

git clone https://github.com/username/repository.git

To clone a specific branch:

git clone -b feature-branch https://github.com/username/repository.git

To clone with a different name for the local directory:

git clone https://github.com/username/repository.git custom-directory-name

Branching and Merging

Git Branch

To create a new branch:

git branch feature-branch

To list all branches:

git branch

To list all remote branches:

git branch -r

To delete a branch:

git branch -d feature-branch

Git Checkout

To switch to a different branch:

git checkout feature-branch

To create and switch to a new branch in one command:

git checkout -b new-feature-branch

To discard changes in a file and restore it to the last committed state:

git checkout -- filename.txt

Git Merge

To merge changes from one branch into another:

git checkout main
git merge feature-branch

For a non-fast-forward merge with a commit message:

git merge --no-ff -m "Merge feature-branch into main" feature-branch

Resolving Merge Conflicts

When Git can't automatically merge changes, you'll need to resolve conflicts manually:

  1. Open the conflicting file(s) in your text editor.
  2. Look for conflict markers (<<<<<<<, =======, >>>>>>>).
  3. Edit the file to resolve the conflict.
  4. Remove the conflict markers.

Complete the merge:

git commit -m "Resolve merge conflict between feature-branch and main"

Stage the resolved file:

git add resolved-file.txt

An example of a conflict in app.py:

<<<<<<< HEAD
def greeting():
    return "Hello, World!"
=======
def greeting(name):
    return f"Hello, {name}!"
>>>>>>> feature-branch

To resolve this, you might choose to keep the feature branch version:

def greeting(name):
    return f"Hello, {name}!"

Then stage and commit the resolved file.

GitHub Features

Forking

Forking creates a personal copy of someone else's project on GitHub. To fork a repository:

  1. Navigate to the repository on GitHub.
  2. Click the "Fork" button in the top-right corner.

Use cases for forking:

  • Contributing to open-source projects
  • Using someone's project as a starting point for your own
  • Proposing changes to someone else's project

Pull Requests

To submit a pull request (PR) on GitHub:

  1. Create a new branch with your changes.
  2. Push the branch to your forked repository.
  3. Navigate to the original repository on GitHub.
  4. Click "Pull requests" > "New pull request".
  5. Select your fork and the branch containing your changes.
  6. Fill out the PR description and create the pull request.

Best practices for PRs:

  • Keep them small and focused on a single issue or feature
  • Provide a clear description of the changes and their purpose
  • Reference any related issues
  • Include tests for your changes
  • Be responsive to feedback and make requested changes promptly

GitHub Codespaces

GitHub Codespaces provides a cloud-powered development environment:

  1. Navigate to your repository on GitHub.
  2. Click the "Code" button.
  3. Select "Open with Codespaces".
  4. Click "New codespace" to create a new environment.

Benefits of Codespaces:

  • Consistent development environment across team members
  • Quick setup for new contributors
  • Access your development environment from any device with a web browser
  • Seamless integration with GitHub features

Undoing Changes

Git Reset

To undo staged changes:

git reset HEAD filename.txt

To undo commits:

# Soft reset (keep changes, unstage commits)
git reset --soft HEAD~1

# Mixed reset (keep changes, unstage commits and modified files)
git reset --mixed HEAD~2

# Hard reset (discard changes and commits)
git reset --hard HEAD~3

Example scenario: You've made three commits but realize the last two were a mistake.

# View the commit history
git log --oneline

# Reset to the desired commit, keeping the changes in your working directory
git reset --mixed HEAD~2

# Make changes and create a new commit
git add .
git commit -m "Combine previous work into a single, correct commit"

Git Revert

To create a new commit that undoes a previous commit:

git revert commit-hash

Example:

# View commit history
git log --oneline

# Revert a specific commit
git revert abc1234

# Push the revert commit
git push origin main

Git Commit --amend

To update the last commit message:

git commit --amend -m "New commit message"

To add files to the last commit:

git add forgotten-file.txt
git commit --amend --no-edit

Note: Avoid amending commits that have already been pushed to a shared repository, as it can cause conflicts for other contributors.

Advanced Git Techniques