{"id":24054701,"url":"https://github.com/rnaveensrinivas/git","last_synced_at":"2026-04-16T02:31:45.234Z","repository":{"id":268314235,"uuid":"900276760","full_name":"rnaveensrinivas/git","owner":"rnaveensrinivas","description":"A repository to explore and learn Git commands and version control concepts.","archived":false,"fork":false,"pushed_at":"2025-02-12T06:22:41.000Z","size":24283,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"progit","last_synced_at":"2025-02-26T10:46:28.236Z","etag":null,"topics":["distributed-version-control","git","github","version-control"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rnaveensrinivas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-08T11:11:50.000Z","updated_at":"2025-02-12T06:22:44.000Z","dependencies_parsed_at":"2024-12-16T01:31:15.247Z","dependency_job_id":"f811a801-f7e9-40d3-8790-fb84569384e7","html_url":"https://github.com/rnaveensrinivas/git","commit_stats":null,"previous_names":["rnaveensrinivas/git"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rnaveensrinivas/git","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rnaveensrinivas%2Fgit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rnaveensrinivas%2Fgit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rnaveensrinivas%2Fgit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rnaveensrinivas%2Fgit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rnaveensrinivas","download_url":"https://codeload.github.com/rnaveensrinivas/git/tar.gz/refs/heads/progit","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rnaveensrinivas%2Fgit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31868492,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T15:24:51.572Z","status":"online","status_checked_at":"2026-04-16T02:00:06.042Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["distributed-version-control","git","github","version-control"],"created_at":"2025-01-09T03:49:36.013Z","updated_at":"2026-04-16T02:31:45.204Z","avatar_url":"https://github.com/rnaveensrinivas.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Table of contents\n\n* [Introduction](#Introduction)\n  * [What is Git?](#what-is-git)\n  * [Introduction to Version Control](#introduction-to-version-control)\n  * [Centralized vs. Distributed Version Control](#centralized-vs-distributed-version-control)\n  * [Design Philosophy of Git](#design-philosophy-of-git)\n* [Git Components](#git-components)\n* [Getting Started](#getting-started)\n  * [install Git](#install-git)\n  * [Set Up SSH for GitHub](#set-up-ssh-for-github)\n  * [Test Your SSH Connection](#test-your-ssh-connection)\n  * [Set SSH as Default for All Repositories](#set-ssh-as-default-for-all-repositories)\n  * [Configure Git](#configure-git)\n  * [**Summary**](#summary-of-git-configuration-commands)\n* [initializing Repositories](#initializing-repositories)\n  * [Cloning an Existing Repository](#cloning-an-existing-repository)\n  * [Optional: Swithcing to use SSH Instead of HTTPS](#optional-swtiching-to-use-ssh-instead-of-https-for-cloned-repositories)\n  * [**Summary**](#summary-of-git-initialization-commands)\n* [Recording Changes](#recording-changes)\n  * [Git Snapshots](#git-snapshots)\n  * [Staging Area](#the-staging-area-also-called-index)\n  * [Commits](#commits)\n  * [Tagging Commits](#tagging-commits)\n  * [**Summary**](#summary-of-recording-changes-commands)\n* [Undoing Changes](#undoing-changes)\n  * [Undoing Changes in Working Directory](#undoing-changes-in-the-working-directory)\n  * [Undoing changes in Staging Area](#undoing-in-the-staging-area)\n  * [Undoing Commits](#undoing-commits)\n  * [Amending Commits](#amending-commits)\n  * [**Summary**](#summary-of-undoing-changes)\n* [Branches](#branches)\n  * [Manipulating Branches](#manipulating-branches)\n  * [Merging Branches](#merging-branches)\n  * [Rebasing](#rebasing)\n  * [**Summary**](#summary-of-branches)\n* [Branching Workflows](#branching-workflows)\n  * [Types of Branches](#types-of-branches)\n    * [Permanent Branches](#permanent-branches)\n    * [Topic Branches](#topic-branches)\n  * [Sample Workflow](#sample-workflow)\n  * [Branching Workflow Flexibility](#branching-workflow-flexibility)\n  * [**Summary**](#summary-of-key-points) \n* [Remote Repositories](#remote-repositories)\n  * [What is a Remote Repository?](#what-is-a-remote-repository)\n  * [Managing Remote Repository](#managing-remote-repositories)\n  * [Working with Remote Branches](#working-with-remote-branches)\n  * [Integrating changes from Remote Repositories](#integrating-changes-from-remote-branches)\n  * [Pushing Changes to Remote Repositories](#pushing-changes-to-remote-repositories)\n  * [**Summary**](#summary-of-remote-repositories)\n* [Remote Workflows](#remote-workflows)\n  * [Public (Bare) Repositories](#public-bare-repositories)\n  * [The Centralized Workflows](#the-centralized-workflow)\n  * [The Integrator Workflow](#the-integrator-workflow)\n* [**Cheat Sheet**](#cheat-sheet)\n\n\n---\n\n# Introduction\n## What is Git?\n- Git is an **open-source version control system** known for its:\n  - **Speed**\n  - **Stability**\n  - **Distributed collaboration model**\n- Originally created in **2006** by *Linus Torvalds* to manage the Linux kernel.\n- Today, Git has:\n  - A **comprehensive feature set**\n  - **Active development team**\n  - Several **free hosting communities** like GitHub, GitLab, Bitbucket, etc.\n\n## Introduction to Version Control\n\n### Definition:\nVersion control is a system that **tracks changes to files over time**, enabling collaboration and version management.\n\n### Key Benefits:\n- Maintains a **history of changes**, allowing you to view or revert to earlier versions.\n- Facilitates **collaboration** by letting multiple people work on the same project simultaneously.\n- Tracks **who made what changes and when**, providing accountability.\n- Reduces risk by serving as a **backup system** for your code or files.\n\n### Types of Version Control:\n- **Local Version Control**: Stores changes on a single machine. Simple but limited for collaboration.\n- **Centralized Version Control**: Uses a central server to store files and version history (e.g., SVN, CVS).\n- **Distributed Version Control**: Each user has a complete copy of the repository (e.g., Git, Mercurial).\n\n### Common Use Cases:\n- Software development (code management).\n- Document versioning and collaborative editing.\n- Managing configuration files and scripts.\n\n### Popular Tools:\n- Git, Mercurial, Subversion (SVN), CVS.\n- Hosting services like GitHub, GitLab, and Bitbucket simplify sharing and collaboration.\n\n### Why It's Essential:\n- Helps avoid overwriting others' work.\n- Enables **parallel development**.\n- Provides a **safety net** against accidental data loss or errors.\n\n## Centralized vs. Distributed Version Control\n\n### Centralized Version Control Systems (CVCS)\n- **How It Works**:\n  - A single **central repository** stores all project files and version history.\n  - Developers pull files from the central server, make changes, and push them back.\n- **Examples**: Subversion (SVN), CVS.  \n- **Key Features**:\n  - **Single Point of Truth**: The central server holds all the data.\n  - **Network Dependency**: You need to be connected to the server for most operations.\n  - **Simple to Understand**: The workflow is straightforward for small teams.\n- **Challenges**:\n  - If the central server goes down, work halts for everyone.\n  - Limited offline capabilities.\n\n### Distributed Version Control Systems (DVCS)\n- **How It Works**:\n  - Each developer has a **complete copy** of the repository, including full version history.\n  - Changes can be made offline and shared with others by syncing repositories.\n- **Examples**: Git, Mercurial.\n- **Key Features**:\n  - **Decentralized Model**: No single point of failure since every developer has a full backup.\n  - **Offline Work**: You can commit changes, view history, and work locally without a network.\n  - **Collaboration**: Developers can push/pull changes to/from each other's repositories.\n- **Advantages**:\n  - Fast and reliable, as most operations are local.\n  - Great for large teams and open-source projects.\n\n## Design Philosophy of Git\n- Git was designed with a focus on **distributed software development**, avoiding the limitations of centralized systems like SVN (Subversion) or CVS (Concurrent Versions Systems).\n\n## Key Benefits of Git's Distributed Model\n\n1. **Faster Commands**:\n   - Since Git stores the repository locally, almost all actions are performed on the **local machine**, eliminating the need to communicate with a central server.\n   - This leads to **faster commands** and the ability to **work offline** without workflow disruption.\n\n2. **Stability**:\n   - Git's distributed nature means each collaborator has a **backup** of the entire project.\n   - This lowers the risk of **data loss** from server crashes or repository corruption, a common issue in centralized systems reliant on a single point of access.\n\n3. **Isolated Environments**:\n   - Every Git repository, whether **local or remote**, retains the **full history** of a project.\n   - Having a complete and isolated environment allows users to experiment with **new features** before integrating them into the main project.\n\n4. **Efficient Merging**:\n   - Since each developer has their own local history, their development branches may diverge.\n   - Git excels in handling **divergent histories**, making it **highly efficient** at **merging branches** and resolving conflicts between different lines of development.\n\n---\n\n# Git Components\n\n## Four Key Components of a Git Repository\n1. **The Working Directory**\n2. **The Staging Area**\n3. **Committed History**\n4. **Development Branches**\n\n---\n\n### 1. The Working Directory\n- **What It Is:**\n  - The **working directory** is where you interact with your files during development.\n  - It is where you **edit files**, **compile code**, and perform other tasks related to your project.\n  - You can treat the working directory as a **normal folder** where you directly modify the contents of the project.\n\n- **Git's Role:**\n  - The working directory gives you access to Git's features, enabling you to **record changes**, **alter** files, and **transfer** them using Git commands.\n  - Git keeps track of any changes you make in this directory before committing them to the project's history.\n\n---\n\n### 2. The Staging Area\n- **What It Is:**\n  - The **staging area** acts as an intermediary between the **working directory** and the **project history**.\n  - It allows you to **prepare and organize changes before committing** them to the history.\n\n- **Functionality:**\n  - Instead of committing all changes at once, Git allows you to **group related changes** into a **changeset**.\n  - Changes staged in this area are not part of the project's history until they are committed.\n  - This gives you control over which changes to include in your commit.\n\n---\n\n### 3. Committed History\n- **What It Is:**\n  - Once changes are staged, you can **commit** them to the project history.\n  - A **commit** records the state of the repository at a particular point in time.\n\n- **Safety of Commits:**\n  - Commits are considered \"safe\" in the sense that **Git does not alter them automatically**.\n  - However, it is possible to **manually rewrite the project history** (e.g., with rebase or amend operations).\n\n---\n\n### 4. Development Branches\n- **What They Are:**\n  - Branches allow you to **fork the project history** and develop multiple features in **parallel**. \n  - Facilitates non linear project history.\n  - A branch creates a divergent path for your work, enabling you to develop **independently** without disrupting the main project history.\n\n- **Git Branches vs. Centralized Systems:**\n  - Git branches are **lightweight**, **cheap to create**, and **simple to merge**.\n  - Unlike centralized version control systems, **Git branches** are **easy to share** and manage.\n\n- **Branching in Git:**\n  - Git branches are used for everything from **long-running** features involving multiple contributors and to quick fixes, such as **5-minute patches**.\n  - Many developers prefer to work in **dedicated topic branches**, keeping the main history branch (e.g., `main` or `master`) clean and reserved for **public releases**.\n\n---\n\n# Getting Started\n\n## Install Git and SSH\n\n### Install Git\n```bash\n$ sudo apt update\n$ sudo apt install git\n```\n\n### Install OpenSSH\nIf OpenSSH is not already installed, use the following command:\n```bash\n$ sudo apt update\n$ sudo apt install openssh-client\n```\n\n---\n\n## Set Up SSH for GitHub\n\n### Generate an SSH Key Pair\n1. Run the command in your terminal.\n    ```bash\n    $ ssh-keygen -t ed25519 -C \"your_email@example.com\"\n    ```\n   - **`ssh-keygen`**: This is the command used to generate a new SSH key pair (a private and public key).\n   - **`-t ed25519`**: Specifies the type of the key to be generated. In this case, **ED25519** is used, which is a modern, secure, and fast elliptic-curve algorithm.\n   - **`-C \"your_email@example.com\"`**: This is a comment or label that will be associated with the key. It's often an email address that helps identify the key, especially when managing multiple keys.\n2. It will prompt you to **enter a file in which to save the key**. If you just press **Enter**, it will save the key to the default location (`~/.ssh/id_ed25519`).\n3. You will be asked to **enter a passphrase** for added security (optional). If you don't want a passphrase, just press **Enter**.\n4. After that, the key pair will be generated:\n   - The **private key** is stored in the file you specified (e.g., `~/.ssh/id_ed25519`).\n   - The **public key** is stored in a corresponding file (e.g., `~/.ssh/id_ed25519.pub`).\n\n### Add the SSH Key to the SSH Agent\nStart the SSH agent:\n```bash\n$ eval $(ssh-agent -s)\n```\n* What does ```ssh-agent -s``` contain?\n  ```bash\n  $ ssh-agent -s  \n  SSH_AUTH_SOCK=/tmp/ssh-abc12345/agent.1234; export SSH_AUTH_SOCK;\n  SSH_AGENT_PID=1234; export SSH_AGENT_PID;\n  echo Agent pid 1234;\n  ```\n\nAdd your SSH **private key**:\n```bash\n$ ssh-add ~/.ssh/id_ed25519\n```\n\n### Add the SSH Key to GitHub\nCopy the **public SSH key**:\n```bash\n$ cat ~/.ssh/id_ed25519.pub\n```\nLog in to your GitHub account, navigate to **Settings \u003e SSH and GPG Keys**, and add the copied key.\n\n---\n\n## Test Your SSH Connection\nVerify the SSH connection to GitHub:\n```bash\n$ ssh -T git@github.com\n```\nIf successful, you should see:\n```\nHi \u003cusername\u003e! You've successfully authenticated, but GitHub does not provide shell access.\n```\n\n---\n\n## Set SSH as Default for All Repositories\nTo always use SSH when cloning or interacting with repositories:\n```bash\n$ git config --global url.\"git@github.com:\".insteadOf \"https://github.com/\"\n```\nThis modifies the `~/.gitconifg` file, which will look like the follow: \n```\n[url \"git@github.com:\"]\n          insteadOf = https://github.com/\n```\n\n## Configure Git\n\n### Set User Information\nSet your name and email, which will be recorded with your commits and also third-party services require them:\n```bash\n$ git config --global user.name \"Naveen Srinivas\"\n$ git config --global user.email \"tonaveensrinivas@gmail.com\"\n```\nUse the `--global` flag to apply these settings globally (modifies the `~/.gitconfig file`) or omit it for repository-specific settings.\n\n### Set Your Preferred Editor\nConfigure the default text editor for Git (e.g., VS Code):\n```bash\n$ git config --global core.editor \"code --wait\"\n```\nReplace `code --wait` with your preferred editor, like `nano` or `vim`. The `--wait` flag ensures Git waits for the editor to close before proceeding.\n\n### Create Command Aliases\nSimplify commonly used Git commands with aliases:\n```bash\n# Syntax:\n$ git config [--global] alias.\u003calias_name\u003e \"\u003ccommand\u003e\"\n\n# Examples:\n$ git config --global alias.st status\n$ git config --global alias.pu \"push -u origin main\"\n```\n\nHere is how `~/.gitconfig` file would like after executing above commands:\n```plaintext\n[user]\n\tname = Naveen Srinivas\n\temail = tonaveensrinivas@gmail.com\n[core]\n\teditor = code --wait\n[alias]\n\tst = status\n\tpu = push -u origin main\n```\n\n### Explore More Options\nRun `git help config` in the terminal to see all available configuration options.\n\n---\n\n## Summary of Git Configuration Commands\n| Command  | Description |\n|----------|-------------|\n| `git config --global user.name \"name\"`| Sets the global Git username for all repositories.|\n| `git config --global user.email \"email\"`| Sets the global Git email for all repositories.|\n| `git config --global core.editor \"editor --wait\"`| Sets the default text editor for Git commands requiring user input, like commit messages.|\n| `git config --global alias.alias_name \"command\"`| Creates a shortcut (alias) for a Git command.|\n| `git help config`| Displays help information about Git configuration options.|\n\n# Initializing Repositories\n\n## Creating a New Repository:\n  \nTo initialize a repository, run the following:\n```bash\n# Syntax\n$ git init \u003cpath\u003e\n\n# Examples\n$ git init \n$ git init ~/Documents/SampleProject\n```\nThe `\u003cpath\u003e` argument can be left blank to initialize the repository in the current directory. Git is **minimally invasive**; it only adds a `.git` directory in the root of your project folder.\n\n## Cloning an Existing Repository:\nInstead of initializing a new repository, you can **clone** an existing Git repository using ssh (preferred) or https:\n```bash\n# Syntax\n$ git clone ssh://\u003cuser\u003e@\u003chost\u003e/path/to/repo[.git]\n$ git clone https://github.com/user/repo[.git]\n\n# Examples\n$ git clone ssh://git@github.com/rnaveensrinivas/GitRepo\n$ git clone https://github.com/rnaveensrinivas/GitRepo\n```\nThis command will create a full copy of the repository, including its history, working directory, staging area, and branch structure. Changes won't be visible to others until you push them to a public repository.\n\n## Optional: Swtiching to use SSH Instead of HTTPS for Cloned Repositories\n\n### Check Your Current Remote URL\nYou must be in a repository that is associated with Github to execute the following command. If you don't have one simply create a GitHub repository and clone it in local. \n- Run the following command:\n```bash\n$ git remote -v\n```\nIf the URL starts with `https://`, then it uses HTTPS Protocol, it can be changed to use `ssh` with the following steps. \n\n### Update the Remote URL\nReplace `username/repository` with your GitHub username and repository name:\n```bash\n$ git remote set-url origin git@github.com:username/repository.git\n```\n\n### Verify the Change\nCheck the updated remote URL:\n```bash\n$ git remote -v\n```\nThe output should now display `git@github.com` instead of `https://`.\n\n### Push Changes Using SSH\nPush your changes without being prompted for a username and password:\n```bash\n$ git push\n```\n**Note**: You may have to provide ssh passphrase. \n\n### Optional: Set SSH as Default for All Repositories\n- To always use SSH when cloning or interacting with repositories:\n```bash\n$ git config --global url.\"git@github.com:\".insteadOf \"https://github.com/\"\n```\n\n## Summary of Git Initialization Commands\n| Command  | Description |\n|----------|-------------|\n| `git init`| Initializes a new Git repository in the current directory.|\n| `git init path`| Initializes a new Git repository at the specified path.|\n| `git clone ssh://\u003cuser\u003e@\u003chost\u003e/path/to/repo[.git]`| Clones a repository from a remote server using an SSH URL with user and host details.|\n| `git clone https://github.com/user/repo[.git]`| Clones a repository from GitHub or another remote server using an HTTPS URL.|\n| `git remote -v`| Displays the list of remote repositories and their URLs.|\n| `git remote url remote_name new_url`| Updates the URL for a specified remote repository.|\n\n---\n\n# Recording Changes\nVersion Control System's core job is to maintain a series of *safe* revisions of project. Git does this with the help of **snapshots**. \n\n## Git Snapshots\n- Git records **snapshots** of the entire project instead of just diffs between files (as in SVN or CVS).\n- Each **commit** in Git represents a complete snapshot of all project files at a given point in time, making Git faster and more reliable.\n- Unlike systems that record incremental changes, Git stores the full version of each file in a commit.\n  \n### Advantages:\n- Faster access to file versions.\n- Avoids the need to regenerate file states when requested.\n\n## The Staging Area (also called Index)\n\n### What is the Staging Area?\n- The **staging area** (also known as the **index**) is an intermediary between the **working directory** and the **committed history**.\n- It allows you to **stage** (select) changes for the next commit, ensuring you can commit only the desired changes and not the entire working directory at once. \n\n---\n\n### Staging Changes\n\n#### Stage File Addition\nTo stage a file or directory, use `git add`. This prepares changes to be committed.\n\n```bash\n# Syntax\n$ git add path_to_file_or_directory\n\n# Examples\n$ git add .           # Stages all changes in the current directory\n$ git add adir/       # Stages changes in the \"adir\" directory\n$ git add f1          # Stages the \"f1\" file\n```\n\n#### Stage File Deletion (Without Removing the File from the Working Directory)\nTo stage the removal of a file or directory, but keep it in the working directory, use `git rm --cached`. This removes the file from the staging area but leaves it in your local file system. \n\n**Note**: The file now becomes **untracked**. \n\n```bash\n# Syntax\n$ git rm [-r] --cached file_or_directory\n\n# Examples\n$ git rm --cached f1               # Stages the removal of the file \"f1\"\n$ git rm -r --cached afolder/      # Stages the removal of the \"afolder\" directory\n```\n\n#### Using `git rm` on a Staged File:\n\n```bash\n# Trying to use \"git rm\" on a staged file (f1)\n$ git rm f1\nerror: the following file has changes staged in the index:\n    f1\n(use --cached to keep the file, or -f to force removal)\n```\nThis shows that you can't use `git rm` directly on a staged file unless you either:\n1. Use the `--cached` option to only remove the file from the staging area, or\n2. Use `-f` to force removal.\n\n#### Using `git rm` on a Tracked File:\n\n```bash\n# Trying to use \"git rm\" on a tracked file (afolder/f4)\n$ git rm afolder/f4\nrm 'afolder/f4'    \n```\nThis removes the file from the working directory and **stages the removal**\n\n#### Using `rm` on a Staged File:\n\n```bash\n# Trying to use \"rm\" on a staged file (f1)\n$ rm f1\n\n$ git status\nOn branch master\n\nNo commits yet\n\nChanges to be committed:\n  (use \"git rm --cached \u003cfile\u003e...\" to unstage)\n  new file:   f1\n\nChanges not staged for commit:\n  (use \"git add/rm \u003cfile\u003e...\" to update what will be committed)\n  (use \"git restore \u003cfile\u003e...\" to discard changes in working directory)\n  deleted:    f1\n```\nHere, `rm` removes the file from the working directory but doesn't unstage it. You'll see the file listed under \"Changes not staged for commit\" in the `git status` output.\n\n---\n\n### Inspecting the Stage\n\n#### Check the Status of the Repository:\nTo view the state of your repository and see which files are staged, modified, or untracked, use:\n```bash\n$ git status\n```\n\n**Output**:\n- **Changes to be committed**: Files staged for commit.\n- **Changes not staged for commit**: Modified files that are not yet staged.\n- **Untracked files**: Files in the working directory that are not part of the repository.\n\n```bash\n$ git status\nOn branch master\nChanges to be committed:\n  (use \"git restore --staged \u003cfile\u003e...\" to unstage)\n\tmodified:   f1\n\nChanges not staged for commit:\n  (use \"git add \u003cfile\u003e...\" to update what will be committed)\n  (use \"git restore \u003cfile\u003e...\" to discard changes in working directory)\n\tmodified:   afolder/f3\n\nUntracked files:\n  (use \"git add \u003cfile\u003e...\" to include in what will be committed)\n\tf2\n```\n\n---\n\n### Viewing Diffs\n\n#### See Unstaged Changes\nTo view changes made in your working directory (but not yet staged for commit), use the following command:\n\n```bash\n# Syntax\n$ git diff\n\n# Example\n$ git diff\ndiff --git a/afolder/f3 b/afolder/f3\nindex e69de29..3b18e51 100644\n--- a/afolder/f3\n+++ b/afolder/f3\n@@ -0,0 +1 @@\n+hello world\n```\nThis shows the difference between your working directory and the last commit for unstaged files.\n\n#### See Staged Changes\nTo view changes that have been staged for commit (but not yet committed), use the following command:\n\n```bash\n# Syntax\n$ git diff --cached\n\n# Example\n$ git diff --cached\ndiff --git a/f1 b/f1\nindex e69de29..3b18e51 100644\n--- a/f1\n+++ b/f1\n@@ -0,0 +1 @@\n+hello world\n```\nThis shows the difference between the staged changes and the last commit.\n\n---\n\n## Commits\n\n### What is a Commit?\nA **commit** represents a snapshot of your project at a specific point in time and acts as an **atomic unit** in Git's version control. Each commit contains:\n\n- A **snapshot** of the entire project at the moment of committing.\n- **Author information** (name and email).\n- A **commit message** describing the changes.\n- A **unique SHA-1 checksum** to ensure the commit's integrity and prevent unintended changes.\n\n### Commit Process\nTo create a commit, stage the changes first and then commit the snapshot to your repository's history:\n\n```bash\n$ git commit\n```\n\nAfter running this command, you will be prompted to enter a **commit message** in your default text editor.\n\n### Commit Message Format\nFollow this format when writing commit messages:\n\n1. **First Line (Summary)**: A brief description of the changes (50 characters or fewer).\n2. **Second Line**: Leave this line blank.\n3. **Following Lines**: A detailed explanation of the changes, reasons, or relevant ticket numbers.\n\n**Example**:\n\n```plaintext\nFixed bug in user authentication\n\nDetailed fix for user authentication issues, including validation errors\nand user session management.\n```\n\n**Note**: If you have a hard time give a short description for a commit, then you should split the commit into many commits. You take help of staging area for this. You can have **logical snapshots** instead of just chronological snapshots. \n\n---\n\n#### Commit Message Rules\n\nShort commit messages are typically used to provide a concise summary of changes. While they are brief, they should still follow best practices to ensure clarity and usefulness. Here are some rules for writing effective short commit messages:\n\n\n1. **Keep It Under 50 Characters**\n   - The message should fit within 50 characters for readability.\n   - If more detail is needed, use the body section in a longer commit message.\n\n2. **Use the Imperative Mood**\n   - Write as if giving a command.\n   - **Examples**:\n     - ✅ \"Fix broken navbar links\"\n     - ❌ \"Fixed broken navbar links\"\n\n3. **Focus on the \"What\"**\n   - Summarize what the change does, not how or why.\n   - **Examples**:\n     - ✅ \"Add search bar to header\"\n     - ❌ \"Add code for implementing the search bar\"\n\n4. **Avoid Noise**\n   - Do not use vague terms like \"Updated files\" or \"Changes made.\"\n   - Be specific: \"Remove unused imports\" or \"Optimize image loading.\"\n\n5. **Use Consistent Style**\n   - Maintain a uniform structure across all commits for consistency.\n   - Decide as a team or individually on a style guide (e.g., capitalization, tense).\n\n6. **Avoid Redundancy**\n   - Skip prefixes like \"Commit:\" or \"Change:.\"\n   - The fact that it's a commit is implied.\n\n7. **No Periods at the End**\n   - Short commit messages do not require punctuation unless it's a complete sentence.\n\n8. **Use Tags (Optional)**\n   - For clarity in large projects, use a prefix or tag if helpful:\n     - `[Bugfix] Fix crash on login`\n     - `[UI] Update button styles`\n\n**Examples of Good Short Commit Messages**:\n- \"Fix typo in README\"\n- \"Update dependencies\"\n- \"Add error handling for API calls\"\n- \"Remove deprecated methods\"\n- \"Refactor login logic\"\n\n\n---\n\n\n### Committing Using Options\n\nYou can skip the default text editor and directly provide a commit message using the `-m` option:\n\n```bash\n# Syntax\n$ git commit -m \"commit message\"\n\n# Example\n$ git commit -m \"This is a commit message\"\n[master (root-commit) cbd9be4] This is a commit message\n1 file changed, 0 insertions(+), 0 deletions(-)\ncreate mode 100644 afile.txt\n```\n\n---\n\n### Inspecting Commits\n\n#### View Commit History:\n\nTo view commit history for a specified branch, use the following command: \n```bash\n# Syntax\n$ git log branch_name\n\n# Example\n$ git log main\ncommit cbd9be4bb54c7573ff55d8826d8b1ea7582a2d0a (HEAD -\u003e master)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 17:56:52 2024 +0530\n\n    commit message\n```\n\nTo see the list of commits in the current branch, use the following command:\n\n```bash\n# Syntax\n$ git log\n\n# Example\n$ git log\ncommit cbd9be4bb54c7573ff55d8826d8b1ea7582a2d0a (HEAD -\u003e master)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 17:56:52 2024 +0530\n\n    commit message\n```\n\n#### Useful Log Options:\n\n##### Single-Line Log (Brief View):\nTo display the log in a brief, single-line format:\n\n```bash\n# Syntax\n$ git log --oneline\n\n# Example\n$ git log --oneline\ncbd9be4 (HEAD -\u003e master) commit message\n```\n\n##### Log for a Specific File:\nTo view the log for a specific file, use:\n\n```bash\n# Syntax\n$ git log [--oneline] file_or_directory\n\n# Example\n$ git log afile.txt\ncommit cbd9be4bb54c7573ff55d8826d8b1ea7582a2d0a (HEAD -\u003e master)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 17:56:52 2024 +0530\n\n    commit message\n\n# Example with oneline option\n$ git log --oneline afile.txt\ncbd9be4 (HEAD -\u003e master) commit message\n```\n\n##### Log for a Specific Range of Commits:\nTo view commits between two points, use the following syntax. Note that the commit marked as **`\u003csince\u003e` is excluded**, while **`\u003cuntil\u003e` is included**.\n\n```bash\n# Syntax\n$ git log \u003csince\u003e..\u003cuntil\u003e\n\n# Examples\n$ git log\ncommit 169223b27b5039d1d69b83889dd14e776891e9a1 (HEAD -\u003e master)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:04:00 2024 +0530\n\n    added some files in afolder\n\ncommit e09fdab287149a6c6a4c176b8c4a40df15284abd\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:03:24 2024 +0530\n\n    changed file names\n\ncommit cbd9be4bb54c7573ff55d8826d8b1ea7582a2d0a\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 17:56:52 2024 +0530\n\n    commit message\n\n# Exclude cbd9be4 and include 169223b\n$ git log cbd9be4..169223b\ncommit 169223b27b5039d1d69b83889dd14e776891e9a1 (HEAD -\u003e master)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:04:00 2024 +0530\n\n    added some files in afolder\n\ncommit e09fdab287149a6c6a4c176b8c4a40df15284abd\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:03:24 2024 +0530\n\n    changed file names\n\n# Exclude e09fdab and include 169223b\n$ git log e09fdab..169223b\ncommit 169223b27b5039d1d69b83889dd14e776891e9a1 (HEAD -\u003e master)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:04:00 2024 +0530\n\n    added some files in afolder\n```\n\n##### Display a Diffstat (Summary of Changes in Each Commit):\nTo show a diffstat summarizing the changes made in each commit, use:\n\n```bash\n# Syntax\n$ git log --stat\n\n# Example\n$ git log --stat\ncommit 169223b27b5039d1d69b83889dd14e776891e9a1 (HEAD -\u003e master)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:04:00 2024 +0530\n\n    added some files in afolder\n\nafolder/f3 | 0\nafolder/f4 | 0\n2 files changed, 0 insertions(+), 0 deletions(-)\n\ncommit e09fdab287149a6c6a4c176b8c4a40df15284abd\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:03:24 2024 +0530\n\n    changed file names\n\na =\u003e afile.txt | 0\nafolder/f1     | 0\nafolder/f2     | 0\n3 files changed, 0 insertions(+), 0 deletions(-)\n\ncommit cbd9be4bb54c7573ff55d8826d8b1ea7582a2d0a\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 17:56:52 2024 +0530\n\n    commit message\n\na | 0\n1 file changed, 0 insertions(+), 0 deletions(-)\n```\n\n#### Visualizing History:\nFor a graphical view of the commit history, use the `gitk` tool, which is available as a separate program:\n\nIt is not installed by default. To install: \n```bash\n$ sudo apt update\n$ sudo apt install gitk -y\n```\n\nTo launch gitk, just type `gitk`, which will open a GUI: \n```bash\n$ gitk\n```\n\n--- \n\n## Tagging Commits\n\n### What are Tags\nTags in Git are **pointers** to specific commits. They are **lightweight markers** that help you highlight important points in your project's history, such as release versions.\n\n### Creating a Tag\nTo create a tag on the current commit, use the following syntax:\n\n```bash\n# Syntax\n$ git tag \u003ctag_name\u003e\n\n# Example\n$ git tag v1.0\n```\n\nAfter creating the tag, you can see it in the commit log:\n\n```bash\n$ git log\ncommit 169223b27b5039d1d69b83889dd14e776891e9a1 (HEAD -\u003e master, tag: v1.0)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:04:00 2024 +0530\n\n    added some files in afolder\n\ncommit e09fdab287149a6c6a4c176b8c4a40df15284abd\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:03:24 2024 +0530\n\n    changed file names\n...\n```\n\nIf you add a new commit, the tag will **remain with the previous commit**:\n\n```bash\n$ git log\ncommit 8325a85452c5f8c2d2c6559e2cc055a1cce116ac (HEAD -\u003e master)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:19:52 2024 +0530\n\n    changed file name\n\ncommit 169223b27b5039d1d69b83889dd14e776891e9a1 (tag: v1.0)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:04:00 2024 +0530\n\n    added some files in afolder\n...\n```\n\n### Creating an Annotated Tag\nTo create an **annotated tag** (a tag with a message), use the following syntax:\n\n```bash\n# Syntax\n$ git tag -a \u003ctag_name\u003e -m \"Tag Message\"\n\n# Example\n$ git tag -a v2.0 -m \"Initial release\"\n```\n\nYou can verify the tag in the commit log:\n\n```bash\n$ git log\ncommit 8325a85452c5f8c2d2c6559e2cc055a1cce116ac (HEAD -\u003e master, tag: v2.0)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:19:52 2024 +0530\n\n    changed file name\n\ncommit 169223b27b5039d1d69b83889dd14e776891e9a1 (tag: v1.0)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:04:00 2024 +0530\n\n    added some files in afolder\n\n...\n```\n---\n\n### Listing Tags\nTo list all tags in the repository, use:\n\n```bash\n# Syntax\n$ git tag\n\n# Example\n$ git tag\nv1.0\nv2.0\n```\n\n### Pushing Tags to Remote\nBy default, **tags are not automatically pushed** to the remote repository. To push a specific tag, use:\n\n```bash\n# Syntax \n$ git push origin \u003ctag_name\u003e\n```\n\nTo **push all tags** at once:\n\n```bash\n# Syntax\n$ git push --tags\n```\n\n### Viewing a Tag\nTo view the details of a tag, use the following command:\n\n```bash\n# Syntax\n$ git show \u003ctag_name\u003e\n```\n\n#### Normal Tag\nFor a normal tag, this command will show details like the commit associated with the tag:\n\n```bash\n$ git show v1.0\ncommit 169223b27b5039d1d69b83889dd14e776891e9a1 (tag: v1.0)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:04:00 2024 +0530\n\n    added some files in afolder\n\ndiff --git a/afolder/f3 b/afolder/f3\nnew file mode 100644\nindex 0000000..e69de29\ndiff --git a/afolder/f4 b/afolder/f4\nnew file mode 100644\nindex 0000000..e69de29\n```\n\n#### Annotated Tag\nFor an annotated tag, additional information like the tagger's name and the tag message is included:\n\n```bash\n$ git show v2.0\ntag v2.0\nTagger: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:24:26 2024 +0530\n\nInitial release\n\ncommit 8325a85452c5f8c2d2c6559e2cc055a1cce116ac (HEAD -\u003e master, tag: v2.0)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:19:52 2024 +0530\n\n    changed file name\n\ndiff --git a/afile.txt b/f1\nsimilarity index 100%\nrename from afile.txt\nrename to f1\n```\n\n### Using Tags for Checkout\nTo check out a specific tag (in a detached HEAD state), use the following:\n\n```bash\n# Syntax\n$ git checkout \u003ctag_name\u003e\n\n# Example\n$ git checkout v1.0\n```\n\nThe output will look like this, **it's worth to take and read and follow it**. :\n\n```bash\nNote: switching to 'v1.0'.\n\nYou are in 'detached HEAD' state. You can look around, make experimental\nchanges and commit them, and you can discard any commits you make in this\nstate without impacting any branches by switching back to a branch.\n\nIf you want to create a new branch to retain commits you create, you may\ndo so (now or later) by using -c with the switch command. Example:\n\n  git switch -c \u003cnew-branch-name\u003e\n\nOr undo this operation with:\n\n  git switch -\n\nTurn off this advice by setting config variable advice.detachedHead to false\n\nHEAD is now at 169223b added some files in afolder\n```\n\n---\n\n## Summary of Recording Changes Commands:\n| Command                               | Description                                                                                       |\n|---------------------------------------|---------------------------------------------------------------------------------------------------|\n| `git add`                             | Stages all changes in the working directory for the next commit.                                  |\n| `git add file/folder`                 | Stages specific files or folders for the next commit.                                             |\n| `git rm`                              | Removes files from the working directory and stages the deletion for the next commit.             |\n| `git rm --cached file`                | Removes a file from the staging area without deleting it from the working directory.              |\n| `git rm -r --cached folder`           | Removes a folder from the staging area without deleting it from the working directory.            |\n| `git status`                          | Shows the status of the working directory and staging area, listing changes to be committed.      |\n| `git diff`                            | Displays unstaged changes in the working directory.                                               |\n| `git diff --cached`                   | Displays changes staged for the next commit.                                                      |\n| `git commit`                          | Commits staged changes to the repository.                                                         |\n| `git commit -m \"commit message\"`      | Commits staged changes with a descriptive message in a single step.                               |\n| `git log branch_name`                 | Displays the commit history of the repository for the specified branch.                           |\n| `git log`                             | Displays the commit history of the repository.                                                    |\n| `git log --oneline`                   | Shows a concise commit history with one commit per line.                                          |\n| `git log --oneline file/folder`       | Shows a concise commit history for a specific file or folder.                                     |\n| `git log \u003csince\u003e..\u003cuntil\u003e`            | Displays commits between two references (e.g., tags, branches), with `\u003csince\u003e` being exclusive.   |\n| `git log --stat`                      | Shows commit history along with a summary of changes made in each commit.                         |\n| `git tag tag_name`                    | Creates a lightweight tag for the current commit.                                                 |\n| `git tag -a tag_name -m \"tag message\"`| Creates an annotated tag with a message for the current commit.                                   |\n| `git tag`                             | Lists all tags in the repository.                                                                 |\n| `git push origin tag_name`            | Pushes a specific tag to the remote repository.                                                   |\n| `git push --tags`                     | Pushes all tags to the remote repository.                                                         |\n| `git show tag_name`                   | Displays details of a specific tag, including the commit it references.                           |\n| `git checkout tag_name`               | Checks out a specific tag, detaching the HEAD to a read-only state.                               |\n| `gitk`                                | Opens a graphical tool to visualize the commit history.                                           |\n\n---\n\n# Undoing Changes\nWhat's the point of having commits when you don't have the ability to undo changes? Git provides tools to undo changes at various stages, allowing you to correct mistakes or discard experiments without fear of breaking your code. These tools can help you reset the **working directory**, **staging area**, or even undo an **entire commit**.\n\n---\n\n## What Does Undoing Changes Mean?\n\n- **Working Directory**: Reverting changes made to files before staging.\n- **Staging Area**: Removing changes staged for a commit.\n- **Commits**: Reverting or amending an entire commit.\n\n---\n\n## Undoing Changes in the Working Directory\n\n### Reset to the Last Commit\nTo discard all uncommitted changes (in both the working directory and staging area), use:\n```bash\n# Syntax\n$ git reset --hard HEAD\n\n# Example\n$ git status\nOn branch master\nChanges to be committed:\n  deleted:    afolder/f4\n  modified:   f1\n\nChanges not staged for commit:\n  modified:   afolder/f3\n\nUntracked files:\n  commands\n  f2\n\n# Resetting the working directory and staging area to the last commit\n$ git reset --hard HEAD\nHEAD is now at 8325a85 changed file name\n\n$ git status\nOn branch master\nUntracked files:\n  commands\n  f2\nnothing added to commit but untracked files present (use \"git add\" to track)\n```\n\n#### Key Points:\n- `git reset --hard HEAD`: Resets the working directory and staging area to match the last commit.\n- **Untracked Files**: Not affected by this command.\n\n#### Remove Untracked Files\nTo delete untracked files:\n```bash\n# Syntax\n$ git clean -f\n\n# Example\n$ git status\nUntracked files:\n  commands\n  f2\n\n# Removing untracked files\n$ git clean -f\nRemoving commands\nRemoving f2\n\n$ git status\nnothing to commit, working tree clean\n```\n\n##### Key Points:\n- `git clean -f`: Deletes untracked files from the working directory.\n- **Force Option (`-f`)**: Required to confirm deletion of untracked files.\n\n---\n\n### Undo Changes to a Specific File\nTo restore a specific file to its state in the last commit:\n```bash\n# Syntax\n$ git checkout HEAD \u003cfile\u003e\n\n# Example\n$ git status\nChanges not staged for commit:\n  modified:   afolder/f2\n  modified:   f1\n\nUntracked files:\n  f\n\n# Reverting `f1` to the state of the last commit\n$ git checkout HEAD f1\nUpdated 1 path from dd3c5af\n\n$ git status\nChanges not staged for commit:\n  modified:   afolder/f2\n\nUntracked files:\n  f\n```\n\n#### Key Points\n- Replaces the file in the working directory with the version from **HEAD** (last commit).\n- Does not affect untracked files or project history.\n\n---\n\n## Undoing in the Staging Area\n\nWhen a file is mistakenly added to the staging area, you can unstage it without affecting the changes in your working directory.\n\nTo remove a file from the staging area: \n```bash\n$ git reset HEAD \u003cfile\u003e\n```\n\n### Key points\n* **Effect**: Moves the file from the staging area back to the working directory as an **unstaged change**.\n* **Working Directory**: The file remains unchanged, preserving your modifications.\n* This action is non-destructive, making it safe for recovering from accidental staging.\n\n\n### What is the difference between `reset HEAD file` and `rm --cached file`?\n\n| Command                   | Purpose                                    | Effect on Working Directory | Effect on Repository |\n|---------------------------|--------------------------------------------|-----------------------------|-----------------------|\n| `git reset HEAD \u003cfile\u003e` | Unstages a file without deleting it.      | **Keeps the file unchanged**. | File remains tracked in the repository. |\n| `git rm --cached \u003cfile\u003e` | Removes a file from the repository's index (staging area) but leaves it in the working directory. | **Keeps the file intact** but marks it as untracked. | File is no longer tracked in the repository. |\n\n### Key Differences:\n\n1. **Use Case**:\n   - `git reset HEAD \u003cfile\u003e`: Used to **unstage changes** that were added with `git add` but not yet committed.\n   - `git rm --cached \u003cfile\u003e`: Used to **stop tracking a file** entirely, often for files that were mistakenly added to the repository (like large binaries or sensitive data).\n\n2. **Impact on Tracking**:\n   - `git reset HEAD \u003cfile\u003e`: The file remains **tracked**; only its staging status changes.\n   - `git rm --cached \u003cfile\u003e`: The file is **untracked** by Git but stays in your working directory.\n\n3. **Practical Example**:\n   - `git reset HEAD example.txt`: Reverts `example.txt` from the staging area to the working directory, keeping it tracked for future commits.\n   - `git rm --cached example.txt`: Stops tracking `example.txt` entirely but leaves it in the working directory as an untracked file.\n\n\n## Undoing Commits\n\n**Two Ways to Undo Commits**:\n1. **Reset**: Removes a commit entirely from the history.\n2. **Revert**: Creates a new commit that undoes the changes of a previous commit.\n\n### Resetting Commits\n\nThe `git reset` command is used to move the `HEAD` pointer to a specific commit, effectively removing commits from the history. Depending on the mode, it can also preserve or discard changes.\n\nThe syntax for resetting the commits is as follows: \n```bash\n$ git reset HEAD~\u003cnumber\u003e\n```\n\n#### Resetting the Most Recent Commit\n\nThe syntax for resetting the most recent commit is as follows: \n```bash\n$ git reset HEAD~1\n```\n\n##### Example: Undo the Most Recent Commit\n1. **Check Commit History**:\n   ```bash\n   $ git log\n   commit bdab6c6e81cb82dd603db485c5e41c564a210dde (HEAD -\u003e master)\n   Author: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\n   Date:   Sun Dec 29 05:37:31 2024 +0530\n\n       bad commit\n\n   commit 8325a85452c5f8c2d2c6559e2cc055a1cce116ac (tag: v2.0)\n   Author: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\n   Date:   Sat Dec 28 18:19:52 2024 +0530\n\n       changed file name\n   ```\n\n2. **Undo the Most Recent Commit**:\n   ```bash\n   $ git reset HEAD~1\n   Unstaged changes after reset:\n   M    afolder/f2\n   ```\n\n3. **Verify the New History**:\n   ```bash\n   $ git log\n   commit 8325a85452c5f8c2d2c6559e2cc055a1cce116ac (HEAD -\u003e master, tag: v2.0)\n   Author: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\n   Date:   Sat Dec 28 18:19:52 2024 +0530\n\n       changed file name\n   ```\n\n---\n\n#### Resetting to a Specific Commit\n\nYou can reset your repository to any commit in the history. Consider the following commit log:\n\n```bash\n$ git log\ncommit 173d36dddfc4c474ac38135f95dd00bb377ed9e8 (HEAD -\u003e master)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sun Dec 29 05:58:47 2024 +0530\n\n    updated f1\n    fixed a typo in f1\n\n... # bunch of commits\n\ncommit 8325a85452c5f8c2d2c6559e2cc055a1cce116ac (tag: v2.0)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:19:52 2024 +0530\n\n    changed file name\n```\n\nTo reset your repository to `tag: v2.0`, there are **two options**:\n\n---\n\n##### Option 1: `git reset --soft`\n\n1. **Command**:\n   ```bash\n   $ git reset --soft 8325a854   # Or git reset --soft v2.0\n   ```\n\n2. **Effect**:\n   - Moves `HEAD` to `tag: v2.0`.\n   - Removes all commits after `tag: v2.0`.\n   - Preserves the changes from deleted commits and stages them.\n\n3. **Example**:\n   ```bash\n   $ git reset --soft 8325a854\n\n   $ git log\n   commit 8325a85452c5f8c2d2c6559e2cc055a1cce116ac (HEAD -\u003e master, tag: v2.0)\n   Author: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\n   Date:   Sat Dec 28 18:19:52 2024 +0530\n\n       changed file name\n\n   $ git status # notice how the deleted commit's changes are in staged.\n   Changes to be committed:\n     (use \"git restore --staged \u003cfile\u003e...\" to unstage)\n     modified:   f1\n   ```\n\n---\n\n##### Option 2: `git reset --hard`\n\n1. **Command**:\n   ```bash\n   $ git reset --hard 8325a854   # Or git reset --hard v2.0\n   ```\n\n2. **Effect**:\n   - Moves `HEAD` to `tag: v2.0`.\n   - Removes all commits after `tag: v2.0`.\n   - Discards all changes from deleted commits, without saving them.\n\n3. **Example**:\n   ```bash\n   $ git reset --hard 8325a854\n   HEAD is now at 8325a85 changed file name\n   ```\n\n---\n\n#### Key Points\n\n1. **`HEAD~\u003cnumber\u003e`**: Refers to a specific number of commits back from the current `HEAD`.  \n   - Example: `HEAD~3` moves 3 commits back.\n\n2. **Modes of Reset**:\n   - **Soft**: Keeps changes from deleted commits and stages them.\n   - **Mixed (default)**: Keeps changes from deleted commits but unstages them.\n   - **Hard**: Discards all changes from deleted commits.\n\n3. **Rewriting History**:\n   - Resetting rewrites commit history, which can lead to issues in collaborative projects if the commits have been shared. Use with caution!\n\n4. **Safe Usage**:\n   - Reset private commits that haven't been pushed.\n   - Avoid resetting shared commits to prevent conflicts.\n- \n### Reverting Commits\n\nThe `git revert` command is a safer alternative to `git reset`, particularly in public repositories. Instead of rewriting commit history, it **creates a new commit that reverses the changes introduced by a commit**.\n\n```bash\n$ git revert \u003ccommit-id\u003e\n```\n\n---\n\n#### Example: Reverting the Most Recent Commit\n\n##### Step 1: Check the Commit History\n```bash\n$ git log\ncommit e4a9e9928f1648638e3292f5d0a36934ff18ecd6 (HEAD -\u003e master)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sun Dec 29 05:42:51 2024 +0530\n\n    bad commit\n\ncommit 8325a85452c5f8c2d2c6559e2cc055a1cce116ac (tag: v2.0)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:19:52 2024 +0530\n\n    changed file name\n```\n\n##### Step 2: Revert the Commit\n```bash\n$ git revert HEAD\nhint: Waiting for your editor to close the file...\n```\n\nThis opens the editor for a commit message. The default message typically includes the reverted commit details:\n\n```plaintext\nRevert \"bad commit\"\n\nThis reverts commit e4a9e9928f1648638e3292f5d0a36934ff18ecd6.\n```\n\n- Edit the message as needed and close the editor.  \n- Once the editor is closed, the revert operation completes.\n\n---\n\n#### Step 3: Verify the Revert\n```bash\n$ git log\ncommit 442f724d702b6ac5199bfe80de8e08009b737019 (HEAD -\u003e master)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sun Dec 29 05:47:13 2024 +0530\n\n    Revert \"bad commit\"\n    \n    This reverts commit e4a9e9928f1648638e3292f5d0a36934ff18ecd6.\n    \n    Changed the file by mistake\n\ncommit e4a9e9928f1648638e3292f5d0a36934ff18ecd6\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sun Dec 29 05:42:51 2024 +0530\n\n    bad commit\n```\n\n\n#### Key Features of `git revert`\n\n1. **Does Not Rewrite History**:\n   - Unlike `git reset`, which modifies the commit history, `git revert` creates a new commit that cancels out the changes of the specified commit.\n\n2. **Safe for Public Repositories**:\n   - Since it avoids altering history, `git revert` is ideal for projects where multiple people are working collaboratively.\n\n3. **Works on Specific Commits**:\n   - You can revert any commit in the history, not just the latest one. Simply replace `HEAD` with the appropriate `\u003ccommit-id\u003e`.\n\n4. **Interactive Editor**:\n   - The revert process opens a text editor for the new commit message. You can customize it or leave the default message.\n\n---\n\n\n## Amending Commits\n\nAmending a commit allows you to **modify the most recent commit**, whether to include forgotten changes or fix the commit message. The syntax for ammending a commit: \n```bash\n$ git commit --amend\n```\n\n### Example Workflow:\n\n#### 1. Initial Commit:\nLet's intentionally make a mistake and commit it. \n```bash\n# Making a mistake. \n$ echo \"hello wordl\" \u003e f1\n\n# Commiting it. \n$ git add .\n$ git commit -m \"update f1\"\n[master 53932d1] update f1\n1 file changed, 1 insertion(+)\n```\n\n#### 2. Check Commit History:\n```bash\n$ git log\ncommit 53932d1315f14a3a0bff75f24918848fc71b598c (HEAD -\u003e master)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sun Dec 29 05:58:47 2024 +0530\n\n   update f1\n...\n```\n\n#### 3. Make Corrections:\n\nFix the typo in `f1`:\n\n```bash\n$ echo \"hello world\" \u003e f1\n$ git add .\n```\n\nAmend the commit:\n\n```bash\n$ git commit --amend\nhint: Waiting for your editor to close the file...\n```\n\nThis opens the COMMIT_EDITOR, showing the current commit message:\n```plaintext\nupdate f1\n\n# Please enter the commit message for your changes. Lines starting\n# with '#' will be ignored, and an empty message aborts the commit.\n#\n# Date:      Sun Dec 29 05:58:47 2024 +0530\n#\n# On branch master\n# Changes to be committed:\n#    modified:   f1\n#\nfix typo in f1\n```\nEdit the message if needed and save the file.\n\n#### 4. Result:\n```bash\n# After closing the COMMIT_EDITOR windows:\n[master 173d36d] update f1\nDate: Sun Dec 29 05:58:47 2024 +0530\n1 file changed, 1 insertion(+)\n\n$ git log\ncommit 173d36dddfc4c474ac38135f95dd00bb377ed9e8 (HEAD -\u003e master)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sun Dec 29 05:58:47 2024 +0530\n\n   update f1\n    \n   fix typo in f1\n...\n```\n\n### Key Points:\n- **Purpose**: Replaces the previous commit with a new one, incorporating changes to the message or content without creating a new commit.\n- **Rewriting History**: Amending a commit changes its hash. **Avoid amending commits that have already been pushed or shared**, as this can cause issues for collaborators.\n\n## Summary of Undoing Changes\n\n| **Command**| **Description**|\n|------------|----------------|\n| `git reset --hard HEAD`| Resets the working directory to the state of the last commit.|\n| `git clean -f`| **Deletes untracked files** from the working directory.|\n| `git checkout HEAD \u003cfile\u003e`| Reverts a specific file to its state in the last commit.|\n| `git reset HEAD \u003cfile\u003e`| Removes a file from the staging area, **leaving its changes in the working directory**. |\n| `git rm --cached \u003cfile\u003e`| Removes a file from the staging area, removing it from the repository and make it **untracked**. |\n| `git reset HEAD~\u003cnumber\u003e`| Removes commits until the number from history and keeps its changes in the working directory. |\n| `git reset HEAD~1`| Removes the last commit from history and keeps its changes in the working directory. |\n| `git reset --hard \u003ccommit-id\u003e`| Resets to a specific commit, **discarding all changes** after it.|\n| `git reset --soft \u003ccommit-id\u003e`| Resets to a specific commit, **keeping changes staged** but removing subsequent commits. |\n| `git revert \u003ccommit-id\u003e`| Creates a new commit that reverses the changes made by a specific commit.|\n| `git revert HEAD`| Creates a new commit that reverses the changes made by a most recent commit.|\n| `git commit --amend`| Edits the most recent commit message or adds changes to it.|\n\n---\n\n# Branches\n\nBranches in Git allow you to create multiple development paths, enabling parallel work on different versions of a project. **When you create a new branch, you essentially get a new environment for working**, including an isolated working directory, staging area, and project history. \n\nBranches are **nothing but a pointer** to a commit. The default branch in any Git repo is **master**, which is created with first commit. Branches are nothing but files containing commit hash, you can view these files in `.git/refs/heads/branch_name`.\n\n## Manipulating Branches\n\n### Listing Branches  \nYou can view all your branches with the `git branch` command, which shows the current branch with an asterisk next to it:\n```bash\n# Syntax\n$ git branch\n\n# Example\n$ git branch\n* main\n```\n\n### Creating Branches\nCreate a new branch using the command:\n```bash\n# Syntax\n$ git branch \u003cname\u003e [\u003cbase_branch\u003e]\n\n# Example\n$ git branch sample_branch main\n$ git branch\n* main\n  sample_branch\n  develop\n$ git branch feature/BBMC-5555 develop\n```\nThis creates a new branch that points to the current commit, but it **does not automatically switch to it**.\n\n### Deleting Branches\nTo delete a branch, use:\n```bash\n# Syntax\n$ git branch -d \u003cname\u003e\n\n# Example\n$ git branch -d sample_branch \nDeleted branch sample_branch (was 8325a85).\n```\n\nIf the branch has unmerged commits, Git will prevent the deletion to avoid data loss. You can force deletion with:\n\n```bash\n$ git branch -D \u003cname\u003e\n```\n\n### Checking Out Branches\nTo switch between branches, use the `git checkout` or `git switch` command:\n```bash\n# Syntax\n$ git checkout \u003cbranch\u003e\n$ git switch \u003cbranch\u003e\n\n# Example\n$ git checkout sample_branch \nSwitched to branch 'sample_branch'\n\n$ git switch sample_branch \nSwitched to branch 'sample_branch'\n```\n**Note**: Before checking out, ensure that working directory is clean. Logically this makes sense, when you checkout, the **entire working directory is reconstructed from the .git repository**, if you leave something uncommited then those tracked files will be overriden or cleaned. \n\n### Creating and Checking out Simulataneously\n\n#### 1. `git checkout -b \u003cnew-branch-name\u003e`\n\n- **Function:** \n  - Creates a new branch with the specified name.\n  - Automatically switches the working directory to this new branch.\n\n- **Usage Example:**\n  ```bash\n  $ git checkout -b feature/login\n  ```\n  This command:\n  - Creates a new branch called `feature/login`.\n  - Switches to the `feature/login` branch.\n\n- **Behind the scenes:**\n  - Equivalent to running:\n    ```bash\n    $ git branch \u003cnew-branch-name\u003e\n    $ git checkout \u003cnew-branch-name\u003e\n    ```\n  - This two-step process (create and switch) is combined into one with the `-b` option.\n\n#### 2. `git switch -c \u003cnew-branch-name\u003e`\n\n- **Function:** \n  - A newer and more intuitive command introduced in Git 2.23 (released in August 2019).\n  - Similar to `git checkout -b`, it creates and switches to a new branch in a single step.\n\n- **Usage Example:**\n  ```bash\n  $ git switch -c feature/login\n  ```\n  This command does the same as `git checkout -b feature/login`.\n\n- **Why `git switch`?**\n  - `git switch` was introduced to separate branch-related operations from file-related ones.\n  - Makes it clear that you're working with branches and not modifying files in the working directory.\n\n#### When to Use Which?\n\n- **If you prefer older commands or are using an older version of Git (\u003c 2.23):**\n  Use `git checkout -b`.\n\n- **If you're using Git 2.23 or later and prefer clarity:**\n  Use `git switch -c`.\n\n#### Key Notes:\n\n1. **Naming the branch:**\n   Ensure your branch name is descriptive and relevant to the work you'll be doing on it, e.g., `bugfix/payment`, `feature/signup`, etc.\n\n2. **Branch creation context:**\n   - The new branch is created from the **current branch's HEAD**. If you want to create it from a different branch, you must first switch to that branch or use `git switch`/`checkout` with additional options.\n\n3. **Default branch movement:**\n   By default, branches are based on the `HEAD` of your current branch unless you specify a different base.\n\n\n### Detached HEADs\nA detached HEAD occurs when you **checkout to a specific commit or tag** rather than a branch. In this state, any new commits won't belong to a branch and may be lost when switching branches. \n```bash\n# Background\n$ git log\ncommit 8325a85452c5f8c2d2c6559e2cc055a1cce116ac (HEAD -\u003e sample_branch, tag: v2.0, master)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:19:52 2024 +0530\n\n    changed file name\n\ncommit 169223b27b5039d1d69b83889dd14e776891e9a1 (tag: v1.0)\nAuthor: rnaveensrinivas \u003crnaveensrinivas@gmail.com\u003e\nDate:   Sat Dec 28 18:04:00 2024 +0530\n\n    added some files in afolder\n\n...\n\n# Checking out tag v1.0, we are warned!\n$ git checkout v1.0\nNote: switching to 'v1.0'.\n\nYou are in 'detached HEAD' state. You can look around, make experimental\nchanges and commit them, and you can discard any commits you make in this\nstate without impacting any branches by switching back to a branch.\n\nIf you want to create a new branch to retain commits you create, you may\ndo so (now or later) by using -c with the switch command. Example:\n\n  git switch -c \u003cnew-branch-name\u003e\n\nOr undo this operation with:\n\n  git switch -\n\nTurn off this advice by setting config variable advice.detachedHead to false\n\nHEAD is now at 169223b added some files in afolder\n```\n\nYou can create a new branch from this state with:\n```bash\n$ git checkout -b \u003cnew-branch-name\u003e\n# or\n$ git switch -c \u003cnew-branch-name\u003e\n```\n---\n\n## Merging Branches\n\nMerging is used to combine changes from one branch into another. The general process involves two steps:\n\n```bash\n$ git checkout \u003cbranch_you_want_other_branch_to_merge_into\u003e\n$ git merge \u003cother_branch_name\u003e\n```\n\nThis tells Git to merge the changes from `\u003cother_branch_name\u003e` into the branch you currently have checked out.\n\nInternally git manages merging in two ways: \n1. **Fast-forward Merge**\n2. **3-way Merge**\n---\n\n### 1. Fast-forward Merge\n\nA fast-forward merge happens when there have been no new commits on the target branch since the branch was created. Git **simply moves the branch pointer forward** to include the commits from the other branch. **No new commits are created for merges.**\n\n#### Example:\n\n1. Assume the following branch structure:\n   ```\n   * Commit C (feature)\n   |\n   * Commit B\n   |\n   * Commit A (main)\n   ```\n   - `main` is the target branch.\n   - `feature` is the branch to merge.\n\n2. Commands:\n   ```bash\n   $ git checkout main\n   $ git merge feature\n   ```\n\n3. Resulting branch structure:\n   ```\n   * Commit C (main, feature)\n   |\n   * Commit B\n   |\n   * Commit A\n   ```\n   The `main` branch now includes all commits from `feature`, and the `feature` branch pointer fast-forwards to the same commit as `main`.\n\n---\n\n### 2. Three-way Merge\n\nA 3-way merge is required when the **two branches have diverged**, meaning both branches have new commits. Git uses the **common ancestor** of both branches and the changes on each branch to create a new **merge commit**. Two branch commits, and one common ancestor make up three commits, hence called three-way merge. \n\n#### Example:\n\n1. Assume the following branch structure:\n   ```\n   (feature) D *          * Commit C (main)\n                \\        /\n                 * Commit B\n                 |\n                 * Commit A\n   ```\n   - Both `main` and `feature` have unique commits (`C` and `D`, respectively).\n\n2. Commands:\n   ```bash\n   $ git checkout main\n   $ git merge feature\n   ```\n\n3. Resulting branch structure:\n   ```\n                  * Merge Commit (main)\n                /        \\\n   (feature) D *          * Commit C\n                \\        /\n                 * Commit B\n                 |\n                 * Commit A\n   ```\n   A **merge commit** is created to combine the changes from both branches.\n\n---\n\n### Merge Conflicts\n\nIf there are conflicting changes in the files between the two branches, Git will pause the merge and mark the conflicting files. You'll need to manually resolve it by editing the file.\n\n1. Identify conflicts:\n   ```bash\n   $ git status\n   ```\n   Conflicting files will be listed with the status **both modified**.\n\n2. Open the conflicting files and resolve conflicts:\n   - Git marks conflicts in the file like this:\n     ```diff\n     \u003c\u003c\u003c\u003c\u003c\u003c\u003c HEAD\n     Changes from the current branch\n     =======\n     Changes from the branch being merged\n     \u003e\u003e\u003e\u003e\u003e\u003e\u003e \u003cother_branch_name\u003e\n     ```\n   - Edit the file to combine or choose the appropriate changes.\n\n3. After fixing the conflict, stage the file with\n   ```bash\n   $ git add \u003cconflicted_file\u003e\n   ```\n\n4. Complete the merge:\n   ```bash\n   $ git commit\n   ```\n---\n\n### Summary of Merge Strategies\n\n| **Merge Type**| **When It Happens**| **Result**|\n|---------------|--------------------|-----------|\n| **Fast-forward Merge**  | When the target branch has no new commits since branching.| Moves the branch pointer forward, no new commit is created.|\n| **3-way Merge**| When both branches have diverged with new commits.| Creates a new merge commit to combine changes.|\n| **Merge Conflicts**| When changes in the branches conflict and cannot be automatically merged. | Requires manual resolution before completing the merge.|\n\n## Rebasing\nRebasing is the process of moving a branch to a new base. Rebasing is better than merging when you want a **clean, linear commit history**. It eliminates unnecessary merge commits, making the project history easier to read and navigate. Merge Commit hold no significance apart from merging, hence having lot of merges may clutter the tree. Rebasing is particularly useful for feature branches being integrated into main branches, as it simplifies tracking changes and avoids the clutter of multiple merge points. However, it should be used cautiously in collaborative workflows to avoid issues from rewritten history.\n\n\n### Basic Rebasing Workflow Syntax\n1. Check out the branch you want to rebase:\n```bash\n$ git checkout some-feature\n```\n2. Rebase onto another branch:\n```bash\n$ git rebase master\n```\n- This moves the `some-feature` branch onto the tip of `master`, creating a linear history.\n\n### Comparison: Rebase vs. Merge\n#### Rebase\nCreates a linear history by moving the branch onto the new base. No additional merge commits are created. Consider the following example: \n```\n* Commit C (main)\n|\n|  * Commit D (some-feature)\n|/\n* Commit B\n|\n* Commit A\n```\n\nAfter rebasing, \n```\n   * Commit D (some-feature)\n / \n* Commit C (main)\n|\n|  \n|\n* Commit B\n|\n* Commit A\n```\n#### Merge\n- Combines branches using a merge commit.\n- May result in a cluttered history if done repeatedly.\n- Example:\n```\n                *   Merge Commit (main)\n                |\\  \n                | * Commit D (some-feature)\n                | |  \nCommit C (main) * | \n                |/  \n                * Commit B\n                |\n                * Commit A\n\n```\n### Advantages of Rebasing\n- Creates a clean and linear history.\n- Eliminates superfluous merge commits.\n- Enhances readability and navigability of the project history.\n\n### Disadvantages of Rebasing\n- **History Rewriting**:\n  - Rebasing creates new commits with different IDs, effectively destroying the original commits.\n  - This can lead to issues in collaborative workflows if others are working on the same branch.\n\n---\n\n### Interactive Rebasing\n\n#### Initial Commit History  \nImagine you have the following Git history for a feature branch (`some-feature`):  \n\n```\n* 7d2e4c8 Fix typos in the feature implementation\n* 5b1a7c3 Add unit tests for the feature\n* 3f8c6b2 Implement the feature logic\n* e1f1d7a Initial commit for the feature\n* a1f76d0 Latest commit on master\n* b3c19e1 Older commit on master\n```\n\nThe feature branch includes **four commits**:  \n1. `e1f1d7a`: Initial commit for the feature  \n2. `3f8c6b2`: Implement the feature logic  \n3. `5b1a7c3`: Add unit tests for the feature  \n4. `7d2e4c8`: Fix typos in the feature implementation  \n\nYou want to clean up this history by:  \n- Combining the four feature branch commits into one.  \n- Writing a single, meaningful commit message summarizing the changes.  \n\n---\n\n#### Step-by-Step Workflow\n\n##### 1. Start Interactive Rebase\nRun the following command:  \n```bash\n# Syntax\n$ git rebase -i master\n```  \nThis tells Git:  \n- Rebase all commits in `some-feature` (`7d2e4c8`, `5b1a7c3`, `3f8c6b2`, `e1f1d7a`) onto `master` (`a1f76d0`).  \n\n---\n\n##### 2. Interactive Rebase Prompt\nGit opens an editor showing the commits in the feature branch:  \n\n```plaintext\npick e1f1d7a Initial commit for the feature\npick 3f8c6b2 Implement the feature logic\npick 5b1a7c3 Add unit tests for the feature\npick 7d2e4c8 Fix typos in the feature implementation\n```\n\nEach line represents a commit. The `pick` command means \"keep this commit as is.\"  \n\n---\n\n##### 3. Modify the Rebase Instructions\nTo combine all four commits into one, change `pick` to `squash` for the last three commits:  \n\n```plaintext\npick e1f1d7a Initial commit for the feature\nsquash 3f8c6b2 Implement the feature logic\nsquash 5b1a7c3 Add unit tests for the feature\nsquash 7d2e4c8 Fix typos in the feature implementation\n```\n\n**Explanation**:  \n- The first commit (`pick e1f1d7a`) will remain as the base.  \n- The changes from the next three commits will be **combined (squashed)** into the first commit.  \n\n---\n\n##### 4. Edit the Commit Message\nGit prompts you to write a new commit message summarizing the combined changes:  \n\n```plaintext\n# This is a combination of 4 commits.\n# The first commit's message is:\nInitial commit for the feature\n\n# The following commit messages will be discarded:\nImplement the feature logic\nAdd unit tests for the feature\nFix typos in the feature implementation\n\n# Write a new commit message:\nAdded a new feature with logic, tests, and typo fixes\n```\n\n**Tip**: Write a clear and descriptive message summarizing the changes.  \n\n---\n\n##### 5. View the Cleaned-Up Commit History\nAfter completing the rebase, the branch history now looks like this:  \n\n```\n* 9d3f2a5 Added a new feature with logic, tests, and typo fixes\n* a1f76d0 Latest commit on master\n* b3c19e1 Older commit on master\n```\n\n**Key Changes**:  \n- The four commits in the feature branch are now combined into one (`9d3f2a5`).  \n- The history is clean, linear, and easier to understand.  \n\n---\n\n### Commands Used in Interactive Rebase\n\n| **Command** | **Effect** | **Example Use Case** |\n|-------------|------------|----------------------|\n| **pick**    | Keep the commit as is. | Retain an important commit without changes. |\n| **squash**  | Combine the commit with the previous one and merge their messages. | Reduce multiple related commits into one. |\n| **fixup**   | Combine the commit with the previous one but discard its message. | Clean up small fixes without keeping commit messages. |\n| **reword**  | Keep the commit but edit its message. | Clarify an unclear commit message. |\n| **drop**    | Remove the commit from history. | Delete unnecessary or experimental commits. |\n| **edit**    | Pause the rebase to make changes to the commit or files. | Modify a specific commit in the middle of history. |\n\n---\n\n### Best Practices for Interactive Rebase\n1. **Use for Local Cleanup**:  \n   - Squash commits and refine messages before sharing the branch with others.  \n\n2. **Avoid Rebasing Public Branches**:  \n   - Rewriting history on branches shared with others can cause conflicts.  \n\n3. **Combine Related Commits**:  \n   - Merge small, incremental commits into a single meaningful change.  \n\n4. **Keep Commit Messages Clear**:  \n   - Write descriptive and concise commit messages for easier collaboration.  \n\n--- \n\n## Summary of Branches\n\n| **Command**                            | **Description**                                                                 |\n|----------------------------------------|---------------------------------------------------------------------------------|\n| `git branch`                           | Lists all local branches in the repository.                                    |\n| `git branch branch_name [base_branch_name]`| Creates a new branch with the specified name, based out of base branch     |\n| `git branch -d branch_name`            | Deletes the specified branch (only if it has been fully merged).               |\n| `git branch -D branch_name`            | Force deletes the specified branch, even if it has not been merged.            |\n| `git checkout branch_name`             | Switches to the specified branch.                                              |\n| `git switch branch_name`               | Another command to switch to the specified branch (preferred over `checkout`). |\n| `git checkout -b branch_name`          | Creates a new branch and switches to it.                                       |\n| `git switch -c branch_name`            | Creates a new branch and switches to it (preferred over `checkout`).           |\n| `git checkout \u003ccommit-id\u003e/\u003ctags\u003e`      | Checks out a specific commit or tag in a detached HEAD state.                  |\n| **Merging**                            |                                                                                 |\n| `git checkout branch_you_want_other_branch_to_merge_into`| Switches to the `branch_you_want_other_branch_to_merge_into` branch.|\n| `git merge other_branch_name`| Merges the `other_branch_name` branch into the current branch (`branch_you_want_other_branch_to_merge_into`).               |\n| **Rebasing (Opposite of Merging)**     |                                                                                 |\n| `git checkout other_branch_name`| Switches to the `other_branch_name` branch.                                              |\n| `git rebase branch_you_want_other_branch_to_rebase_into`| Reapplies the commits from `other_branch_name` onto `branch_you_want_other_branch_to_rebase_into` for a linear history.      |\n| **Interactive Rebasing**               |                                                                                 |\n| `git checkout other_branch_name`| Switches to the `other_branch_name` branch.                                              |\n| `git rebase -i branch_you_want_other_branch_to_rebase_into`| Opens an interactive rebase session for `other_branch_name` on top of `branch_you_want_other_branch_to_rebase_into`.         |\n\n---\n\n# Branching Workflows\n\nGit's lightweight and easy-to-merge branches make it a powerful tool for software development. \n\n## Key Commands for Branching Workflows\n- `git branch`: Create, list, or delete branches.\n- `git checkout`: Switch to another branch or restore files.\n- `git merge`: Merge changes from one branch into another.\n- `git rebase`: Reapply commits from one branch onto another to create a linear history.\n\n---\n\n## Types of Branches\n\nBranches can be categorized into two main types:\n1. **Permanent Branches**\n2. **Topic Branches**\n  \n---\n\n\n### Permanent Branches\n- **Purpose**: These branches contain the main history of a project and serve as **integration points** for stable, finalized changes.\n- **Characteristics**:\n  - Typically long-lived and persist throughout the project lifecycle.\n  - Often include branches like `master` (or `main`) and `develop`.\n- **Common Workflows**:\n  - Use `master` exclusively for stable, production-ready code.\n  - Use an intermediate integration branch like `develop` for combining and testing features before merging them into `master`.\n- **Example Workflow**:\n  - Developers work on feature branches.\n  - Feature branches are merged into `develop` for integration and testing.\n  - Once stable, `develop` is merged into `master` for public release.\n- **Benefits**:\n  - Clear distinction between stable code and code under development.\n  - Allows for orderly releases and minimizes risks to the production branch.\n\n#### Example:\n```plaintext\nmaster ← develop ← [feature-1, feature-2, ...]\n```\n### Topic Branches\n\nTopic branches are temporary and created for specific tasks or changes. They help keep the project organized and protect permanent branches from untested code.\n\n#### Feature Branches\n- **Purpose**: Encapsulate a new feature or refactor.\n- **Characteristics**:\n  - Typically stem from `develop` or another integration branch.\n  - Not merged directly into `master`.\n  - Short-lived and deleted after the feature is completed and integrated.\n- **Benefits**:\n  - Isolates new features from the main codebase until they are complete and tested.\n  - Encourages parallel development by multiple contributors.\n\n#### Example Workflow:\n```plaintext\nmaster ← develop ← feature/new-feature\n```\n1. Create a feature branch:\n   ```bash\n   # create a new branch based on develop\n   git checkout -b feature/new-feature develop\n   ```\n2. Work on the feature and commit changes.\n3. Merge the feature branch into `develop` when ready:\n   ```bash\n   git checkout develop\n   git merge feature/new-feature\n   ```\n4. Delete the feature branch:\n   ```bash\n   git branch -d feature/new-feature\n   ```\n\n#### Hotfix Branches\n- **Purpose**: Quickly patch bugs or issues in the production code.\n- **Characteristics**:\n  - Stem directly from `master` (or the public release branch).\n  - Focus on critical bug fixes or updates that cannot wait for the next release cycle.\n  - Merged back into both `master` and `develop` to keep branches synchronized.\n- **Example Workflow**:\n  - Developers work on feature branches.\n  - Feature branches are merged into `develop` for integration and testing.\n  - Once stable, `develop` is merged into `master` for public release.\n- **Benefits**:\n  - Ensures production issues are resolved quickly.\n  - Maintains consistency across all branches.\n\n#### Example Workflow:\n```plaintext\nmaster ← hotfix/fix-critical-bug\n```\n1. Create a hotfix branch:\n   ```bash\n   # create a hotfix branch based on master\n   git checkout -b hotfix/fix-critical-bug master\n   ```\n2. Apply the patch and commit changes.\n3. Merge the hotfix into `master`:\n   ```bash\n   git checkout master\n   git merge hotfix/fix-critical-bug\n   ```\n4. Merge the hotfix into `develop` to synchronize:\n   ```bash\n   git checkout develop\n   git merge hotfix/fix-critical-bug\n   ```\n5. Delete the hotfix branch:\n   ```bash\n   git branch -d hotfix/fix-critical-bug\n   ```\n\n## Sample Workflow\n```\n            hotfix/fix-critical-bug             hotfix/fix-critical-bug\n          --*--                               --*--\nv0.3     /   /      v0.4            v1.0     /   /\n*---*---*---*---*---*---*---*---*---*---*---*---*---*---*  main\n         \\                     /\n          *---*---*---*---*---*---*---*  develop\n               \\         /         \\\n                *---*---*           *---*---*---*---* feature/big-feature\n                        feature/new-feature  \\\n                                              *---*---* UserStory\n```\n\n**Legend**:\n- **`main`**: The stable, production-ready branch.\n- **`develop`**: The integration branch where features are merged before being released.\n- **`feature/*`**: Temporary branches for developing new features.\n- **`hotfix/*`**: Urgent branches for fixing critical bugs directly on `main`.\n- **`*`**: Commit points on the branches.\n- **`v0.3`, `v0.4`, `v1.0`**: Version tags marking stable releases in the `main` branch.\n\n### Branch Structure and Workflow\n\n1. **Main Branch (`main`)**:\n   - Holds stable, production-ready code.\n   - Releases such as **v0.3**, **v0.4**, and **v1.0** are tagged from this branch.\n\n2. **Develop Branch (`develop`)**:\n   - Integrates feature developments.\n   - Changes are merged here before going to `main`.\n\n3. **Hotfix Branch (`hotfix/fix-critical-bug`)**:\n   - Created from `main` for urgent bug fixes.\n   - Once fixed, it's merged into both `main` and `develop` to ensure consistency.\n\n4. **Feature Branches**:\n   - **`feature/new-feature`** and **`feature/big-feature`** are created from `develop` to work on new functionality.\n   - These are merged back into `develop` once the feature is ready.\n\n### Branch Flow\n\n- **Hotfixes** fix urgent issues in `main` and are merged back into `develop`.\n- **Feature branches** are created from `develop`, worked on, and then merged back into `develop`.\n- Once all features are integrated and tested, `develop` is merged into `main` for the next release.\n\n## Branching Workflow Flexibility\n\n- Git treats all branches equally — the roles and purposes of branches are purely **conventional**.\n- Adapt these workflows to suit your project's needs.\n- Understanding the mechanics of branches enables you to design custom workflows that align with your team's requirements and preferences.\n\n## Summary of Key Points\n\n- **Permanent Branches**:\n  - `master` (stable, production-ready code).\n  - `develop` (integration branch for combining features).\n- **Topic Branches**:\n  - Feature branches (encapsulate new features).\n  - Hotfix branches (critical fixes for production).\n- **Best Practices**:\n  - Always branch off from the appropriate branch (`develop` for features, `master` for hotfixes).\n  - Test and review changes before merging.\n  - Delete topic branches after merging to keep the repository clean.\n\n---\n\n# Remote Repositories\n\n## What is a Remote Repository?\n\nA **remote repository** is a version of your project stored outside your local machine. It can be hosted on:  \n- **Platforms**: GitHub, GitLab, or Bitbucket.  \n- **Personal Systems**: Another developer's computer.  \n- **Other Locations**: A network server or a shared file system.  \n\nRemote is nothing but a bookmark(an identifier to path) to other repositories that are not in local.\n\n### Why Use Remote Repositories?  \n- Facilitate collaboration by allowing developers to share code and changes.  \n- Enable distributed development workflows for teams.  \n\n### Best Practices\n1. Use **separate repositories** for individual developers' contributions.  \n2. Create **branches** for feature development within a repository.  \n\n---\n\n## Managing Remote Repositories  \n\nThe `git remote` command helps manage remote repository connections.  \n\n### Listing Remotes  \nTo see all configured remotes:  \n```bash\n# Command\n$ git remote\n\n# Example\n$ git remote\norigin\n```  \nHere, `origin` is the default remote added when a repository is cloned.  \n\nTo view remotes with their URLs:  \n```bash\n# Command\n$ git remote -v\n\n# Example\n$ git remote -v\norigin\tgit@github.com:user/repo (fetch)\norigin\tgit@github.com:user/repo (push)\n```  \n\n---\n\n### Adding a Remote  \nTo add a new remote repository:  \n```bash\n# Syntax\n$ git remote add \u003cremote_name\u003e \u003curl_ssh_http\u003e\n\n# Example\n$ git remote add origin ssh://git@github.com/username/repo.git\n```  \n- `origin`: A common name for the primary remote repository.  \n- `\u003curl\u003e`: The URL of the remote repository, accepts many network protocols including `file://`, `ssh://`, `http://`, and `git://`.  \n\n---\n\n### Deleting a Remote  \nTo remove a remote:  \n```bash\n# Command\n$ git remote rm \u003cbranch_name\u003e\n\n# Example\ngit remote rm origin\n```  \n- This only deletes the reference to the remote from your local repository.  \n- The actual remote repository remains unaffected.  \n\n---\n\n## Working with Remote Branches  \n\n### What are Remote Branches?  \nRemote repositories communicate via **remote branches**. Remote branches are just like local branches, but they represent a \"local\" branch in someone else's repository. Remote branches represent the state of branches in a remote repository. Example: `origin/master` refers to the `master` branch in the `origin` remote repository.  \n\n---\n\n### Fetching Remote Branches  \nThe act of downloading branches from another repository is called **fetching**. Fetching downloads **changes** from the remote repository without merging them into your local branches. \n\nGit will never automatically fetch branches, this needs to be done manually. This is done by design, since one doens't have to worry about others' changes when working in an isolated environment. \n\n#### Fetch a specific branch:\n```bash\n# Syntax\n$ git fetch \u003cremote_name\u003e \u003cbranch_name\u003e\n\n# Example\n$ git fetch origin master\n```  \nDownloads the latest `master` branch from the `origin` remote.  \n\n#### Fetch all branches:\n```bash\n# Syntax\n$ git fetch \u003cremote_name\u003e\n\n# Example\ngit fetch origin\n```  \n\n#### List all remote branches:\nRemote branches are prefixed with remote name and are red in color. \n```bash\n# Syntax\n$ git branch -r\n\n# Example\n$ git branch -r\norigin/master  \norigin/feature/some-feature  \n```  \n\n### List all branches (remote and local): \n```bash\n# Syntax \n$ git branch -a\n\n# Example \n$ git branch\n* main\n$ git branch -r\n  origin/HEAD -\u003e origin/main\n  origin/main\n$ git branch -a\n* main\n  remotes/origin/HEAD -\u003e origin/main\n  remotes/origin/main\n```\n\n#### Color coding \n* **Remote branches** are printed in **red colour**. \n* **Local branches** are printed in **green colour**.\n\n---\n\n### Inspecting Remote Branches  \n\n**Remote branches behave like read-only.** To interact with them, you cannot continue developing them before integrating them into you rlocal repository. This is also done by desing because remote branches are *copies* of other users' commits.   \n\n#### Check out a remote branch:\n```bash\n$ git checkout origin/feature/some-feature\n```  \n**Note:** This puts you in a **detached HEAD** state, where you're not on any local branch.  \n\n#### Compare commits between a local branch and a remote branch:\nThe `..` syntax is very useful for filterning log history. It's a good idea to **run this before merging chagnges** so you know exactly what you're integrating. \n```bash\n$ git log master..origin/master\n```  \n**Result:** Displays commits in `origin/master` that are not in your local `master`.  \n\n--- \n\n## Integrating Changes from Remote Branches\nWe have got the new changes and we inspected them. The next thing is to combine them into working directory. And, the whole point of fetching is to integrate the resulting remote branches into local. \n\n### Merging Changes\nUse `git merge` to integrate changes from a remote branch into your feature branch:\n```bash\n# Syntax\n$ git checkout some-feature\n$ git fetch origin\n$ git merge origin/master\n```\n\nLet's consider an ASCII art expalanation: \n\n**Legend**:\n| Symbol            | Description                                   |\n|-------------------|-----------------------------------------------|\n| `*`               | Individual commits in the repository          |\n| `master`          | The local master branch                       |\n| `origin/master`   | The master branch on the remote repository    |\n| `some-feature`    | A feature branch created off the master branch|\n| `\\` or `/`        | Indicates branch divergence or merging point  |\n\n#### Before the Merge\n```plaintext\n               master      origin/master\n--- ---*---*---*---*---*---*\n                \\\n                 *---*---* some-feature**Summary**\n```\n\n1. **Branches**:\n   - The `master` branch (local) and `origin/master` (remote copy) are updated independently with different commits.\n   - `some-feature` is a separate branch created for a new feature. It was originally branched from `master` but now has additional commits.\n\n2. **Need for Merge**:\n   - To ensure `some-feature` has the latest changes from `origin/master`, a merge is required. This avoids potential conflicts during future integrations.\n\n---\n\n#### After the Merge\n```plaintext\n               master      origin/master\n--- ---*---*---*---*---*---*\n                \\           \\\n                 *---*---*---* some-feature (merged with origin/master)\n```\n\n1. **Integration**:\n   - The changes from `origin/master` are fetched and integrated into `some-feature` using `git merge`.\n   - `some-feature` now includes all updates from the remote master branch (`origin/master`) while retaining its unique commits.\n\n2. **Merged Timeline**:\n   - A new commit is created in `some-feature` to record the merge, showing the integration of the `origin/master` updates.\n\n\n### Rebasing Changes\nUse `git rebase` to update your feature branch with changes from the remote branch by rewriting the commit history.  \n\n```bash\n# Syntax\n$ git checkout some-feature\n$ git fetch origin\n$ git rebase origin/master\n```\n\nLet's consider an ASCII art expalanation: \n\n#### Before the Rebase\n```plaintext\n               master      origin/master\n--- ---*---*---*---*---*---*\n                \\\n                 *---*---* some-feature\n```\n\n#### After the Rebase\n```plaintext\n               master      origin/master\n--- ---*---*---*---*---*---*\n                             \\\n                              *---*---* some-feature (rebased onto origin/master)\n```\n\n#### Explanation of the Rebase Workflow  \n\n**Before the Rebase**  \n- **Branches**:\n  - `some-feature` branch diverged from `master` and has its own unique commits.  \n  - The `origin/master` branch contains new updates that are missing from `some-feature`.  \n\n- **Need for Rebase**:\n  - To apply the updates from `origin/master` onto `some-feature`, ensuring it is up-to-date without creating a merge commit.  \n\n**After the Rebase**  \n- **Rewritten Timeline**:\n  - The commits in `some-feature` are reapplied on top of the latest `origin/master`.  \n  - No merge commit is created, resulting in a cleaner, linear commit history.  \n\n\n### Pulling Changes\n`git pull` combines fetch and merge [rebase] in one step:\n```bash\n$ git pull [--rebase] origin master\n```\n\n#### Setting Rebase as Default for `git pull`\n\nTo always use `rebase` instead of `merge` for `git pull`:\n1. **Globally for all repositories:**\n   ```bash\n   git config --global pull.rebase true\n   ```\n2. **For a specific repository:**\n   ```bash\n   git config pull.rebase true\n   ```\n\n   - To check the current setting:\n    ```bash\n    git config pull.rebase\n    ```\n\n## Pushing Changes to Remote Repositories\nWhen pushing to remote, we create **local** branches in remote. But if the remote where to **fetch** from us, it would create **remote branch**. \n\n### Pushing a Branch\nTo push your local branch to a remote:\n```bash\n# Syntax\ngit push \u003cremote\u003e \u003cbranch\u003e\n\n# Example\ngit push origin my-feature\n```\nThis uploads `my-feature` to the `origin` remote. \n\n**Note**: \n- If the remote workflow is ahead in commit, then we will have to fetch-rebase and send off. \n- `push` adds the changes to remote without notice, imagine seeing lot of changes that you didn't even inted to get. \n  - For example: \n    ```plaintext\n    Mary's Repository before pushing\n    \n    ---*---*---* master\n\n    Mary's Repository after pushing\n\n    ---*---*---* master\n                \\\n                 *---*---* my-feature (local branch, since we pushed it)\n    ```\n  - In the above ASCII art, `my-feature` is **local branch** for Mary, if she had fetched, it would be **remote-branch**. \n\n### `git push -u origin main`\n\nThe command `git push -u origin main` serves two purposes:\n\n#### 1. Push the Local `main` Branch to the Remote `origin` Repository\n\n- `git push`: Pushes the changes from your local repository to the remote repository.  \n- `origin`: Refers to the name of the remote repository (default name when you clone a repository).  \n- `main`: The branch you want to push.  \n\nWhen executed, this command uploads your local `main` branch to the remote repository named `origin`.\n\n---\n\n#### 2. Set the `main` Branch as the Upstream for Future Push/Pull\n\n- `-u` (or `--set-upstream`):  \n  - Links your local `main` branch to the remote `origin/main` branch.  \n  - After this, you can simply use `git push` or `git pull` without specifying the remote and branch name again.  \n\nThis simplifies workflows by establishing a tracking relationship between your local branch and the remote branch.\n\n---\n\n#### Detailed Workflow\n\n##### Scenario  \nYou have a local repository with a `main` branch. The remote repository exists but doesn't yet have a `main` branch.\n\n1. **Before the command:**\n```plaintext\nLocal: main branch exists.\nRemote: No main branch yet.\n```\n\n1. **Run the command:**\n```bash\ngit push -u origin main\n```\n\n1. **Result after the command:**\n- The `main` branch is created in the remote repository and populated with the contents of your local branch.\n- Your local branch now tracks `origin/main`.\n\n```plaintext\nLocal: main (tracking origin/main)\nRemote: main branch now exists.\n```\n\n---\n\n#### Why Use `-u`?\n\n- To save time. Once the tracking relationship is established, you can:\n  - Push updates using `git push` instead of `git push origin main`.\n  - Pull changes using `git pull` instead of `git pull origin main`.\n\n---\n\n#### Example Usage\n\n##### Initial Push\n```bash\n$ git push -u origin main\n```\n\n##### Subsequent Pushes\n```bash\n$ git push\n```\n\n##### Pull Changes\n```bash\n$ git pull\n```\n\nUsing `git push -u origin main` is a common practice when you push a branch to a remote repository for the first time. It simplifies future commands by linking the local branch to its remote counterpart.\n\n---\n\n### Push to Colleague\n- Pushing to a colleague's repository:\n```bash\ngit push mary my-feature\n```\n- Sends your `my-feature` branch to Mary's remote repository.\n\n### Caution with Pushing\n- Avoid creating unnecessary branches on the remote repository:\n  - Pushing creates remote branches visible to all collaborators.\n  - Coordinate with your team to avoid cluttering the repository.\n\n---\n\n## Summary of Remote Repositories\n\n| **Command**| **Description**|\n|------------|----------------|\n| `git remote`| Lists all remote repositories configured in the local repository.|\n| `git remote -v`| Displays the full URLs of the configured remote repositories.|\n| `git remote add remote_name url`| Adds a new remote repository with a friendly name (`remote_name`) and its URL. |\n| `git remote rm remote_name`| Removes the specified remote repository connection.|\n| `git fetch remote_name branch_name`| Fetches updates from the specified branch of the remote repository.|\n| `git fetch remote_name`| Fetches updates from all branches of the specified remote repository.|\n| `git branch -r`| Lists all remote branches available.|\n| **Fetching and Merging**||\n| `git fetch remote_name`| Fetches changes from the remote repository without merging them.|\n| `git merge remote_name/master`| Merges changes from the remote `master` branch into the current branch.|\n| **Shortcut for Fetch + Merge**||\n| `git pull remote_name master`| Fetches and merges changes from the remote `master` branch into the current branch. |\n| **Fetching and Rebasing**||\n| `git fetch remote_name`| Fetches changes from the remote repository without merging them.|\n| `git rebase remote_name/master`| Rebases the current branch on top of the remote `master` branch.|\n| **Shortcut for Fetch + Rebase**||\n| `git pull --rebase remote_name master`| Fetches and rebases changes from the remote `master` branch into the current branch. |\n| **Pushing Changes**||\n| `git push remote_name branch_name`| Pushes the specified local branch to the remote repository.|\n| `git push -u remote_name branch_name` | Pushes the branch and sets the upstream branch for future pushes/pulls.|\n\n---\n\n# Remote Workflows\n\nRemote workflows describe how multiple developers collaborate on a project by sharing code through remote repositories. There are two common models for collaboration:\n\n1. **Centralized Workflow**\n2. **Integrator Workflow**\n\nGit treats all repositories as equal, unlike SVN or CVS, which have a single \"master\" repository. In Git, the **central repository is just a project convention**.\n\n\n## Public (Bare) Repositories\n\n- **Public repositories** are central locations where developers pull and push their changes and collaborate on a project but do not work with it directly. These repositories are designed to be accessible to multiple developers, making it easier to contribute to a shared codebase.\n  \n- **Bare repositories** are a special type of repository that are intended for collaboration. Unlike standard repositories, a bare repository does not contain a working directory (the actual files of the project). This design ensures that the repository is not used for development directly, but rather serves as a central hub where changes are pushed and pulled from.\n\n  - The absence of a working directory in bare repositories prevents accidental overwriting of files and ensures that developers only push their changes, rather than modifying or deleting files directly.\n  \n  - To create a bare repository, you can use the following command:\n    ```bash\n    git init --bare \u003cpath\u003e\n    ```\n\n  - Example: If you want to create a bare repository named `some-repo.git`, you would use:\n    ```bash\n    git init --bare some-repo.git\n    ```\n\nThis setup is ideal for collaboration, as developers will clone this repository and push their changes to it. However, they will not modify files directly in the bare repository itself.\n\n---\n\n## The Centralized Workflow\n\nThe **centralized workflow** is best suited for small teams where **all developers have write access** to the central repository.\n\n### Workflow:\n\n1. **Work locally**: Developers work on their local repositories.\n2. **Merge feature branches**: Once a developer completes a feature, they merge their feature branch into their local `master` branch.\n3. **Push changes**: The developer pushes the merged `master` branch to the central repository.\n4. **Fetch and integrate**: Other developers fetch the latest changes from the central repository and integrate them into their local repositories.\n\n---\n\n### Issues in the Centralized Workflow:\n\nConflicts may arise if multiple developers try to push changes to the central repository simultaneously. For example, if Developer John pushes changes before Developer Mary, she might encounter a **non-fast-forward error**:\n\n```\n! [rejected] master -\u003e master (non-fast-forward)\nerror: failed to push some refs to 'some-repo.git'\n```\n\n#### To resolve the conflict:\n\n1. **Fetch the latest changes** from the central repository:\n   ```bash\n   git fetch origin master\n   ```\n\n2. **Rebase her changes** on top of the latest version from the central repository:\n   ```bash\n   git rebase origin/master\n   ```\n\n3. **Push her changes** to the central repository:\n   ```bash\n   git push origin master\n   ```\n\n---\n\n### Advantages of the Centralized Workflow\n\n- **Simple setup**: Only one central server is required.\n- **Ideal for small teams**: This workflow is well-suited for teams where developers have trusted access to the central repository.\n\n---\n\n## The Integrator Workflow\n\nThe **integrator workflow** addresses **scalability and security concerns** that arise in the centralized model. In this workflow, developers maintain both a **private** and a **public repository**. The **public repository** is used for pushing changes, while an **integrator** (project maintainer) fetches, reviews, and merges those changes into the central project repository.\n\n---\n\n### Workflow in the Integrator Model:\n\n1. **Contributors work on their own repositories**: A contributor makes a fix or adds a feature in **their private repository**.\n2. **Integrator fetches changes**: The integrator **uses a read-only HTTP protocol** to fetch the changes from the contributor's public repository.\n3. **Review and merge**: After reviewing the changes, the integrator merges them into their local branch and pushes the updates to the official repository.\n4. **Limited push access for contributors**: Contributors only need push access to their own repositories, not the central repository.\n\n---\n\n### Security and Scalability in the Integrator Workflow:\n\n- **Security**: Contributors can only push changes to their own repositories, ensuring that no unauthorized changes can reach the central repository.\n- **Scalability**: By allowing independent contributions from many developers, this model avoids bottlenecks in the central repository.\n\n---\n\n### Key Characteristics of the Integrator Workflow:\n\n- **Official repository**: A single official repository is designated for the project, ensuring order and synchronization.\n- **Multiple remotes**: Integrators manage multiple remotes to maintain flexibility and security while handling contributions.\n- **Ideal for open-source projects**: This workflow is particularly effective for **open-source projects** where many developers contribute.\n\n## Comparison of Centralized and Integrator Workflows\n- **Centralized Workflow**: Best for small teams with direct access to the central repository.\n  - Simple and easy to set up but may lead to conflicts when multiple developers push at the same time.\n- **Integrator Workflow**: Ideal for larger teams or open-source projects, offering better security and scalability.\n  - Contributors push to their own repositories, while integrators review and merge changes into the central repository.\n\n### Conclusion\n- Git's distributed nature makes the **integrator workflow** perfect for large-scale open-source projects.\n- The **centralized workflow** is better for small teams but can face issues when multiple developers try to update the central repository at once.'\n\n# Cheat Sheet\n\n| Command  | Description |\n|----------|-------------|\n| **Basic Commands**    |\n| `git config --global user.name \"name\"`| Sets the global Git username for all repositories.|\n| `git config --global user.email \"email\"`| Sets the global Git email for all repositories.|\n| `git config --global core.editor \"editor --wait\"`| Sets the default text editor for Git commands requiring user input, like commit messages.|\n| `git config --global alias.alias_name \"command\"`| Creates a shortcut (alias) for a Git command.|\n| `git help config`| Displays help information about Git configuration options.|\n| _______________________________ |\n| **Git Initialization Commands** | \n| `git init`| Initializes a new Git repository in the current directory.|\n| `git init path`| Initializes a new Git repository at the specified path.|\n| `git clone ssh://\u003cuser\u003e@\u003chost\u003e/path/to/repo[.git]`| Clones a repository from a remote server using an SSH URL with user and host details.|\n| `git clone https://github.com/user/repo[.git]`| Clones a repository from GitHub or another remote server using an HTTPS URL.|\n| `git remote -v`| Displays the list of remote repositories and their URLs.|\n| `git remote url remote_name new_url`| Updates the URL for a specified remote repository.|\n| ______________________________ |\n| **Recording Changes Commands** | \n| `git add`                             | Stages all changes in the working directory for the next commit.                                  |\n| `git add file/folder`                 | Stages specific files or folders for the next commit.                                             |\n| `git rm`                              | Removes files from the working directory and stages the deletion for the next commit.  Makes the file or folder untracked          |\n| `git rm --cached file`                | Removes a file from the staging area without deleting it from the working directory. Makes the file untracked.             |\n| `git rm -r --cached folder`           | Removes a folder from the staging area without deleting it from the working directory. Makes the folder untracked.           |\n| `git status`                          | Shows the status of the working directory and staging area, listing changes to be committed.      |\n| `git diff`                            | Displays unstaged changes in the working directory.                                               |\n| `git diff --cached`                   | Displays changes staged for the next commit.                                                      |\n| `git commit`                          | Commits staged change","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frnaveensrinivas%2Fgit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frnaveensrinivas%2Fgit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frnaveensrinivas%2Fgit/lists"}