Git and GitHub guide from Beginner to expert [Tutorial]

Git branching model, showing the flow of code from development to production.

Git is a powerful version control system (VCS) that helps developers track changes in their code, collaborate with others, and maintain a clean project history. Whether you’re a beginner just starting out or looking to refine your expertise, this tutorial will guide you through Git’s essential features and advanced functionalities.

What is a VCS?

A Version Control System (VCS) helps manage changes to files over time, enabling collaboration and version tracking.

A comparison of centralized and distributed version control systems. The centralized system has a single server repository, while the distributed system has multiple repositories.
Figur 01: Centralized version control system vs Distributed version control system
  • Centralized VCS uses a single central repository, where developers check out files, make changes, and commit them back to the server. This setup is straightforward but relies heavily on the central server, creating a single point of failure.
  • Decentralized (Distributed) VCS, like Git, gives each developer a full copy of the repository, allowing them to work independently and commit changes locally. This system is more resilient and flexible, as it doesn’t depend on a central server.

Git is a widely used distributed VCS that supports robust and flexible workflows, enabling developers to work offline and synchronize their work efficiently.

1. Introduction to Git

Before Git, how manual repositories were maintained.
Figure 02: Before Git, version control relied on manual file naming and directory structures to track changes.

Before version control systems like Git, managing project versions often involved manually creating multiple copies of files with names like “copy 1,” “copy 2,” “final final,” etc. This method made merging changes from different team members chaotic and time-consuming.

What is Git?

Git is a distributed version control system allowing multiple developers to work on the same project without overwriting each other’s changes. It also tracks changes to files, enabling developers to revert to previous versions if needed.

Git has following features.

  • Free, open-source
  • Version Control: Track every change made to your project.
    • Handle small files very effectively
    • Tracks contents, not files
  • Collaboration: Work on the same project simultaneously with others.
  • Easy and efficient Backup: Keep a history of all your changes, making it easy to revert to a previous state.
  • Branching: Experiment with new features without affecting the main codebase.

Installing Git to your system.

To start using Git, you’ll need to install it on your system.
  • Install git
    • Linux: Install via your package manager,

 

  • After installation, configure Git with your name and email:

2. Getting Started with Git

Initializing a Repository

To start tracking a project with Git, navigate to your project directory and initialize a new repository:

This command creates a “.git” directory that contains all the necessary files for version control. The .git directory is crucial as it tracks changes in your project, moving files through Git’s three stages:
  • Working Directory: This is where you work on your project files. Changes made here are not yet tracked by Git.
  • Staging Area: Also known as the index, this is where you place changes you intend to include in your next commit. Files are added to this area using the git add command.
  • Repository: This is where Git stores all the project’s history and metadata. It’s the heart of the Git system, containing all committed snapshots.
Git workflow, showing the three main areas: working directory, staging area, and repository.
Figure 03: Git three stages working directory, staging area and Repository

Configuring .gitignore

Define files and directories that Git should ignore by listing them in a .gitignore file at the root of your repository:

Files and directories matching these patterns will not be tracked by Git.

3. Basic Git Workflow

The basic Git workflow involves the following steps:

(I)  Staging Changes: Add files to the staging area using

      a. git add:

      b. or stage all changes:

(II)  Committing Changes: Commit the staged changes with a descriptive message:

Conventional Commits structure

<type>[optional scope]: <description>
[optional body]
[optional footer(s)]

  • Focus on one change per commit.
  • Write a clear and descriptive message.
  • Keep the subject line concise (50 chars or less).
  • type examples:
    • feat – a new feature is introduced with the changes.
    • fix – a bug fix has occurred.
    • chore – changes that do not relate to a fix or feature.
    • refactor – refactored code that neither fixes a bug nor adds a feature.
    • docs – updates to documentation such as the README or other markdown files.
    • style – changes that do not affect the meaning of the code, related to code formatting.
    • perf – performance improvements.
    • ci – continuous integration related..
    • build – changes that. affect the build system or external dependencies.
    • revert – reverts a previous commit.

(III) Viewing the Status & Monitoring:

    a. Check the status of your working directory and staging area (Monitoring tool for your changes):
    b. Comparing Changes: View differences between versions to see what has changed since the last commit:
    • i. To see all changes in tracked files:
    • ii. To see changes in a specific file:
      • (Note: git diff can also show differences between arbitrary revisions.)
  •  
      • c. Viewing Commit History: Review the commit history on your current branch:
        • i. To see the full history:
      • ii. To see the last few commits, e.g., the last three commits:

    Understanding What is a Commit

    A commit is a snapshot of your repository at a specific point in time. Each commit has a unique SHA-1 hash and can be referenced at any time. The commit history forms the backbone of your project’s timeline.

    Branching and Merging – locally

    What Are Branches?

    Branches are pointers to a specific commit. The main branch (or master in older repositories) is the default branch, but you can create other branches to work on features or fixes independently.

    Creating, switching between Branches and merging branches

    Combined create and switching most common way:

    Or
      1. Create a new branch with:
      • 2. Switch to it using:

    Merging Branches

    Once your work is complete, you can merge it back into the main branch:

    Resolving Merge Conflicts

    Conflicts occur when changes in two branches overlap. Git pauses the merge process and marks the conflicting files. To resolve:

    1. Edit the Conflicted Files Manually: Open the conflicting files in an editor like VS Code. Git will highlight the conflicting sections, usually with <<<<<<<, =======, and >>>>>>> markers showing the different changes.

    2. Mark Them as Resolved: Once you’ve manually edited and resolved the conflicts, stage the resolved files:

    3. Complete the merge:

    Resolving example with VS Code:

    When you open a conflicted file in an IDE like VS Code, the editor visually separates the conflicting changes, making it easier to choose which version to keep or to merge the changes manually. After resolving, save the file, then use the above Git commands to finish the process.

    General flow Git diagram:

    Git branching model. The diagram shows the flow of changes between different branches.
    Figure 04: Using feature branches development branch and releases

    Generally, feature branches are used to develop new features or fixes in isolation from the main codebase, allowing multiple features to be worked on simultaneously without interfering with each other. The development branch (develop) serves as an integration branch where completed features are merged and tested together before being deemed stable. Once a set of features is ready and thoroughly tested, the code is merged into the main branch (main or master) and tagged with a release version, signifying a stable and deployable state of the software. This workflow ensures organized development, facilitates parallel work, and maintains a clear and stable release history.

    4. Working with a Remote Repository (GitHub, GitLab, etc.)

    To clone an existing repository from a remote server:

    Add a remote repository:

    List all remotes:

    Git push and pull commands.
    Figure 05: Remote Git and pull push and commit

    Pushing and Pulling Changes

    • Push your changes to a remote repository:
    • Pull changes from the remote repository:

    5. Advanced Git Techniques

    Rebasing vs. Merging

    Rebase replays your branch’s commits onto another branch’s tip, providing a cleaner history:

    Use merge to preserve the full history:

    Interactive Rebase

    Interactive rebase allows you to edit, combine, or reorder commits:

    Cherry-Picking Commits

    Cherry-picking allows you to apply specific commits from one branch to another:

    Stashing Changes

    Stash your changes temporarily without committing:

    Apply the stash later:

    Creating Patches with Git

    Suppose you’ve made some commits and want to create a patch of those changes. You would navigate to your project directory and run:

    This will generate a single patch file called fix. patch that contains all the changes from your recent commits. You can then share this patch file with others, or use it to apply the changes in another repository using the git apply command. With sent patch file named fix.patch, you can apply those changes to your project,

    This method is especially useful when you need to share specific changes with others without pushing to a shared repository.

    6. Collaborating with Others

    Forking and Pull Requests

    Fork a repository to your account, make changes, and submit a pull request to propose your changes to the original project.

    Code Reviews

    Code reviews are essential for maintaining quality. Reviewers can comment on your pull request, suggest changes, and approve it.

    Best Practices for Collaboration

    • Write meaningful commit messages.
    • Keep your branches up-to-date with main.
    • Squash commits to keep history clean.

    7. Git history commit management– advanced tools

    Reverting and Resetting Commits:

    Create a new commit that undoes the changes from a specific commit:

    This command generates a new commit that applies the inverse of the specified commit’s changes, preserving the project history.

    Reset a branch to a specific commit (destructive):

    This command changes the branch’s history and working directory to match the specified commit, discarding all changes and commits made after that point.

    Amending Commits

    Amend the last commit:

    This command allows you to edit the last commit and add additional changes or modify the commit message.

    Squashing Commits

    Squash multiple commits into one using interactive rebase:

    This command opens an interactive rebase interface where you can choose which commits to squash, edit, or reorder. Select the commits to squash into one and save the changes to streamline the commit history.

    8. Advanced Configuration and Optimization

    Git Aliases

    Create shortcuts for common Git commands is a handy way to save time:

    Using Hooks for Automation

    Git hooks allow you to automate tasks. For example, run tests before committing with a pre-commit hook. Place a script in .git/hooks/pre-commit.

    Performance Optimization Tips

    • Use shallow clones for large repositories:
    • Clean up unnecessary files and optimize your repository:

    This tutorial has covered a wide range of Git functionalities, from the basics to more advanced techniques. By mastering these tools, you’ll be well-equipped to handle any version control challenges that come your way. Happy coding!