<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Gitcommands - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Gitcommands - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 23 Jun 2026 22:44:52 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/gitcommands/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Learn How to Use Git and GitHub – A Beginner-Friendly Handbook ]]>
                </title>
                <description>
                    <![CDATA[ In this handbook, you’re going to dive into something really exciting: Git and GitHub. To start, let’s clear one thing up: Git and GitHub are not the same thing. In short, Git is the tool that runs on your own computer and keeps track of changes in y... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-how-to-use-git-and-github-a-beginner-friendly-handbook/</link>
                <guid isPermaLink="false">693c859b176ed5964e28b921</guid>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Gitcommands ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Sumit Saha ]]>
                </dc:creator>
                <pubDate>Fri, 12 Dec 2025 21:14:03 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1765495440352/0eadf330-7a89-4328-aed1-3c851d279a5d.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this handbook, you’re going to dive into something really exciting: Git and GitHub.</p>
<p>To start, let’s clear one thing up: Git and GitHub are not the same thing.</p>
<p>In short, Git is the tool that runs on your own computer and keeps track of changes in your files, while GitHub is an online platform that lets you store those Git projects in the cloud and collaborate with other people. Git works perfectly fine on its own, but GitHub makes teamwork, sharing, and backup much easier. They’re connected, yes, but completely different.</p>
<p>Think of it this way – Git is the “coffee,” and GitHub is the “coffee shop” where that coffee is served. Fun analogy, right? Don’t worry, in just a moment you’ll see exactly what that means.</p>
<h2 id="heading-what-does-git-do">What Does Git Do?</h2>
<p>So, let’s start by understanding what Git actually is and how it works. Simply put, Git is a powerful tool that constantly keeps track of every change you make to your files - and I mean <em>literally</em> all the time. Day or night, 365 days a year, Git records what changed, when it changed, who changed it, and even where it happened.</p>
<p>Now, what kind of files are we talking about? Almost any kind – not just code. It could be an image, a text file, JavaScript, PHP, Python, or even a video. No matter what you’re working on, Git tracks every single change. Pretty amazing, isn’t it?</p>
<p>But here’s the best part: the magic of Git doesn’t stop there. The coolest thing about Git is that it saves different versions of your files. Imagine you wrote some code and then made a few changes to it after a few days. Now you want to make sure the old version doesn’t get lost. That’s exactly where Git comes to the rescue. It lets you keep multiple versions of the same file effortlessly, and whenever you want, you can roll back to any previous version in just a moment.</p>
<p>By the end of this handbook, you’ll not only understand what Git and GitHub are, but you’ll also be able to use them confidently in real projects. You’ll learn how Git tracks changes locally, how repositories work, how to move changes through Git’s workflow, and how to collaborate with others using GitHub.</p>
<p>We’ll start from the very basics and gradually move toward more advanced concepts like branching, merging, resolving conflicts, and safely undoing mistakes – all with hands-on examples you can follow along with.</p>
<h2 id="heading-heres-what-well-cover">Here’s What We’ll Cover:</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-git">What is Git</a>?</p>
<ul>
<li><a class="post-section-overview" href="#heading-git-vs-github">Git vs GitHub</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-git-architecture-local-and-remote">Git Architecture – Local and Remote</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-install-git-on-your-computer">How to Install Git on Your Computer</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-a-project-and-install-a-local-repository">How to Create a Project and Initialize a Local Repository</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-a-remote-repository-on-github-and-clone-it">How to Create a Remote Repository on GitHub and Clone It</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-track-changes-with-git-status">How to Track Changes with <code>git status</code></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-move-changes-to-the-staging-agrea-with-git-add">How to Move Changes to the Staging Area with <code>git add</code></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-save-work-permanently-with-git-commit-and-configure-git">How to Save Work Permanently with <code>git commit</code> (and Configure Git)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-delete-and-restore-files-with-git-rm-and-git-reset">How to Delete and Restore Files with <code>git rm</code> and <code>git reset</code></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-view-commit-history-with-git-log">How to View Commit History with <code>git log</code></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-branching-and-merging-in-git">Branching and Merging in Git</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-understanding-merge-conflicts">Understanding Merge Conflicts</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-navigate-history-with-git-checkout-and-compare-commits-with-git-diff">How to Navigate History with <code>git checkout</code> and Compare Commits with <code>git diff</code></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-work-with-remotes-git-push-git-fetch-and-git-pull">How to Work with Remotes: <code>git push</code>, <code>git fetch</code>, and <code>git pull</code></a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-example-git-push">Example – <code>git push</code></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-example-pushing-other-branches">Example – Pushing Other Branches</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-example-git-fetch">Example – <code>git fetch</code></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-example-git-pull">Example – <code>git pull</code></a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-undo-local-changes-with-git-restore">How to Undo Local Changes with <code>git restore</code></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-temporarily-shelve-staged-work-with-git-stash">How to Temporarily Shelve Work with <code>git stash</code></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-undo-commits-safely-with-git-revert">How to Undo Commits Safely with <code>git revert</code></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-keep-history-clean-with-git-rebase">How to Keep History Clean with <code>git rebase</code></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-collaborate-on-github-with-pull-requests">How to Collaborate on GitHub with Pull Requests</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-git-amp-github-concise-summary">Git &amp; GitHub – Concise Summary</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-git-vs-github">Git vs GitHub</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-core-git-architecture-amp-workflow">Core Git Architecture &amp; Workflow</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-getting-started">Getting Started</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-seeing-amp-moving-changes">Seeing &amp; Moving Changes</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-deleting-restoring-amp-undoing">Deleting, Restoring &amp; Undoing</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-branching-merging-amp-conflicts">Branching, Merging &amp; Conflicts</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-navigating-amp-comparing-history">Navigating &amp; Comparing History</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-working-with-remotes-github">Working with Remotes (GitHub)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-temporarily-shelving-work-with-git-stash-1">Temporarily Shelving Work with git stash</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-keeping-history-clean-with-git-rebase-1">Keeping History Clean with git rebase</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-collaboration-with-pull-requests-prs">Collaboration with Pull Requests (PRs)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-big-picture-takeaways">Big Picture Takeaways</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-final-words">Final Words</a></p>
</li>
</ol>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li><p><strong>Basic File &amp; Folder Navigation</strong> – Using Finder / File Explorer.</p>
</li>
<li><p><strong>CLI Usage</strong> – Running simple commands in Terminal or Command Prompt.</p>
</li>
<li><p><strong>Text Editor</strong> – Any editor for opening and editing files.</p>
</li>
</ul>
<p>I’ve also created a video to go along with this article. If you’re the type who likes to learn from video as well as text, you can check it out below:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/wNrbaAGE2PY" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<h2 id="heading-what-is-git">What is Git?</h2>
<p>Git is most commonly used in coding projects, but its power goes far beyond just code. You can use Git to keep track of changes and maintain different versions of almost any file. This means you never have to worry about losing a file or accidentally overwriting something important.</p>
<p>Let’s look at a real-life example. Suppose you’re working on a project. You’ve spent hours writing code, your client loves it, and everything’s going great. Then, a month later, the client asks for some new changes. You make the updates as requested. But after a few days, the client comes back and says, “Actually, the old version was better.” Now you’re in trouble, right? Because you’ve already overwritten the original code. How do you get it back?</p>
<p>That’s exactly the kind of problem Git solves. This is why Git is known as a Version Control System – it keeps every version of your files or code safely stored, so you can go back to any previous state whenever you need to, without losing a thing.</p>
<p>Git was created by Linus Torvalds – the same brilliant mind behind Linux. And honestly, what he built is nothing short of genius. Most tools programmers use have a short lifespan, but Git is one of those rare ones that, once you learn it, stays useful for the rest of your career.</p>
<p>The best part? The basics of Git aren’t that hard to learn at all. It’s built around a few simple commands and concepts, and once you understand those, the whole system starts to make perfect sense.</p>
<p>Still, for beginners, Git can feel a little confusing at first – and that’s exactly why this handbook exists. Think of it not just as a tutorial, but as a complete learning resource for learning Git inside and out. We’ll cover all the essential topics you’ll actually use in real-world projects. And if you want to jump to a specific topic, you can easily find it by using the section headings in the table of contents after the intro.</p>
<p>If you follow this tutorial closely, you’ll be able to understand every part of Git, step by step.</p>
<h3 id="heading-git-vs-github">Git vs GitHub</h3>
<p>Now, let’s move on to another important topic: the difference between Git and GitHub. Git is a tool that runs locally on your own computer. It tracks all the changes you make to your files and keeps everything organized.</p>
<p>But imagine this: you and your teammate are working on the same project. You’re coding on your own computer, and your teammate is working from another one. That means you both have different versions of the same project, right? And if your team has more members, there will be even more versions – each saved separately on their own machines.</p>
<p>This is exactly where GitHub comes in. When the project is complete, you’ll need to combine everyone’s work into one place to merge all those changes together. For that, you need a central hub where everyone can upload their updates. You push your work there, your teammate pushes theirs, and GitHub brings it all together.</p>
<p>GitHub acts as that central online server where your team’s entire project lives, making it easy for everyone to see, edit, and share updates in one place, without any confusion.</p>
<p>But GitHub isn’t the only place where you can host your Git repositories. There are other popular platforms too, like GitLab and Bitbucket. These are also widely used and trusted by developers around the world. Still, among all of them, GitHub remains the most popular and widely adopted platform.</p>
<p>That’s why in this tutorial, our focus will mainly be on GitHub. It’s now owned by Microsoft and is maintained with great care and attention. Especially in the programming community and in the world of open-source projects, GitHub’s contribution is truly remarkable.</p>
<p>So without wasting any more time, let’s dive in and explore how Git and GitHub actually work – and see some real-world use cases that will help you understand their power in action.</p>
<h2 id="heading-git-architecture-local-and-remote">Git Architecture – Local and Remote</h2>
<p>Before you start working with Git, the most important thing is to understand its core concept: how it actually works and what its internal structure, or architecture, looks like.</p>
<p>Git is mainly divided into two major parts, <strong>Local</strong> and <strong>Remote</strong>.</p>
<ul>
<li><p>The <strong>Local</strong> part refers to your own computer, where you do all your work. This is where your files, code, and every change you make are stored.</p>
</li>
<li><p>The <strong>Remote</strong> part, on the other hand, lives in the cloud. It’s where you push or upload your local work. In most cases, when you say “remote,” you’re usually referring to GitHub.</p>
</li>
</ul>
<p>Now, let’s start with how the local part works. On your computer, the folder where you’re working on your project is called the <strong>Working Directory</strong>. This is where all the action happens: you write code, create new files, modify existing ones, and make changes as needed. And when you feel like, “Alright, this version looks good, I want to save this change,” that’s when you move on to the next stage in Git’s workflow.</p>
<p>So, what do you do next? You move your work to the “<strong>stage</strong>.” At first, this word might sound a bit unfamiliar, but once you use it a few times, it’ll make perfect sense. In simple terms, when you finish your work in the working directory, staging means you’re saying, “Alright, my changes are ready – they can move to the next step.” This staging process is the second phase in Git’s workflow.</p>
<p>Then comes the third phase where you take the staged files and send them to the local repository. You can think of the staging area as a middle ground – a temporary space where files sit between your working directory and the final save in the repository.</p>
<p>Once you’ve reviewed everything and you’re confident the work is correct, you “commit” it. Committing means permanently saving those changes to your local <strong>repository</strong> – that is, locking them in as a recorded version of your project’s history.</p>
<p>Now you might be wondering, what exactly is a repository? Simply put, a repository is a place where all the versions of your files and their complete change history are stored. In the case of a local repository, it’s a specific folder on your own computer. For a remote repository, it lives on a cloud server, like GitHub.</p>
<p>You can think of a repository as a digital cabinet for your code. It’s a secure place where Git neatly stores every record of your work and every change you’ve ever made. Inside this repository, Git automatically creates a few system files that track everything – your changes, history, commits, and more. These files are managed entirely by Git itself, and the whole system runs based on the data stored within them.</p>
<p>So if we summarize everything so far, it goes like this:</p>
<ol>
<li><p>You work inside your local working directory.</p>
</li>
<li><p>Once you’re done, you stage your changes.</p>
</li>
<li><p>Then you commit those staged files to the local repository.</p>
</li>
</ol>
<p>Up to this point, everything happens only on your own computer – nothing has been sent to the cloud yet. You need the cloud only when you want to share your code with others, access it from another computer, or keep it safely backed up.</p>
<p>That’s when you “push” your local repository to the remote repository. In other words, you upload it to GitHub. Think about it like this: just as you use Google Drive or OneDrive to store files, photos, or documents, you could technically keep everything only on your own device. But you store them in the cloud so that you can access them from anywhere, and even if something gets deleted locally, it stays safe online.</p>
<p>GitHub works the same way. It’s your cloud backup for code. So you see, the main purpose of this whole process is to make collaboration and remote access possible. Having a remote means you can easily send your code from the local repository to a cloud server, and if needed, pull that same code back to any other machine.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765442130301/fa1908c2-c2ef-4a07-86dc-1d7d12b13a21.gif" alt="Git Architecture" width="1138" height="640" loading="lazy"></p>
<p>That’s the core idea of Git, and the foundation of the entire system rests on this simple concept. Beyond that, there’s nothing overly complex. Once you clearly understand this basic workflow, everything else in Git will feel much easier to grasp.</p>
<h2 id="heading-how-to-install-git-on-your-computer">How to Install Git on Your Computer</h2>
<p>Now, let’s see how to get started using Git from scratch.</p>
<p>The very first step before working with Git is installing it on your computer. It might already be installed on your machine, so just check first.</p>
<p>If you do need to install Git, you can download it directly from the <a target="_blank" href="https://git-scm.com/downloads">official website</a>. There, you’ll find different versions for the three major operating systems – Windows, macOS, and Linux. Simply choose the one that matches your system, and you’ll get clear download instructions right there.</p>
<p>If you’re on Windows, click on the Windows option, and you’ll see two download choices: one for 32-bit and another for 64-bit systems. Just pick the one that matches your setup, download it, and run the installer.</p>
<p>For Mac users, when you select the macOS option, you’ll also find instructions on how to install Git using <a target="_blank" href="https://brew.sh/">Homebrew</a>. Just follow those steps, and your installation will be done in no time.</p>
<p>And for those using Linux or other Unix-based systems, you can follow the installation guide provided on the site according to your distribution. The entire process is simple and straightforward.</p>
<p>Once you have Git installed, the next step is to open your terminal or command prompt. If you’re using a Mac, open the Terminal app. For Windows users, you can use either Command Prompt or PowerShell – both will work just fine.</p>
<p>But after installing Git, you’ll usually get a separate terminal called <strong>Git Bash</strong>. You can use that too if you prefer. Many developers like working in Git Bash because it feels very similar to a Linux terminal and makes running Git commands easy and intuitive.</p>
<p>On Windows, you can open Git Bash by right-clicking anywhere inside a folder and selecting <strong>“Git Bash Here”.</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765568453563/43d574fe-ba17-4a8a-b7ae-ec0fa71d84eb.jpeg" alt="Open Git Bash from inside any folder" class="image--center mx-auto" width="916" height="638" loading="lazy"></p>
<p>You can also open it by searching for <strong>Git Bash</strong> from the Start menu.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765568550303/8e54b211-475b-4774-bbf6-6b76674d8fcf.png" alt="Opening Git Bash from Start Menu" class="image--center mx-auto" width="1024" height="576" loading="lazy"></p>
<p>When it opens, you’ll see a terminal window that looks very similar to a Linux or macOS terminal, with a dark background and a command prompt ready to accept Git commands.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765567732235/e6edfc98-778b-47be-a70e-97821fa243c1.png" alt="Git Bash Terminal" class="image--center mx-auto" width="2486" height="1510" loading="lazy"></p>
<p>For the rest of this tutorial, I’ll be using <strong>macOS with the default Terminal app</strong>, but the Git commands themselves are exactly the same on Windows (Git Bash) and Linux. If you’re using Windows or Linux, you can follow along using your terminal of choice – only the way you open the terminal may differ slightly.</p>
<p>So now open your terminal. The first thing you need to do is make sure Git is properly installed, right? To check that, type a simple command in the terminal:</p>
<pre><code class="lang-bash">git --version
</code></pre>
<p>Then press Enter. As soon as you do that, you’ll see an output on the terminal showing the version of Git installed on your machine. Keep in mind that the version number might not be the same for everyone – it depends on when you installed Git and which update you’re using.</p>
<p>If Git is installed correctly, you’ll see this version output. But if it isn’t installed, you’ll get an error message instead. Hopefully, Git is now properly set up on your machine, and you’re ready to start using it.</p>
<h2 id="heading-how-to-create-a-project-and-initialize-a-local-repository">How to Create a Project and Initialize a Local Repository</h2>
<p>Now it’s time to get hands-on and do some practical work. As I mentioned earlier, Git can be implemented in any file or folder, right? So first, you need to create a few files and folders to work with.</p>
<p>Start by navigating to the desktop using the terminal:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> ~/Desktop
</code></pre>
<p>Here, <code>cd</code> is a terminal command that stands for “change directory.” It simply means you’re moving from one folder to another. Hopefully, you’re already familiar with some basic terminal commands like <code>cd</code>, <code>pwd</code>, <code>touch</code>, and <code>mkdir</code>. If not, you can easily learn them using Google or tools like ChatGPT. They’re simple to understand.</p>
<p>Just remember, for Windows users, some of these commands might be slightly different. And keep in mind, commands like <code>cd</code>, <code>pwd</code>, <code>touch</code>, and <code>mkdir</code> are general terminal commands – not Git commands.</p>
<p>Now that you’re inside the Desktop directory, create a new folder where you’ll keep all your project files. Name it <code>git-one</code>:</p>
<pre><code class="lang-bash">mkdir git-one
</code></pre>
<p>Press Enter. You’ve now created a new folder named <code>git-one</code> inside the Desktop directory. Move into that folder like this:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> git-one
</code></pre>
<p>You’re now inside the <code>git-one</code> folder, and this is where your Git project begins. Inside the <code>git-one</code> folder, create two files:</p>
<pre><code class="lang-bash">touch one.txt
touch two.txt
</code></pre>
<p>Next, create another folder named <code>myfolder</code>:</p>
<pre><code class="lang-bash">mkdir myfolder
</code></pre>
<p>Then use <code>cd myfolder</code> to enter the folder. Inside this folder, create another file:</p>
<pre><code class="lang-bash">touch three.txt
</code></pre>
<p>Now check everything you’ve created in your file system. On macOS, for example, you can open the <code>git-one</code> folder in Finder by running:</p>
<pre><code class="lang-bash">open .
</code></pre>
<p>Here, the dot means “the current folder.” As soon as you press Enter, Finder opens up. Inside the <code>git-one</code> folder, you’ll see two files, <code>one.txt</code> and <code>two.txt</code>, and a folder named <code>myfolder</code>, which contains the <code>three.txt</code> file.</p>
<p>Now write something inside each of the files. Open <code>one.txt</code> in a text editor, write <code>one</code>, and save it. Then open <code>two.txt</code>, write <code>two</code>, and save that as well. Finally, go inside the <code>myfolder</code> directory, open <code>three.txt</code>, write <code>three</code>, and save it. Now all three files contain some content.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765442159140/ff01dfea-fe75-4b27-9a91-8133cd538f1f.gif" alt="Finder Open Git One Folder" width="1138" height="640" loading="lazy"></p>
<p>This <code>git-one</code> folder is your <strong>working directory</strong>. As mentioned earlier, this is the folder where you’re doing all your work, and where all your files are stored.</p>
<p>If you want Git to start monitoring everything inside this <code>git-one</code> folder, you have to tell Git, “This is my project folder. Track all the changes here.” To do this, go back to the terminal, make sure you’re inside the <code>git-one</code> folder, and type this:</p>
<pre><code class="lang-bash">git init
</code></pre>
<p>The word <code>init</code> means “initialize.” In other words, you’re telling Git to start working inside this folder from now on. Once you run the command, it shows a message: “Initialized empty Git repository.” That means Git has now started tracking this folder.</p>
<p>So how do you know that? Since you’re inside the <code>git-one</code> folder, type this:</p>
<pre><code class="lang-bash">ls
</code></pre>
<p>You’ll see all the files and folders inside it. Now type:</p>
<pre><code class="lang-bash">ls -la
</code></pre>
<p>Notice that now you can also see a hidden directory named <code>.git</code>. The <code>ls -la</code> command lets you view hidden files and folders.</p>
<p>Operating systems hide certain files and folders by default to protect users from accidentally modifying or deleting critical system data. These hidden files usually store configuration, metadata, or internal information that regular users don’t need to touch. For example, you might see hidden files like <code>.env</code>, <code>.DS_Store</code>, or <code>.config</code> in different projects.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765442184486/d3a47514-cf80-4401-ae98-cb96b8924464.png" alt="Git Init and Hidden .git Folder" width="2560" height="1440" loading="lazy"></p>
<p>You can see a hidden folder named <code>.git</code> inside your project directory. Who created it? Git did. This <code>.git</code> folder is actually the core of the entire project. It’s where Git keeps all its internal data, such as which files have changed, who made the changes, and what the previous versions were. In short, everything Git does is stored right here.</p>
<p>The <code>.git</code> folder is hidden for the same reason: it contains Git’s internal database and configuration. You normally never edit anything inside <code>.git</code> manually. If this folder is deleted or corrupted, Git loses the entire history of the project. Hiding it helps prevent accidental damage.</p>
<p>From now on, Git will be able to track every change you make in your work. Let’s say you make some changes to the three files you created earlier. That means you now have a <strong>local Git repository</strong>. By running <code>git init</code>, Git created the hidden <code>.git</code> folder and started tracking this directory as a repository. From this point on, any changes you make to files inside this folder can be staged, committed, and recorded in Git’s history. Even though you haven’t made a commit yet, the repository already exists locally and is ready to track your work.</p>
<h2 id="heading-how-to-create-a-remote-repository-on-github-and-clone-it">How to Create a Remote Repository on GitHub and Clone It</h2>
<p>You can also create a <strong>remote repository</strong> directly. I mentioned this earlier, so let’s see how to do it. Open your browser again and go to:</p>
<pre><code class="lang-text">https://github.com
</code></pre>
<p>If you’re new, you’ll need to create an account on GitHub first. If you’re already logged in, you’ll see your profile. On the left side, you can see your repositories, feeds, and other details. Your goal is to store your local files on GitHub.</p>
<p>To do that, you need to create a new repository on GitHub. Click the blue <strong>New</strong> button. Just like you used <code>git init</code> to create a local repository, here you can initialize one in the cloud. Give it a name – for example, <code>git-journey</code> – and in the description, write something like “You are learning Git and GitHub.” Keep it public so everyone can view it. Then click the <strong>Create Repository</strong> button. You’ve now created a new repository on GitHub.</p>
<p>Right now, the repository is completely empty – it doesn’t have any files in it. To add some files, click the <strong>Create a new file</strong> button, name it <code>one.txt</code>, and inside the file, write <code>one</code>. Then click the <strong>Commit changes</strong> button. The term “commit” basically means “save.” Committing is like saving a file – nothing complicated. Don’t worry about this too much now, as I’ll explain commits in more detail later.</p>
<p>For now, there’s already a default commit message saying “Create one.txt,” so you can keep that as it is and click <strong>Commit changes</strong>. Next, create another file the same way – this time naming it <code>two.txt</code>, writing <code>two</code> inside, and saving it. Now, if you check your GitHub repository, you can see two files there: <code>one.txt</code> and <code>two.txt</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765442212397/732bc0ff-60e4-4d43-a863-b1760453ec80.gif" alt="GitHub New Repository with Two Files" width="1138" height="640" loading="lazy"></p>
<p>At this point, you have two repositories – one on the cloud (GitHub), and another one locally on your computer. You initialized the local one yourself earlier, but now you want to bring the GitHub repository down to your machine by <strong>cloning</strong> it.</p>
<p>Go back to your terminal. Suppose you’re currently inside the <code>git-one</code> folder, but you want to clone the remote repository onto your Desktop. In the terminal, type:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> ../
</code></pre>
<p>This command takes you back to the Desktop. Now, you’re going to clone the remote repository – the one you just created on GitHub. For that, you need a link, which is the repository’s URL. Go back to GitHub, open that repository, and click on the <strong>Code</strong> button. There, you’ll see an HTTPS link. Copy that link. Then, in the terminal, type the following:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> &lt;repository-https-link&gt;
</code></pre>
<p>Replace <code>&lt;repository-https-link&gt;</code> with the link you just copied, and press Enter. Git pulls your GitHub repository down onto your local machine.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765442236567/d4ad9633-897c-421b-979f-121c77573078.gif" alt="Cloning GitHub Repository" width="1138" height="640" loading="lazy"></p>
<p>After a few moments, the cloning process is complete. To verify whether the repository has been successfully cloned, type in the terminal:</p>
<pre><code class="lang-bash">ls
</code></pre>
<p>Remember that this command shows the list of folders in your current location. You’ll see a new folder named <code>git-journey</code>, alongside your previous <code>git-one</code> folder. Enter the <code>git-journey</code> folder like this:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> git-journey
</code></pre>
<p>You’re now inside the <code>git-journey</code> directory. If you type this:</p>
<pre><code class="lang-bash">ls
</code></pre>
<p>you can see the contents of the folder. Inside it you should see the two files, <code>one.txt</code> and <code>two.txt</code>. To see hidden files, type:</p>
<pre><code class="lang-bash">ls -a
</code></pre>
<p>You’ll find a <code>.git</code> folder here as well. That proves this is also a complete Git repository, cloned from the cloud. Earlier, you saw the same thing in your local repository, right? So, this is how you can create a Git repository in two ways – one by initializing it locally, and the other by cloning it from GitHub or any other remote server. No matter which way you create it, to start working with Git, initialization is always required.</p>
<h2 id="heading-how-to-track-changes-with-git-status">How to Track Changes with <code>git status</code></h2>
<p>Now let’s look at something new. Suppose you’re currently inside the <code>git-journey</code> folder. This is the repository you just cloned from the remote, right? If you make any changes to this repository – for example, you open the file <code>one.txt</code> in a text editor, keep everything as it was, but add the number <code>1</code> at the end and save the file – you might want to know what exactly changed, or whether Git has detected the modification.</p>
<p>To check that, type in the terminal:</p>
<pre><code class="lang-bash">git status
</code></pre>
<p>As soon as you run this command, Git immediately tells you: <code>modified - one.txt</code>. This means Git has already detected the change you made in that file.</p>
<p>Now let’s say you make a small change in <code>two.txt</code> as well – just adding a <code>2</code> at the end – and then run <code>git status</code> again. This time it shows <code>modified - two.txt</code>. That means both files have been changed, and Git has detected both modifications.</p>
<p>This is exactly how Git continuously keeps an eye on every change you make. It’s like it’s always watching over your project. At any moment, you can run the <code>git status</code> command to see which files have been modified or updated.</p>
<p>In a real project, you’ll often work with multiple files at the same time, right? In that case, <code>git status</code> gives you a clear summary of the overall situation: what has changed, which files are new, and which ones are modified.</p>
<p>So, up to this point, you’ve learned that you can initialize Git in two ways – either locally or from a remote repository. And with <code>git status</code>, you can easily check what changes have been made in your working directory.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765442263827/d48beb32-1dcf-4dc6-81df-a64adced52c1.gif" alt="Git Status Showing Modified Files" width="1138" height="640" loading="lazy"></p>
<p>Now let’s move out of the working directory into the staging area.</p>
<h2 id="heading-how-to-move-changes-to-the-staging-area-with-git-add">How to Move Changes to the Staging Area with <code>git add</code></h2>
<p>So far, you’ve only worked inside the <strong>working directory</strong>. That means you’ve created and modified files, but you haven’t yet told Git to keep those changes. Now you’re going to move them into the <strong>staging area</strong>.</p>
<p>In Git’s terminology, the process of moving changes from the working directory to the staging area is called <strong>adding</strong>. Simply put, <code>git add</code> means telling Git, “I want to keep this change.” Right now, inside the <code>git-journey</code> folder, you have two files, and both have been modified.</p>
<p>Now create another folder inside <code>git-journey</code>, named <code>myFolder</code>:</p>
<pre><code class="lang-bash">mkdir myFolder
</code></pre>
<p>Use <code>cd myFolder</code> to enter that folder. Inside <code>myFolder</code>, create a new file named <code>three.txt</code>:</p>
<pre><code class="lang-bash">touch three.txt
</code></pre>
<p>Open <code>three.txt</code> in your text editor, write <code>three</code>, and save the file. Now, you’ve made quite a few changes:</p>
<ul>
<li><p>You created a new folder.</p>
</li>
<li><p>You added a new file.</p>
</li>
<li><p>You modified some existing ones.</p>
</li>
</ul>
<p>Your entire project has gone through multiple changes. Go back to the repository’s root folder (the <code>git-journey</code> folder) by running this:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> ..
</code></pre>
<p>From here, check which files have actually been changed:</p>
<pre><code class="lang-bash">git status
</code></pre>
<p>Git shows that two text files have been modified, and a new folder has been created. Git also says that the old files are “tracked,” while the new folder is “untracked.” Why is that? Because the old files came from the remote repository you cloned earlier, so Git already knows about them. But since <code>myFolder</code> is newly created, Git doesn’t recognize it yet.</p>
<p>If you want to move everything to the staging area at once, you have two options: use <code>git add --all</code> or the shorter version <code>git add -A</code>. Both commands do exactly the same thing. Try it out:</p>
<pre><code class="lang-bash">git add --all
git status
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765442889338/448d6a6e-df96-4e74-be07-13d285f3ca5f.png" alt="Git Add All and Status" width="2560" height="1440" loading="lazy"></p>
<p>Git has staged everything. All the changes you made are now “ready to commit.” You’ll learn more about commits in detail later. For now, just remember that when you use <code>git add --all</code>, Git takes every change and prepares it for the next commit. If you want to go back to the previous state – that is, remove everything from the staging area and return them to the working directory – type this:</p>
<pre><code class="lang-bash">git reset
git status
</code></pre>
<p>You’ll notice everything is back to the earlier state.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765442910152/1b8a64da-813c-4925-846f-0a0b5527aa76.gif" alt="Git Reset and Status" width="1138" height="640" loading="lazy"></p>
<p>Now try <code>git add -A</code>:</p>
<pre><code class="lang-bash">git add -A
git status
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765442932087/5eb27c66-5fee-4d87-bc11-2fee381e9288.png" alt="Git Add A and Status" width="2560" height="1440" loading="lazy"></p>
<p>You’ll see that Git has staged everything again. So whether you use <code>git add --all</code> or <code>git add -A</code>, both do the same thing – Git stages every change. Next, run:</p>
<pre><code class="lang-bash">git reset
git status
</code></pre>
<p>Everything is unstaged again. Now, in this state, if you type this:</p>
<pre><code class="lang-bash">git add .
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765442982841/bb3acfb7-b236-4230-8fd8-f48ef9c69093.png" alt="Git Add Dot and Status" width="2560" height="1440" loading="lazy"></p>
<p>at first glance it seems like it’s doing the same thing as <code>git add --all</code>, as everything appears to be staged. But there’s an important difference. Reset again:</p>
<pre><code class="lang-bash">git reset
</code></pre>
<p>Now go inside the <code>myFolder</code> directory:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> myFolder
git add .
git status
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443005193/c5d8a16e-d85d-431c-a56a-2a79326980fb.gif" alt="Git Add Dot Inside Folder and Status" width="1138" height="640" loading="lazy"></p>
<p>Git has only staged the <code>three.txt</code> file that’s inside <code>myFolder</code>. The other files in the root folder are still unstaged. This difference is really important:</p>
<ul>
<li><p><code>git add --all</code> or <code>git add -A</code> stage every change across the entire project.</p>
</li>
<li><p><code>git add .</code> stages only the changes within the <strong>current directory</strong> (and its subdirectories).</p>
</li>
</ul>
<p>Also, if there were a subfolder inside <code>myFolder</code>, using the dot would still include the files inside that subfolder too. In simple terms, the dot means “the current directory and everything inside it.”</p>
<p>So now you’ve seen three variations of the <code>git add</code> command: <code>--all</code>, <code>-A</code>, and <code>.</code> (dot). The first two work exactly the same way, while the dot version is limited to the current directory. Now run:</p>
<pre><code class="lang-bash">git reset
git status
</code></pre>
<p>to bring everything back again. Return to the root folder:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> ..
</code></pre>
<p>And stage everything again:</p>
<pre><code class="lang-bash">git add --all
</code></pre>
<p>Now all files are ready to commit. At this point, imagine you make some changes directly in the working directory. For example, you delete the file <code>two.txt</code> and create a new one named <code>four.txt</code>, writing <code>four</code> inside it. That means you’ve deleted one file and added another new one.</p>
<p>Check the status:</p>
<pre><code class="lang-bash">git status
</code></pre>
<p>Git shows that under “Changes to be committed,” the previously staged files are still there. But under “Changes not staged for commit,” it now lists <code>two.txt</code> as deleted and <code>four.txt</code> as untracked. Now type:</p>
<pre><code class="lang-bash">git add *
git status
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443030396/e69e74ab-9980-48f4-bf94-dd1fe525faea.png" alt="Git Add Asterisk and Status" width="2560" height="1440" loading="lazy"></p>
<p>Git has staged the newly created <code>four.txt</code> file, but it hasn’t staged the deleted <code>two.txt</code> file. That’s why it’s important to understand that <code>git add *</code> only stages <strong>new or modified files</strong>, but <strong>not deleted ones</strong>. So to summarize:</p>
<ul>
<li><p><code>git add *</code> stages visible new/modified files, but not deletions.</p>
</li>
<li><p><code>git add .</code> stages changes in the current directory, including modifications and deletions.</p>
</li>
<li><p><code>git add -A</code> / <code>git add --all</code> stage all changes (additions, modifications, deletions) across the entire repo.</p>
</li>
</ul>
<p>Reset again:</p>
<pre><code class="lang-bash">git reset
git status
</code></pre>
<p>If you want to stage only a specific file – say <code>one.txt</code>, which has been modified – you can do that by typing:</p>
<pre><code class="lang-bash">git add one.txt
</code></pre>
<p>Similarly, if you want to stage a file inside a folder (for example the file inside <code>myFolder</code>) you can write:</p>
<pre><code class="lang-bash">git add myFolder/three.txt
</code></pre>
<p>You can also stage a single file like this:</p>
<pre><code class="lang-bash">git add two.txt
git status
</code></pre>
<p>You’ll see that only <code>two.txt</code> has been staged. You can also stage files by their extension. For example, to stage all <code>.txt</code> files:</p>
<pre><code class="lang-bash">git reset
git add *.txt
git status
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443054715/07804ce7-1389-41bf-a48a-f2e83c3c3456.gif" alt="Git Add Txt Files and Status" width="1138" height="640" loading="lazy"></p>
<p>This command stages all <code>.txt</code> files in the current directory, excluding deleted ones and excluding files inside subfolders.</p>
<p>Finally, if you want to stage <strong>everything</strong> at once, a simple and common practice is to go to the root directory and type:</p>
<pre><code class="lang-bash">git add .
git status
</code></pre>
<p>All the changes are now staged together. That means all your changes have been moved from the working directory to the staging area.</p>
<h2 id="heading-how-to-save-work-permanently-with-git-commit-and-configure-git">How to Save Work Permanently with <code>git commit</code> (and Configure Git)</h2>
<p>So far, you’ve learned how to move changes from the working directory to the staging area using the <code>git add</code> command. Now let’s see how to save those changes from the staging area to the local repository. In Git’s language, this is called a <strong>commit</strong>. It means you’re confirming and saving your changes permanently.</p>
<p>You can think of it like getting ready for a party. You don’t just walk straight out the door. First, you stand in front of a mirror and check your clothes, shoes, accessories, and hair. That’s the stage where you make adjustments – maybe you realize, “This shirt doesn’t look good,” or “Let me change these shoes.” That’s an intermediate step. You haven’t left for the party yet – you’re just making sure everything is in order. If something’s off, you can fix it right there. Once you’re satisfied and everything looks perfect, that’s when you finally leave for the party.</p>
<p>Git works in the same way. Instead of going straight from the working directory to the local repository, you first move your changes to the staging area. This is an intermediate step where you can review, adjust, or even remove changes before saving them permanently. You don’t commit directly from the working directory because the staging area gives you a chance to verify everything before finalizing. When you finally “commit,” it means you’re sure everything is correct – no more mistakes – and now the work can be saved permanently. That’s why this process is called a commit.</p>
<p>First, check your current state:</p>
<pre><code class="lang-bash">git status
</code></pre>
<p>It shows that the staging area contains some changes that are ready but not yet committed. To commit them, write this:</p>
<pre><code class="lang-bash">git commit -m <span class="hljs-string">"I have made some changes to files"</span>
</code></pre>
<p>The <code>-m</code> flag lets you add a short message describing what you changed.</p>
<p>Sometimes an error may appear the first time you try to commit. When you install Git for the first time and attempt a commit, you might see a message like this:</p>
<pre><code class="lang-text">*** Please tell me who you are
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443087625/11b0ecda-49e6-48e6-9171-4b3ec11f4478.png" alt="Git Commit Error - Please Tell Me Who You Are" width="2560" height="1440" loading="lazy"></p>
<p>This is completely normal. It’s just Git’s way of asking for your identity before recording a commit. Git needs to know who is making the changes and from which email address. This information is attached to every commit in the project history, which later helps track who made which changes.</p>
<p>Fixing this issue is simple. Git tells you exactly what to do. Run the following two commands:</p>
<pre><code class="lang-bash">git config --global user.email <span class="hljs-string">"your@email.com"</span>
git config --global user.name <span class="hljs-string">"your name"</span>
</code></pre>
<p>By running these two commands, the problem is solved. The first command sets your email address, and the second sets your name. The <code>--global</code> flag means that this configuration will apply to your entire computer - so every Git commit you make from this machine will use the same name and email.</p>
<p>If you want to make the configuration specific to a single project, you can use the <code>--local</code> flag instead. That way, the settings will apply only to that particular repository.</p>
<p>In short, when you use Git for the first time, setting up your user configuration is mandatory. It’s part of the basic Git setup you need to do before committing. Once it’s configured, Git will automatically recognize your identity for all future commits. If Git is already configured, you don’t need to set it up again.</p>
<p>Now, let’s go back to the main task of making a commit:</p>
<pre><code class="lang-bash">git commit -m <span class="hljs-string">"I have made some changes to files"</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443109452/9960deef-7e54-46f0-b0a2-328ab52a2b4a.png" alt="Git Commit Successful" width="2560" height="1440" loading="lazy"></p>
<p>Now the commit is done. The terminal shows how many files were changed, how many lines were added, and how many were deleted. You can verify everything by checking the status:</p>
<pre><code class="lang-bash">git status
</code></pre>
<p>Everything looks clean now, meaning all the changes have been successfully saved in the local repository. From now on, whenever you make new changes to any file, you’ll have to stage and commit them again, just like before.</p>
<p>One more thing about commits: you can always roll back to the previous state if needed. To do that, type the following:</p>
<pre><code class="lang-bash">git reset HEAD~
git status
</code></pre>
<p>This command will undo the last commit and bring everything back to the working directory. You’ll see that all the files have returned to the working directory, ready to be staged again. You can now modify or commit them as you wish.</p>
<p>This shows how much control Git gives you over your work. It’s just about remembering the right commands.</p>
<p>Before we move on to deleting and restoring files, go ahead and make a new commit again so you’re working from a clean state:</p>
<pre><code class="lang-bash">git add .
git commit -m <span class="hljs-string">"I have made some changes to files"</span>
</code></pre>
<h2 id="heading-how-to-delete-and-restore-files-with-git-rm-and-git-reset">How to Delete and Restore Files with <code>git rm</code> and <code>git reset</code></h2>
<p>Now the commit is done. Manually delete the <code>one.txt</code> file from your file system and then go back to the terminal. Type:</p>
<pre><code class="lang-bash">git status
</code></pre>
<p>Git shows that <code>one.txt</code> has been deleted. If you then type:</p>
<pre><code class="lang-bash">git add .
</code></pre>
<p>the deletion will also be staged. Instead of deleting a file manually and then adding it again, you can perform both steps in a single command. If you want to delete a file and stage that deletion at the same time, type:</p>
<pre><code class="lang-bash">git rm four.txt
</code></pre>
<p>Here, <code>four.txt</code> is just an example. This command deletes <code>four.txt</code> and automatically moves that change to the staging area. Once you run this and check the status:</p>
<pre><code class="lang-bash">git status
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443133023/f9d77e54-9829-4ff2-bd45-9e91b520bef0.gif" alt="Git Rm and Status" width="1138" height="640" loading="lazy"></p>
<p>you’ll notice that <code>four.txt</code> has been deleted and staged. You no longer have to perform two separate steps – deleting and adding manually. You can do both at once with this shortcut.</p>
<p>If you check in your file explorer, you’ll see that <code>four.txt</code> has disappeared. Now, roll back the deleted file using <code>git reset</code>. When you run a regular <code>git reset</code>, it only brings back the <strong>staged changes</strong>, not the deleted files. You’ll see the message “Unstaged changes after reset.” But if you check your file system, the deleted file hasn’t returned. That’s because a regular reset only brings back staging information, not the physical file. You can confirm this with:</p>
<pre><code class="lang-bash">git status
</code></pre>
<p>You’ll notice only the changes are back, and that manually deleted files are still missing. If you want to restore everything (both the changes and the deleted files) you have to run:</p>
<pre><code class="lang-bash">git reset --hard
</code></pre>
<p>Once you execute this, both your changes and the deleted files return to their previous state.</p>
<p>Now let’s explore the use of <code>git rm</code> a bit deeper. Suppose you want to remove a file. First, reset everything:</p>
<pre><code class="lang-bash">git reset --hard
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443156544/ba29878e-c5b8-48a8-8110-d7f80bc9d5be.gif" alt="Git Reset Hard" width="1138" height="640" loading="lazy"></p>
<p>Now you’re back to your original state. Edit the <code>four.txt</code> file and write <code>4</code> inside it. That means there’s now a modification in the working directory. If you try to delete it directly using:</p>
<pre><code class="lang-bash">git rm four.txt
</code></pre>
<p>the file isn’t deleted, and Git shows an error: “the following file has local modifications.” This means Git isn’t allowing the deletion because it has detected uncommitted changes in that file.</p>
<p>Before you can remove it, you either have to commit those changes or confirm that you truly want to discard them. If you’re sure you want to delete the file anyway, you can force it by using:</p>
<pre><code class="lang-bash">git rm -f four.txt
</code></pre>
<p>As soon as you run this command, the file is forcefully deleted. If you check your file explorer, you’ll see that <code>four.txt</code> is gone. Now consider another situation. Run another hard reset:</p>
<pre><code class="lang-bash">git reset --hard
</code></pre>
<p>This brings everything back again. Modify <code>four.txt</code> by writing <code>hello</code> inside it. Now, if you type:</p>
<pre><code class="lang-bash">git rm --cached four.txt
</code></pre>
<p>this removes the file from the staging area but keeps it physically in your working directory. Check it:</p>
<pre><code class="lang-bash">git status
</code></pre>
<p>You’ll see that <code>four.txt</code> has moved to the “Untracked files” section: it’s no longer staged, but the file itself still exists in the system. That’s the difference between the <code>--force</code> and <code>--cached</code> flags:</p>
<ul>
<li><p><code>git rm -f</code> completely deletes the file.</p>
</li>
<li><p><code>git rm --cached</code> removes the file from staging (and from tracking), but keeps it in your working directory.</p>
</li>
</ul>
<p>Another useful command is:</p>
<pre><code class="lang-bash">git rm -r folder
</code></pre>
<p>Here, the <code>-r</code> flag stands for “recursive.” This means if the folder contains other subfolders or files, all of them will be removed recursively. If you mention the folder name without <code>-r</code>, then only that folder will be removed, not its contents. Try this out. Reset everything again:</p>
<pre><code class="lang-bash">git reset --hard
</code></pre>
<p>Now experiment with <code>myFolder</code>:</p>
<pre><code class="lang-bash">git rm -r myFolder
git status
</code></pre>
<p>The folder is deleted from your file system as well, and <code>myFolder</code> is listed as deleted and staged automatically. Reset everything again:</p>
<pre><code class="lang-bash">git reset --hard
</code></pre>
<h2 id="heading-how-to-view-commit-history-with-git-log">How to View Commit History with <code>git log</code></h2>
<p>So far, you’ve made quite a few commits. Now you’ll learn how to view those commits. Viewing commits means checking the <strong>commit log</strong>. In the terminal, type:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">log</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443180087/c4acc03d-e2a2-424e-b6e7-30b7cec94ddd.gif" alt="Git Log Showing Commit History" width="1138" height="640" loading="lazy"></p>
<p>You’ll see the full commit history. You might see three commits, for example. Along with each one, there are details and messages that clearly describe what was done in that commit.</p>
<p>You’ll also notice long random strings which are <strong>commit IDs</strong>. Using these IDs, you can go back to previous versions later on. The first two commits might be the ones created when you made files while setting up your GitHub repository, and the last one might be when you modified some files recently.</p>
<p>If you want to view this log in a cleaner, more compact format, you can use:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">log</span> --oneline
</code></pre>
<p>Once you run it, you’ll see a short summary of each commit with just the essential information. The commit IDs are also shown in a shortened format. These shortened IDs can also be used to return to any previous version later on.</p>
<h2 id="heading-branching-and-merging-in-git">Branching and Merging in Git</h2>
<p>Now let’s move on to one of Git’s most powerful and important features: <strong>branching</strong>. At the moment, your repository has only one branch. A branch in Git is like a separate line of development where you can work independently.</p>
<p>If you check the online repository you cloned earlier, you’ll see that the default branch is called <strong>main</strong>. This is the default branch where all work begins. In recent times, Git has shifted from calling it “master” to “main,” but the idea remains the same: the main branch is your project’s central line of development.</p>
<p>To understand branching more simply, imagine you’re working in the kitchen of a large restaurant. The <strong>main branch</strong> is the main kitchen where all the dishes are prepared and served to customers. Now, if your client wants to try a new dish or recipe, you wouldn’t experiment directly in that main kitchen, because if something goes wrong, it could ruin everything.</p>
<p>Instead, you create a separate <em>test kitchen</em> where you can safely prepare and test the new dish. Once the recipe is perfected, you bring it back into the main kitchen to serve it officially.</p>
<p>Git works exactly the same way. Instead of making changes directly in the main branch, you create a separate <strong>development branch</strong> where you test and commit all your changes. Once everything is stable and verified, you merge that branch back into the main branch. This ensures that your main project stays safe, while new features can be developed and tested without breaking anything.</p>
<p>In short, branching in Git provides a secure and organized intermediate step that allows you to review, test, and manage changes before merging them into the main codebase.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443203531/fa09c9c1-c1e6-4617-bc35-8d16c7902b4d.gif" alt="Git Branching and Merging" width="1138" height="640" loading="lazy"></p>
<p>Since I’ve already mentioned the word “merge”, let’s understand what it means. <strong>Merging</strong> simply means combining the changes from two branches into one. It’s an important concept for understanding how branches work.</p>
<p>In Git, you can create multiple branches – like <code>staging</code>, <code>development</code>, <code>frontend</code>, or <code>backend</code> – and work on each of them separately. Once all the changes are finalized and tested, they’re merged back into the main branch.</p>
<p>Right now, your application has only one branch. To see how many branches you have, type:</p>
<pre><code class="lang-bash">git branch
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443230339/361868df-dc2f-4b01-8773-5a6b16fb721f.png" alt="Git Branch Command" width="2560" height="1440" loading="lazy"></p>
<p>This command shows the list of all branches. At the moment, you may have only one, and the branch you’re currently in has a star (<code>*</code>) next to it.</p>
<p>To create a new branch, type <code>git branch</code> followed by the branch name. For example:</p>
<pre><code class="lang-bash">git branch development
git branch
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443248217/e70e516a-1601-401e-a02a-6a25d020b97a.png" alt="Git Create New Branch" width="2560" height="1440" loading="lazy"></p>
<p>You’ll see two branches listed: <code>main</code> and <code>development</code>. The star next to <code>main</code> means you’re still on the main branch. You can easily switch from one branch to another.</p>
<p>When a new branch is created, it takes the exact state of the branch you were on at that moment. So, in this case, the <code>development</code> branch is an exact copy of the <code>main</code> branch. Whenever you create a new branch, it inherits the current state of the branch you’re in.</p>
<p>Now that you’ve created a new branch, switch to it:</p>
<pre><code class="lang-bash">git checkout development
git status
</code></pre>
<p>You’re now inside the <code>development</code> branch. If you check the status, everything looks clean, because the <code>development</code> branch was created with the same content as <code>main</code>. Go to your file system and create a new file named <code>three.txt</code>. Inside it, write <code>three</code>. Then, back in the terminal:</p>
<pre><code class="lang-bash">git status
git add .
git commit -m <span class="hljs-string">"I created three.txt and entered three there"</span>
</code></pre>
<p>Now your commit is done inside the <code>development</code> branch. Next, switch back to the main branch:</p>
<pre><code class="lang-bash">git checkout main
</code></pre>
<p>When you check your file system now, you’ll notice that <code>three.txt</code> is no longer there. Why? Because the changes made in the <code>development</code> branch exist only in that branch. Those changes haven’t been merged into <code>main</code> yet. The moment you switch back to <code>main</code>, Git automatically hides the changes made in <code>development</code>, showing you only what exists in the main branch.</p>
<p>This demonstrates how much control Git has over your file system. When you switch branches, Git instantly adjusts which files are visible so that you only see the changes relevant to that specific branch. There’s no duplication or conflict in your file system, as Git manages everything seamlessly.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443271077/5e9a82df-941f-4692-8eb9-56da9e784085.gif" alt="Git Switch Branches and Isolated Changes" width="1138" height="640" loading="lazy"></p>
<p>In this way, you can create hundreds of branches, each containing its own set of changes, and Git will always show you a separate, isolated view for each one.</p>
<p>For any change to take effect, you must commit it. Whatever branch you’re working in, the commit must be made there. Once committed, Git understands that those changes belong exclusively to that specific branch. That’s why, when you switch back to the main branch, the changes made in the <code>development</code> branch don’t appear there.</p>
<p>Now suppose you make a new change to the <code>four.txt</code> file while you’re on the <code>main</code> branch – you add a <code>4</code> to it. Then, if you check the status:</p>
<pre><code class="lang-bash">git status
git add .
git commit -m <span class="hljs-string">"I changed four.txt and added additional 4"</span>
</code></pre>
<p>Now, both branches have changes – the <code>main</code> branch has this new commit, and the <code>development</code> branch still has its previous one. Since both branches now contain updates, you’ll need to merge the changes.</p>
<p>First, switch to the <code>development</code> branch:</p>
<pre><code class="lang-bash">git checkout development
</code></pre>
<p>Now run:</p>
<pre><code class="lang-bash">git merge main -m <span class="hljs-string">"merging main into development"</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443302835/c0510bc0-f03f-4203-9d51-b2bac312af5a.png" alt="Git Merge Main into Development" width="2560" height="1440" loading="lazy"></p>
<p>After the merge, the changes made in the <code>main</code> branch appear inside the <code>development</code> branch as well. For example, the updated <code>four.txt</code> file is now present in the <code>development</code> branch alongside the previous changes. Both branches’ updates have been combined, and the <code>development</code> branch now reflects all the latest modifications.</p>
<p>Next, switch back to the <code>main</code> branch:</p>
<pre><code class="lang-bash">git checkout main
</code></pre>
<p>The changes from the <code>development</code> branch haven’t yet appeared here. From <code>main</code>, merge everything from <code>development</code>:</p>
<pre><code class="lang-bash">git merge development -m <span class="hljs-string">"merging on main with development"</span>
</code></pre>
<p>After running this command, you’ll see that the <code>three.txt</code> file from the <code>development</code> branch now appears in <code>main</code> as well. Both branches’ changes have been successfully merged, and the merge process is complete.</p>
<h3 id="heading-understanding-merge-conflicts">Understanding Merge Conflicts</h3>
<p>Sometimes during a merge, conflicts may occur. A <strong>merge conflict</strong> happens when the same part of a file has been changed differently in two branches.</p>
<p>For example, if you modified <code>one.txt</code> in the <code>main</code> branch and someone else modified the exact same section of <code>one.txt</code> in the <code>development</code> branch, Git won’t know which version to keep.</p>
<p>In such cases, Git flags the file as having a conflict, and you have to resolve it manually by deciding which changes to keep – or by merging both versions yourself.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443321837/154fb298-dd45-496f-b1c9-cc68c6b228c2.gif" alt="Git Merge Conflict Example" width="1138" height="640" loading="lazy"></p>
<p>Right now, you’re on the <code>main</code> branch. From here, you’ll create a new branch so that <code>main</code> remains untouched while you simulate a conflict. Run:</p>
<pre><code class="lang-bash">git branch staging
git checkout staging
</code></pre>
<p>This creates a new branch named <code>staging</code>, which contains all the latest updates from <code>main</code>, and switches you to it. While working on the <code>staging</code> branch, go to <code>four.txt</code>. At the end of this file, there was the number <code>4</code>. Add <code>44</code> at the end and save the file. Now the <code>staging</code> branch has a change.</p>
<p>Run the following:</p>
<pre><code class="lang-bash">git status
git add .
git commit -m <span class="hljs-string">"changed 44"</span>
</code></pre>
<p>The <code>staging</code> branch work is done. Next, switch back to the <code>development</code> branch:</p>
<pre><code class="lang-bash">git checkout development
</code></pre>
<p>When you open <code>four.txt</code> here, you don’t see the <code>44</code> you added earlier in <code>staging</code>. So, write <code>444</code> and save the file. Then run:</p>
<pre><code class="lang-bash">git add .
git commit -m <span class="hljs-string">"added 444 on four.txt"</span>
</code></pre>
<p>The <code>development</code> branch now has its own separate change. While staying in the <code>development</code> branch, try to merge the changes from the <code>staging</code> branch:</p>
<pre><code class="lang-bash">git merge staging
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443344910/2991cf21-6397-45cb-aa96-70467a1244f8.png" alt="Git Merge Conflict Error" width="2560" height="1440" loading="lazy"></p>
<p>Git fails to merge automatically and shows an error:</p>
<pre><code class="lang-text">Automatic merge failed; fix conflicts and then commit the result.
</code></pre>
<p>This happens because the same line in <code>four.txt</code> was modified in both branches, <code>staging</code> and <code>development</code>. Git can’t decide which version should take priority, so it leaves the decision to you.</p>
<p>In this case, the developer working on the <code>development</code> branch (or whoever is managing it) has to manually resolve the conflict. When you open <code>four.txt</code> in a text editor, Git marks the conflicting section clearly, showing which part came from <code>staging</code> and which part came from <code>development</code>. You’ll see both the <code>44</code> from <code>staging</code> and the <code>444</code> from <code>development</code>. It’s now up to you to decide whether to keep one, remove one, or combine both changes.</p>
<p>While staying on the <code>development</code> branch, you decide which version to keep – for example, <code>444</code>. You’ll then need to remove all the conflict markers, save the file, and then run:</p>
<pre><code class="lang-bash">git add .
git commit -m <span class="hljs-string">"merge conflict solved"</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443365329/94fbc5e8-2cca-4423-b4ab-4f90898ea9c0.gif" alt="Git Merge Conflict Markers" width="1138" height="640" loading="lazy"></p>
<p>Now switch back to the <code>staging</code> branch:</p>
<pre><code class="lang-bash">git checkout staging
</code></pre>
<p>When you open the file system and check <code>four.txt</code>, it still shows <code>44</code>, meaning no change has been applied yet. At this point, you can choose to merge changes either into <code>staging</code> or <code>development</code> since both branches are now in sync in terms of expected final content.</p>
<p>From <code>staging</code>, run:</p>
<pre><code class="lang-bash">git merge development
</code></pre>
<p>This time, Git merges everything smoothly without any conflict because both sides now contain compatible content. When you check the status:</p>
<pre><code class="lang-bash">git status
</code></pre>
<p>it shows everything is clean. Now, if you want to bring these merged changes into the <code>main</code> branch, switch to it:</p>
<pre><code class="lang-bash">git checkout main
</code></pre>
<p>Once you’re on the <code>main</code> branch and open the file system, you may notice that <code>four.txt</code> doesn’t yet have the latest update. Merge the <code>staging</code> branch:</p>
<pre><code class="lang-bash">git merge staging
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443386891/5b346d56-073a-4e58-a34c-736e2a25ba23.gif" alt="Git Merge Staging into Main" width="1138" height="640" loading="lazy"></p>
<p>All the latest changes flow into the <code>main</code> branch. The updates from both branches now combine into the final version. That’s how the entire process of merging and resolving merge conflicts works. You’ve now seen how branching works and how to switch from one branch to another using <code>git checkout</code>. Let’s dig a bit deeper into that command.</p>
<h2 id="heading-how-to-navigate-history-with-git-checkout-and-compare-commits-with-git-diff">How to Navigate History with <code>git checkout</code> and Compare Commits with <code>git diff</code></h2>
<p>Earlier, when we talked about <code>git log</code>, I mentioned that you can go back to a previous version using a commit ID. That’s what you’ll see now – and to do that, you’ll again use <code>git checkout</code>.</p>
<p>First, check your commit history:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">log</span> --oneline
</code></pre>
<p>Suppose you have nine commits in your log. Make a small change. Open <code>one.txt</code> and write <code>hello</code> inside it. Then stage and commit:</p>
<pre><code class="lang-bash">git add .
git commit -m <span class="hljs-string">"update one.txt file"</span>
</code></pre>
<p>Next, run:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">log</span> --oneline
</code></pre>
<p>All the commits are displayed. Now let’s say you want to switch back to one of your previous commits, specifically the one named “merging main into development.” To do that, copy the commit ID of that commit and type:</p>
<pre><code class="lang-bash">git checkout &lt;that-commit-id&gt;
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443408851/61803cda-c1d2-4b19-a298-bf569e3e36f8.gif" alt="Git Checkout Previous Commit" width="1138" height="640" loading="lazy"></p>
<p>Earlier, when you switched branches, you used the branch name. This time, you’re using a commit ID instead. Remember, your commit ID will be different.</p>
<p>After running this command, the project moves from the <code>main</code> branch to the exact state it was in at that previous commit. You must ensure that all your changes on <code>main</code> are tracked and committed before doing this. If there are any untracked or uncommitted files, Git won’t allow you to checkout to a previous version.</p>
<p>Once you run the command, you’ll see that in the terminal, instead of showing <code>main</code>, it now says something like:</p>
<pre><code class="lang-text">HEAD detached at &lt;commit-id&gt;
</code></pre>
<p>That means you’ve successfully switched to that particular commit. If you open <code>one.txt</code> now, you’ll notice that the <code>hello</code> line you added earlier is no longer there. This confirms that you’ve returned to the previous version of your project.</p>
<p>If you want to go back to your latest state – meaning returning to the main branch – use:</p>
<pre><code class="lang-bash">git checkout main
</code></pre>
<p>You’ve switched back to the <code>main</code> branch, and you’re back to the most recent version of your project.</p>
<p>So now you’ve seen how to switch between commits and move from one version to another. Now we’ll explore how to compare one commit with another.</p>
<p>If you want to see the differences between your current commit and a previous commit (that is, what lines of code were added, what lines were deleted), you can do that easily using Git commands.</p>
<p>First, check your commit history again:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">log</span> --oneline
</code></pre>
<p>Suppose there are now 10 commits in total. You’ll compare the commit “update one.txt file” with the previous one “merging main into development.” For that, you’ll need the commit IDs of both.</p>
<p>Since you’ve already run <code>git log</code>, copy those two IDs. Once you have them, write the command:</p>
<pre><code class="lang-bash">git diff &lt;first-commit-id&gt; &lt;second-commit-id&gt;
</code></pre>
<p>After running this command, Git shows the exact changes made between those two commits. The terminal displays which files were changed, what was removed (usually in red), and what was added (usually in green).</p>
<p>One important detail: in <code>git diff</code>, when you place the most recent commit ID first and the older one second, Git shows differences from the perspective of the newer commit – that is, what’s newly added or removed compared to the older one. If you reverse the order (older commit ID first and newer second), Git shows the opposite perspective. Try running the command both ways a few times and you’ll easily understand how the comparison works.</p>
<p>If you’re ever inside an interactive log or diff view, you can exit by pressing <code>q</code> on your keyboard. That closes the view immediately.</p>
<h2 id="heading-how-to-work-with-remotes-git-push-git-fetch-and-git-pull">How to Work with Remotes: <code>git push</code>, <code>git fetch</code>, and <code>git pull</code></h2>
<p>So far, everything you’ve done has been inside your local repository – staging files, making commits, and storing everything locally. But the real goal is to send those updates to the remote repository, like GitHub.</p>
<p>When you send local changes to a remote repository, that process is called a <strong>push</strong>. If any changes have been made in the remote repository that you want to bring into your local repository, you can use <strong>fetch</strong>.</p>
<p>When you run <code>git fetch</code>, the remote changes are downloaded into your local repository’s memory, but they won’t appear in your working directory yet. To update your working directory and see those changes in your files, you need to run <strong>git pull</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443429569/e3d2882f-ad8e-4766-aa02-45633a983932.gif" alt="Git Push Fetch Pull" width="1138" height="640" loading="lazy"></p>
<p>In short:</p>
<ul>
<li><p><strong>push</strong> sends local changes to the remote.</p>
</li>
<li><p><strong>fetch</strong> brings remote changes into your local repository (but does not merge them into your working directory).</p>
</li>
<li><p><strong>pull</strong> fetches and merges; it updates your working directory immediately.</p>
</li>
</ul>
<p>In other words:</p>
<pre><code class="lang-text">git pull = git fetch + git merge
</code></pre>
<h3 id="heading-example-git-push">Example: <code>git push</code></h3>
<p>You’ve already made several changes in your local repository, and now you want to push them to the remote <code>main</code> branch. Since you’re currently on the <code>main</code> branch, use:</p>
<pre><code class="lang-bash">git push origin main
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443452657/0e0d3603-bc38-4ec0-9517-687dbf83c393.gif" alt="Git Push Main Branch" width="1138" height="640" loading="lazy"></p>
<p>Here, <code>origin</code> refers to the remote repository, and <code>main</code> is the branch you want to push to. After running this command, all your latest commits are sent to the remote <code>main</code> branch. If you check your repository on GitHub, you’ll see that everything is updated. But only the <code>main</code> branch is pushed – other branches aren’t uploaded yet. This means you’ve only pushed your <code>main</code> branch to the remote’s <code>main</code>.</p>
<h3 id="heading-example-pushing-other-branches">Example: Pushing Other Branches</h3>
<p>Switch to the <code>staging</code> branch:</p>
<pre><code class="lang-bash">git checkout staging
git push origin staging
</code></pre>
<p>Git creates a new branch named <code>staging</code> in the remote repository and pushes all your staging changes there. When you check GitHub again, you’ll see that the <code>staging</code> branch has been created and updated.</p>
<p>Similarly, switch to the <code>development</code> branch:</p>
<pre><code class="lang-bash">git checkout development
git push origin development
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443476135/9243730d-5d93-48aa-9d32-27ced9d8a762.gif" alt="Git Push Other Branches" width="1138" height="640" loading="lazy"></p>
<p>The <code>development</code> branch is also uploaded to the remote. Now all three branches (<code>main</code>, <code>staging</code>, and <code>development</code>) are fully synced with the remote repository.</p>
<p>Finally, switch back to the <code>main</code> branch again:</p>
<pre><code class="lang-bash">git checkout main
</code></pre>
<h3 id="heading-example-git-fetch">Example: <code>git fetch</code></h3>
<p>Imagine you’ve already pushed your local changes to the remote. Now let’s see how <code>git fetch</code> works.</p>
<p>Suppose you make a change directly on GitHub. For example, open the file <code>three.txt</code> on GitHub, type <code>3</code>, and commit the change. Now, the remote <code>main</code> branch has a new update that your local <code>main</code> branch doesn’t have – it’s behind the remote version. While staying on the local <code>main</code> branch, bring in the latest changes from the remote:</p>
<pre><code class="lang-bash">git fetch
</code></pre>
<p>Git fetches the new changes from the remote repository, but those updates don’t yet appear in your local file system. For example, you won’t see the update in <code>three.txt</code> until you merge the fetched changes. Once you run:</p>
<pre><code class="lang-bash">git merge
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443499165/ff4f6389-ad36-434e-a2b2-8c321160607a.gif" alt="Git Fetch and Merge" width="1138" height="640" loading="lazy"></p>
<p>the remote changes are integrated into your local working directory as well.</p>
<h3 id="heading-example-git-pull">Example: <code>git pull</code></h3>
<p>Now, suppose you edit the remote <code>three.txt</code> file again, this time adding <code>33</code> after <code>3</code> and committing it on GitHub. The remote <code>main</code> branch is now ahead again.</p>
<p>To bring in all those updates and merge them into your local <code>main</code> branch at once, use:</p>
<pre><code class="lang-bash">git pull
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443520831/0c438637-75f5-4743-a2d7-38cea3cd0d2e.gif" alt="Git Pull Command" width="1138" height="640" loading="lazy"></p>
<p><code>git pull</code> automatically performs both fetch and merge in a single command, meaning all the new remote changes, including the latest updates in <code>three.txt</code>, immediately appear in your local files.</p>
<p>You’ve now learned how to:</p>
<ul>
<li><p>push changes from local to remote (<code>git push</code>),</p>
</li>
<li><p>fetch changes from remote without merging (<code>git fetch</code>), and</p>
</li>
<li><p>pull changes from remote while merging them automatically (<code>git pull</code>).</p>
</li>
</ul>
<p>These three commands are among the most frequently used Git operations and are more than enough for most daily development work.</p>
<h2 id="heading-how-to-undo-local-changes-with-git-restore">How to Undo Local Changes with <code>git restore</code></h2>
<p>Now imagine you’re working on a project. You start developing a new feature, write a lot of new code, and modify several existing files. After some point, you realize that the approach you took isn’t working at all. But by then, you’ve already made changes across 10 to 15 different files – some with new code, some heavily modified.</p>
<p>In this situation, you want to discard everything and go back to the previous state. Would you really open each of those 10 to 15 files manually, remove all the new lines, and try to restore the old code one by one? How accurate or even possible would that be? Probably not at all.</p>
<p>In this case, the simplest answer is that it’s actually not practical manually. And the more complicated answer is that there’s no guarantee that everything will return to its exact previous state. This is exactly where the magic of the <code>git restore</code> command comes in.</p>
<p>The <code>git restore</code> command helps you revert any file or directory back to its previous state, meaning the state of the <strong>last commit</strong>. It’s mainly used to undo local uncommitted changes, or to remove changes that were added to the staging area using <code>git add</code>. Let’s test it. Suppose in <code>one.txt</code>, you write:</p>
<pre><code class="lang-text">new feature
</code></pre>
<p>This repository already had some committed history. Now you’re just trying to develop a new feature. After writing the new code, you realize that the change you made in <code>one.txt</code> (adding <code>new feature</code>) was a mistake. The previous version was fine.</p>
<p>Since this change isn’t ready to be committed, you want to undo it and go back to the last committed state. To do that, run:</p>
<pre><code class="lang-bash">git restore one.txt
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443545767/6e1bb71b-4228-40f5-bcec-23d094254355.gif" alt="Git Restore Single File" width="1138" height="640" loading="lazy"></p>
<p>As soon as you run this command, the file instantly reverts to its previous state – the exact version from the most recent commit.</p>
<p>If you want to restore an entire directory instead of a single file, type the directory name after <code>git restore</code> and it’ll bring everything in that folder back to the last committed version.</p>
<p>If you want to undo all changes across the entire repository, run:</p>
<pre><code class="lang-bash">git restore .
</code></pre>
<p>This restores every file to its last committed state. If you’ve already staged some changes using <code>git add</code>, you can still undo them using the <code>--staged</code> flag. For example:</p>
<pre><code class="lang-bash">git restore --staged fileName
<span class="hljs-comment"># or</span>
git restore --staged .
</code></pre>
<p>This removes the files from the staging area but keeps the working directory unchanged.</p>
<p>In summary, the <code>git restore</code> command helps you bring any file or directory back to its previous (last committed) state. It’s mainly used to undo local, uncommitted changes before they’re ever committed.</p>
<h2 id="heading-how-to-temporarily-shelve-work-with-git-stash">How to Temporarily Shelve Work with <code>git stash</code></h2>
<p>Now imagine this: you’re working on a new branch, developing a big feature. It’s a long process, and you’ve already finished about half of it. But the work isn’t yet in a state to be committed.</p>
<p>Suddenly, another developer messages you saying there’s a new update on a different branch and you need to check it and give feedback. How will you switch branches without losing your unfinished work? Will you throw away all your progress using the <code>git restore</code> command?</p>
<p>Of course not. There’s no reason to go through that kind of hassle when Git gives you a much smarter way to handle this: using the <code>git stash</code> command.</p>
<p>With <code>git stash</code>, you can temporarily set aside your unfinished work, switch to another branch to do something else, and later bring all your changes back with a single command.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443582135/733a4f46-6c92-4902-8c45-97cdcd55990f.gif" alt="Git Stash Command" width="1138" height="640" loading="lazy"></p>
<p>Let’s see how it works. Suppose in <code>one.txt</code>, you write:</p>
<pre><code class="lang-text">another feature
</code></pre>
<p>You’re currently on the <code>main</code> branch. Now you need to switch to the <code>development</code> branch to review a new feature. So you type:</p>
<pre><code class="lang-bash">git checkout development
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443604514/8d70a915-8cac-49c8-8776-f4db7ed37bb5.png" alt="Git Checkout Development Branch with Uncommitted Changes" width="2560" height="1440" loading="lazy"></p>
<p>But Git throws an error:</p>
<pre><code class="lang-text">error: Your local changes to the following files would be overwritten by checkout:
    one.txt
Please commit your changes or stash them before you switch branches.
Aborting
</code></pre>
<p>This happens because Git doesn’t allow switching branches when there are uncommitted changes – it’s protecting your work. But since your feature isn’t ready to be committed, this is exactly when you use <code>git stash</code>. Run:</p>
<pre><code class="lang-bash">git stash
</code></pre>
<p>The moment you execute this command, your uncommitted changes disappear from your working directory – but they’re not lost. Git has safely stored them in a temporary area called the <strong>stash</strong>. This lets you switch branches freely without affecting your unfinished work. Now, switch to the <code>development</code> branch:</p>
<pre><code class="lang-bash">git checkout development
</code></pre>
<p>You’ve now successfully switched branches. You can review the new feature, make notes, and do whatever you need to. Once you’re done, switch back to your <code>main</code> branch again:</p>
<pre><code class="lang-bash">git checkout main
</code></pre>
<p>Now, when you look around, you’ll see that your unfinished feature – the one you were working on earlier – isn’t there. It’s still saved in the stash. To bring it back, “pop” it out of the stash:</p>
<pre><code class="lang-bash">git stash pop
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443623961/17568e8b-ba41-4020-b7f2-00a9ae690a9c.gif" alt="Git Stash Use Example" width="1138" height="640" loading="lazy"></p>
<p>As soon as you run this, all your stashed changes reappear in your working directory. The <code>pop</code> command restores the most recently stashed work and simultaneously removes it from the stash list. If you’ve stashed multiple times, Git keeps them all in order – newest on top, oldest at the bottom. When you pop, it brings back the most recent one first.</p>
<p>If you want to reapply the stashed changes <strong>without removing them</strong> from the stash list (so that you can reuse them later), use the <code>apply</code> command instead:</p>
<pre><code class="lang-bash">git stash apply
</code></pre>
<p>Your changes are restored, but they also remain safely stored in the stash for future use. You can stash again:</p>
<pre><code class="lang-bash">git stash
git stash apply
</code></pre>
<p>You’ll notice it behaves almost the same as before, and the changes come back just like when you used <code>pop</code>. You already know that Git can store multiple stashes, and you can view a list of all those stashed changes. To see that list, type:</p>
<pre><code class="lang-bash">git stash list
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443645465/12d2c1f3-a529-4d36-aa55-2ff459a20b2c.gif" alt="Git Stash List Command" width="1138" height="640" loading="lazy"></p>
<p>You’ll see a list of all your saved stashes. Each stash item is marked with an identifier like <code>stash@{0}</code>, <code>stash@{1}</code>, and so on. You can use these identifiers to apply or pop specific stashes:</p>
<pre><code class="lang-bash">git stash pop stash@{0}
<span class="hljs-comment"># or</span>
git stash apply stash@{0}
</code></pre>
<p>Both commands work. The only difference is how they handle the stash afterward. To understand the difference more clearly, suppose you check your stash list:</p>
<pre><code class="lang-bash">git stash list
</code></pre>
<p>and see just one stash. If you previously used <code>git stash apply</code>, that stash item is still there. To remove a stash manually, use <code>git stash drop</code>. The <code>drop</code> command removes a specific stash from the stash list. For example:</p>
<pre><code class="lang-bash">git stash drop
git stash list
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443664000/db9707b8-d32b-451c-8bd8-a0c992ef4f78.gif" alt="Git Stash Drop Command" width="1138" height="640" loading="lazy"></p>
<p>Now the stash list is empty. Since you used <code>git stash apply</code> earlier, all the changes are still in your working directory. Confirm that with:</p>
<pre><code class="lang-bash">git status
</code></pre>
<p>The changes you applied are still there. Now stash those changes again:</p>
<pre><code class="lang-bash">git stash
git stash list
</code></pre>
<p>You’ll see one stash entry again.</p>
<p>Then run:</p>
<pre><code class="lang-bash">git stash pop
git stash list
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443683035/cdd67489-7797-4cce-a0de-a10506244460.gif" alt="Git Stash Pop Command" width="1138" height="640" loading="lazy"></p>
<p>The stashed changes are restored into your working directory, and the stash list is now empty. <code>pop</code> brings your changes back <strong>and removes</strong> them from the stash list – it’s like taking them out permanently. Stash something again:</p>
<pre><code class="lang-bash">git stash
git stash list
</code></pre>
<p>Now run:</p>
<pre><code class="lang-bash">git stash apply
git stash list
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443701166/3df82aab-14d7-461a-8ee6-320609d3fdcb.gif" alt="Git Stash Apply Command" width="1138" height="640" loading="lazy"></p>
<p>The command works. Your files are restored, just like before. But the stash is still in the list. So here’s the key difference:</p>
<ul>
<li><p><code>git stash pop</code> restores your changes <strong>and removes</strong> them from the stash list.</p>
</li>
<li><p><code>git stash apply</code> restores your changes but <strong>keeps</strong> them in the stash list for future use.</p>
</li>
</ul>
<h2 id="heading-how-to-undo-commits-safely-with-git-revert">How to Undo Commits Safely with <code>git revert</code></h2>
<p>Now let’s talk about <code>git revert</code>. The <code>git revert</code> command is used to undo the changes made in a previous commit – but instead of deleting that old commit, it creates a <strong>new</strong> one that reverses those changes. In other words, it cancels out the effects of a previous commit while keeping the project history completely clean and traceable.</p>
<p>That’s why it’s called “revert”: because it doesn’t delete any commit. Instead, it creates a new commit that brings the project back to its previous correct state. Simply put, <code>git revert</code> means fixing an old mistake without erasing it.</p>
<p>For example, imagine you accidentally added too much salt while cooking. Instead of throwing the whole dish away, you adjust the flavor by adding some extra ingredients to balance the saltiness. Similarly, <code>git revert</code> doesn’t delete the faulty commit – it corrects it through a new one.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443720093/f7506aa8-e16b-4566-a0c8-f497e195b783.gif" alt="Git Revert Command" width="1138" height="640" loading="lazy"></p>
<p>To revert something, you need its commit ID. Suppose in the file <code>three.txt</code>, you added the line:</p>
<pre><code class="lang-text">hello three
</code></pre>
<p>Then you run:</p>
<pre><code class="lang-bash">git add .
git commit -m <span class="hljs-string">"hello three"</span>
</code></pre>
<p>Now, if you check the log:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">log</span> --oneline
</code></pre>
<p>you’ll see there are 10 commits in total. You realize that the <code>"hello three"</code> commit introduced a bug and you want to remove it. Before that, copy the commit ID of <code>"hello three"</code> and then run:</p>
<pre><code class="lang-bash">git revert &lt;that-commit-id&gt;
</code></pre>
<p>After running the command, you’ll see a prompt asking for a commit message. You can type a custom message or simply keep the default one and exit (for example, by using <code>- wq</code> in Vim). Once you do that, the changes from <code>"hello three"</code> will be undone. Check the logs again:</p>
<pre><code class="lang-bash">git <span class="hljs-built_in">log</span> --oneline
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443740518/c8ef43d8-78e8-4afe-8424-5a24d0987640.gif" alt="Git Revert Specific Commit" width="1138" height="640" loading="lazy"></p>
<p>You’ll notice there’s a new commit added specifically for the revert. At this point, you might be reminded of <code>git reset</code>. The main difference between <code>git reset</code> and <code>git revert</code> is:</p>
<ul>
<li><p><code>git reset</code> can take you back to a specific commit and discard all commits after that point, <strong>without creating any new commit</strong>.</p>
</li>
<li><p><code>git revert</code> removes the changes from a specific commit by <strong>creating a new commit</strong> that reverses it.</p>
</li>
</ul>
<p>If your project is on GitHub or any remote repository, other contributors can also see the revert commit, ensuring clarity and preventing confusion.</p>
<p>Another key point is that if you check the logs after a reset, there’s no record of the removed commits. But when you use revert, you’ll clearly see an additional commit indicating that a revert took place.</p>
<h2 id="heading-how-to-keep-history-clean-with-git-rebase">How to Keep History Clean with <code>git rebase</code></h2>
<p>Now let’s talk about Git Rebase. Imagine you’re starting to work on a new feature. You create a new branch called <code>feature</code> by checking out from the <code>main</code> branch. You begin developing the new feature, making changes bit by bit, and committing your progress as you go. Meanwhile, another developer adds more updates to the <code>main</code> branch for production. Now you want to include those latest updates from <code>main</code> into your <code>feature</code> branch. What can you do?</p>
<p>There are several ways to handle this. As we’ve seen before, one option is to merge the <code>main</code> branch into your <code>feature</code> branch. If you do that, Git creates a new <strong>merge commit</strong>, and all the latest updates from <code>main</code> are merged into your <code>feature</code> branch.</p>
<p>But merging always creates an additional commit – you can see it clearly if you run <code>git log</code>. Some developers find these extra merge commits a bit messy. If you continue merging multiple times, your commit history can look cluttered.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443759550/d074c631-1e65-4ef3-a007-e2d7665eccd7.gif" alt="Git Rebase Command" width="1138" height="640" loading="lazy"></p>
<p>In such cases, a better solution is to use <strong>Git Rebase</strong>. When you perform a rebase, the base of your <code>feature</code> branch changes. That means if you rebase onto <code>main</code>, all the new commits from <code>main</code> are applied directly into your <code>feature</code> branch, and then your <code>feature</code> branch commits are reapplied on top of them. While your <code>main</code> branch’s code content remains the same, the commit history becomes much cleaner and more linear – and you can easily verify this using <code>git log</code>.</p>
<p>Let’s understand this with an example. Create a new branch called <code>feature</code> from <code>main</code>:</p>
<pre><code class="lang-bash">git branch feature
git checkout feature
</code></pre>
<p>You’re now inside the <code>feature</code> branch. Open <code>one.txt</code> and add the line:</p>
<pre><code class="lang-text">adding dark mode functionality
</code></pre>
<p>Then stage and commit:</p>
<pre><code class="lang-bash">git add .
git commit -m <span class="hljs-string">"adding dark mode functionality"</span>
</code></pre>
<p>Now switch back to the <code>main</code> branch:</p>
<pre><code class="lang-bash">git checkout main
</code></pre>
<p>You’re now in the <code>main</code> branch. Create a new file called <code>two.txt</code> and write:</p>
<pre><code class="lang-text">adding dark mode ui
</code></pre>
<p>Then stage and commit:</p>
<pre><code class="lang-bash">git add .
git commit -m <span class="hljs-string">"adding dark mode ui"</span>
</code></pre>
<p>Now the <code>main</code> branch has a new feature – “dark mode ui”. You want that same “dark mode ui” update to appear in your <code>feature</code> branch as well. Switch back to your <code>feature</code> branch:</p>
<pre><code class="lang-bash">git checkout feature
</code></pre>
<p>Your goal is to bring the latest updates from the <code>main</code> branch into the <code>feature</code> branch. But this time, we’ll do it using <strong>rebase</strong>.</p>
<p>To perform a Git rebase, you need to be on the branch you want to rebase, and then specify the branch from which you want to bring the changes. For example, if you’re currently on the <code>feature</code> branch and want to bring in the changes from <code>main</code>, run:</p>
<pre><code class="lang-bash">git rebase main
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443782936/9dbfa229-e02a-40f3-8f91-14fcbf4c858e.gif" alt="Git Rebase Main into Feature" width="1138" height="640" loading="lazy"></p>
<p>Once you run this command, the rebase completes, and the “dark mode ui” update from the <code>main</code> branch appears in your <code>feature</code> branch.</p>
<p>Here’s what happens behind the scenes when you use rebase:</p>
<ol>
<li><p>Git identifies the most recent common commit shared between your current branch (<code>feature</code>) and the branch you’re rebasing onto (<code>main</code>).</p>
</li>
<li><p>All the commits in your <code>feature</code> branch that come after that common commit are temporarily set aside.</p>
</li>
<li><p>Git applies all the new commits from the <code>main</code> branch into your <code>feature</code> branch.</p>
</li>
<li><p>Finally, it reapplies the saved commits from the <code>feature</code> branch on top of those <code>main</code> commits, one by one.</p>
</li>
</ol>
<p>The result is a clean, linear commit history that’s much tidier than what you get with merging. You can easily see this difference by running <code>git log</code>.</p>
<p>Just keep in mind that <code>git rebase</code> is powerful. So it’s not recommended to use it on <strong>public repositories</strong> or branches where multiple developers are working together. If you must use it, you should always inform your team beforehand. Otherwise, it can cause serious issues.</p>
<p>The reason is that rebase <strong>rewrites existing commit history</strong> – even the commit hashes (IDs) change. So, if someone else is working on the same branch, your rebased commits won’t match their local copies anymore, and they won’t be able to pull or sync normally.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443802090/97b145e9-7b86-4106-99fe-683ef8d5025b.gif" alt="Git Rebase Warning" width="1138" height="640" loading="lazy"></p>
<p>So before using rebase, make sure you fully understand where you’re applying it and whether it could cause problems for your collaborators. It’s perfectly safe to use rebase on your local or personal branches where only you’re working – just avoid rewriting commits that already exist on a shared remote branch.</p>
<h2 id="heading-how-to-collaborate-on-github-with-pull-requests">How to Collaborate on GitHub with Pull Requests</h2>
<p>Before wrapping up, let’s discuss one last important topic: the <strong>Pull Request</strong>. When working with Git and GitHub, the term “Pull Request,” often shortened as “PR,” comes up frequently.</p>
<p>A Pull Request is essentially a request you make to merge your changes into another branch – usually the <code>main</code> branch. It’s a way of saying, “I’ve made some changes in my branch. Please review them, and if everything looks good, merge them into the main branch.”</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443820127/5ea7b5ce-a06d-42d3-88d7-da5e818210dc.gif" alt="GitHub Pull Request" width="1138" height="640" loading="lazy"></p>
<p>In other words, you typically don’t make changes directly to someone else’s repository. When you finish your work in your own branch, you create a Pull Request to ask for permission to merge your code into the main repository. That’s what a Pull Request is.</p>
<p>Go back to your <code>git-journey</code> repository on GitHub. By now, you’ve already pushed your <code>main</code>, <code>staging</code>, and <code>development</code> branches. At the top of the GitHub page, you’ll see several tabs: <strong>Code</strong>, <strong>Issues</strong>, <strong>Pull requests</strong>, and <strong>Actions</strong>.</p>
<p>Click on the <strong>Pull requests</strong> tab. Here, you’ll see a big green button labeled <strong>New pull request</strong>. This is where you can say, “I want to merge the changes from this branch into another branch.”</p>
<p>Once you click New pull request, GitHub shows you two dropdown menus:</p>
<ul>
<li><p><strong>base</strong>: the branch where you want to merge the changes (select <code>main</code> here).</p>
</li>
<li><p><strong>compare</strong>: the branch from which you want to bring the changes (select <code>development</code>).</p>
</li>
</ul>
<p>In other words, you’re saying, “I’ve made some updates in the <code>development</code> branch, and now I want those updates to be merged into the <code>main</code> branch.” GitHub automatically shows a detailed comparison: which files have been modified, which lines have been added, and which ones have been removed, with everything clearly visible. If everything looks good, scroll down and click <strong>Create pull request</strong>.</p>
<p>Give your PR a title, such as:</p>
<pre><code class="lang-text">Merge development updates into main
</code></pre>
<p>In the description box, you can write something like:</p>
<pre><code class="lang-text">This PR adds the latest updates and fixes from development to main.
</code></pre>
<p>Then click <strong>Create pull request</strong> to submit it. Now, if you go back to the <strong>Pull requests</strong> tab, you’ll see your newly created PR:</p>
<pre><code class="lang-text">development → main
</code></pre>
<p>Click on it, and you’ll find three sections:</p>
<ul>
<li><p><strong>Conversation:</strong> where you and your teammates can discuss or comment on the changes.</p>
</li>
<li><p><strong>Commits</strong>: which lists all the commits included in this PR.</p>
</li>
<li><p><strong>Files changed</strong>: which shows exactly what changes were made in which files.</p>
</li>
</ul>
<p>If everything looks good after review, click the green <strong>Merge pull request</strong> button at the top, and then confirm by clicking <strong>Confirm merge</strong>. Once it’s done, GitHub displays a message:</p>
<pre><code class="lang-text">Pull request successfully merged and closed.
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765443840494/12e57fd1-64fb-412d-913d-599edebf1132.gif" alt="Pull Request Example" width="1138" height="640" loading="lazy"></p>
<p>That means all the updates from the <code>development</code> branch have now been successfully merged into <code>main</code>.</p>
<p>This is how Pull Requests make code management much easier. Every change gets reviewed first and then merged into <code>main</code>. As a result, the main branch stays stable, and the entire team can collaborate safely and efficiently.</p>
<h2 id="heading-git-amp-github-concise-summary">Git &amp; GitHub – Concise Summary</h2>
<h3 id="heading-git-vs-github-1">Git vs GitHub</h3>
<ul>
<li><p><strong>Git</strong>: Local version control tool that tracks every change to your files, lets you keep multiple versions, and roll back any time.</p>
</li>
<li><p><strong>GitHub</strong>: Online hosting platform for Git repositories that acts like a central “code server” so teams can share, review, and collaborate.</p>
</li>
<li><p>Other Git hosts exist (GitLab, Bitbucket), but GitHub is the most widely used, especially for open source.</p>
</li>
</ul>
<h3 id="heading-core-git-architecture-amp-workflow">Core Git Architecture &amp; Workflow</h3>
<ul>
<li><p>Work happens in the <strong>working directory</strong> (your project folder).</p>
</li>
<li><p>When changes are ready, you move them to the <strong>staging area</strong> with <code>git add</code>.</p>
</li>
<li><p>You permanently record a version in the <strong>local repository</strong> with <code>git commit</code>.</p>
</li>
<li><p>The <strong>remote repository</strong> (for example, on GitHub) is a copy of your repo stored in the cloud for backup and collaboration.</p>
</li>
</ul>
<p>Basic flow:</p>
<ol>
<li><p>Edit files in the working directory.</p>
</li>
<li><p>Stage changes: <code>git add &lt;files&gt;</code> or <code>git add .</code></p>
</li>
<li><p>Commit: <code>git commit -m "message"</code></p>
</li>
<li><p>Sync with remote: <code>git push</code> / <code>git pull</code></p>
</li>
</ol>
<h3 id="heading-getting-started">Getting Started</h3>
<ul>
<li><p>Install Git from the official site: <a target="_blank" href="https://git-scm.com/downloads"><code>https://git-scm.com/downloads</code></a>.</p>
</li>
<li><p>Check installation: <code>git --version</code>.</p>
</li>
<li><p>Configure identity (needed before first commit):</p>
<ul>
<li><p><code>git config --global</code> <a target="_blank" href="http://user.name"><code>user.name</code></a> <code>"Your Name"</code></p>
</li>
<li><p><code>git config --global</code> <a target="_blank" href="http://user.email"><code>user.email</code></a> <code>"</code><a target="_blank" href="mailto:you@example.com"><code>you@example.com</code></a><code>"</code></p>
</li>
</ul>
</li>
<li><p>Initialize a repo in a folder: <code>git init</code>.</p>
</li>
<li><p>Or clone an existing repo from GitHub: <code>git clone &lt;repo-url&gt;</code>.</p>
</li>
</ul>
<h3 id="heading-seeing-amp-moving-changes">Seeing &amp; Moving Changes</h3>
<ul>
<li><p>Check what changed and what’s staged: <code>git status</code>.</p>
</li>
<li><p>Stage changes:</p>
<ul>
<li><p><code>git add --all</code> / <code>git add -A</code>: stage everything (adds, changes, deletions).</p>
</li>
<li><p><code>git add .</code>: stage changes only in the current directory.</p>
</li>
<li><p><code>git add &lt;file&gt;</code> or <code>git add *.txt</code>: stage specific files or patterns.</p>
</li>
</ul>
</li>
<li><p>Unstage everything (but keep edits in files): <code>git reset</code>.</p>
</li>
<li><p>Save staged changes as a commit: <code>git commit -m "message"</code>.</p>
</li>
<li><p>View commit history:</p>
<ul>
<li><p>Full: <code>git log</code></p>
</li>
<li><p>Compact: <code>git log --oneline</code></p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-deleting-restoring-amp-undoing">Deleting, Restoring, &amp; Undoing</h3>
<ul>
<li><p>Delete a tracked file and stage the deletion: <code>git rm &lt;file&gt;</code>.</p>
<ul>
<li><p>Force delete changed file: <code>git rm -f &lt;file&gt;</code>.</p>
</li>
<li><p>Stop tracking but keep file: <code>git rm --cached &lt;file&gt;</code>.</p>
</li>
</ul>
</li>
<li><p>Undo staged changes only: <code>git reset</code>.</p>
</li>
<li><p>Reset everything (including working directory) to last commit: <code>git reset --hard</code>.</p>
</li>
<li><p>Restore file content back to last commit:</p>
<ul>
<li><p>Single file: <code>git restore &lt;file&gt;</code></p>
</li>
<li><p>All files: <code>git restore .</code></p>
</li>
</ul>
</li>
<li><p>Undo a <strong>commit</strong> safely (create a new “fix” commit):</p>
<ul>
<li><code>git revert &lt;commit-id&gt;</code></li>
</ul>
</li>
<li><p>Move HEAD and history back to an earlier commit (dangerous on shared branches):</p>
<ul>
<li>Example: <code>git reset HEAD~</code> (undo last commit locally).</li>
</ul>
</li>
</ul>
<h3 id="heading-branching-merging-amp-conflicts">Branching, Merging, &amp; Conflicts</h3>
<ul>
<li><p>A <strong>branch</strong> is an independent line of development (for example, <code>main</code>, <code>development</code>, <code>staging</code>, <code>feature</code>).</p>
</li>
<li><p>List branches: <code>git branch</code>.</p>
</li>
<li><p>Create branch: <code>git branch development</code>.</p>
</li>
<li><p>Switch branch: <code>git checkout development</code> (or <code>git switch development</code> in newer Git).</p>
</li>
<li><p>Typical workflow: keep <code>main</code> stable, build new features on separate branches, then merge back.</p>
</li>
<li><p>Merge another branch into the current one: <code>git merge &lt;branch-name&gt;</code>.</p>
</li>
<li><p>If the same lines changed differently in two branches, you get a <strong>merge conflict</strong>:</p>
<ul>
<li><p>Git marks conflicts in the file with <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt;</code>, <code>=======</code>, <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt;</code>.</p>
</li>
<li><p>You manually edit to the correct final content, then:</p>
<ul>
<li><p><code>git add .</code></p>
</li>
<li><p><code>git commit -m "merge conflict resolved"</code></p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="heading-navigating-amp-comparing-history">Navigating &amp; Comparing History</h3>
<ul>
<li><p>Jump to an old commit (read-only “detached HEAD” state): <code>git checkout &lt;commit-id&gt;</code></p>
</li>
<li><p>Return to the latest <code>main</code>: <code>git checkout main</code>.</p>
</li>
<li><p>Compare two commits: <code>git diff &lt;old-id&gt; &lt;new-id&gt;</code> – shows what changed between them.</p>
</li>
</ul>
<h3 id="heading-working-with-remotes-github">Working with Remotes (GitHub)</h3>
<ul>
<li><p>Push local branch to remote: <code>git push origin &lt;branch&gt;</code>.</p>
</li>
<li><p>Fetch latest state from remote <strong>without</strong> updating your working files: <code>git fetch</code></p>
<ul>
<li>Then merge if needed: <code>git merge origin/main</code></li>
</ul>
</li>
<li><p>Pull and merge in one step: <code>git pull</code> (equivalent to <code>fetch + merge</code>).</p>
</li>
</ul>
<h3 id="heading-temporarily-shelving-work-with-git-stash">Temporarily Shelving Work with <code>git stash</code></h3>
<ul>
<li><p>Use <code>git stash</code> when you have uncommitted work but need to switch branches.</p>
</li>
<li><p><code>git stash</code>: saves current changes and cleans your working directory.</p>
</li>
<li><p>Switch branches, do other work, then come back and restore:</p>
<ul>
<li><p><code>git stash pop</code>: restore and remove from stash list.</p>
</li>
<li><p><code>git stash apply</code>: restore but keep entry in the stash.</p>
</li>
</ul>
</li>
<li><p>See all stashes: <code>git stash list</code>.</p>
</li>
<li><p>Remove a stash explicitly: <code>git stash drop</code>.</p>
</li>
</ul>
<h3 id="heading-keeping-history-clean-with-git-rebase">Keeping History Clean with <code>git rebase</code></h3>
<ul>
<li><p><code>git rebase &lt;branch&gt;</code> replays your current branch’s commits on top of another branch, creating a cleaner, linear history.</p>
</li>
<li><p>Safe on your <strong>own</strong> local branches, but dangerous on shared/public branches because it rewrites commit history (IDs change).</p>
</li>
<li><p>Common pattern: on <code>feature</code> branch, run <code>git rebase main</code> to bring latest <code>main</code> changes under your feature commits.</p>
</li>
</ul>
<h3 id="heading-collaboration-with-pull-requests-prs">Collaboration with Pull Requests (PRs)</h3>
<ul>
<li><p>On GitHub, you usually:</p>
<ol>
<li><p>Push your feature branch.</p>
</li>
<li><p>Open a <strong>Pull Request</strong> (PR) to request merging into <code>main</code> (or another base branch).</p>
</li>
<li><p>Teammates review code, discuss in comments, and approve.</p>
</li>
<li><p>The PR is merged (and usually closed) once accepted.</p>
</li>
</ol>
</li>
<li><p>PRs keep <code>main</code> stable and make reviews and history clearer.</p>
</li>
</ul>
<h3 id="heading-big-picture-takeaways">Big Picture Takeaways</h3>
<ul>
<li><p>Git tracks every change, lets you move safely between versions, and protects you from losing work.</p>
</li>
<li><p>GitHub (or other remotes) adds backup, sharing, and collaboration.</p>
</li>
<li><p>Most day‑to‑day work is based on a small set of commands: <code>git status</code>, <code>git add</code>, <code>git commit</code>, <code>git push</code>, <code>git pull</code>, <code>git branch</code>, <code>git checkout</code>, <code>git merge</code>, <code>git log</code>.</p>
</li>
<li><p>Advanced commands like <code>git reset</code>, <code>git restore</code>, <code>git revert</code>, <code>git stash</code>, and <code>git rebase</code> give you powerful ways to undo mistakes and keep history clean.</p>
</li>
</ul>
<h2 id="heading-final-words">Final Words</h2>
<p>This tutorial on Git and GitHub has walked through the essential, day-to-day concepts in a step-by-step, practical way. It’s especially helpful for those who are just getting started. If you’ve always felt a bit intimidated or confused about using Git for the first time, this guide was created with you in mind.</p>
<p>If you found the information here valuable, feel free to share it with others who might benefit from it. I’d really appreciate your thoughts – mention me on X <a target="_blank" href="https://x.com/sumit_analyzen">@sumit_analyzen</a> or on Facebook <a target="_blank" href="https://www.facebook.com/sumit.analyzen">@sumit.analyzen</a>, <a target="_blank" href="https://www.youtube.com/@logicBaseLabs">watch</a> my coding tutorials, or simply <a target="_blank" href="https://www.linkedin.com/in/sumitanalyzen/">connect with me</a> on LinkedIn. You can also checkout my official website <a target="_blank" href="https://www.sumitsaha.me/">sumitsaha.me</a> for more details about me.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Git Cheat Sheet – Helpful Git Commands with Examples ]]>
                </title>
                <description>
                    <![CDATA[ This Git Cheat Sheet will provide you with a handy list of common (and not so common) commands that will make your life easier when working with Git. You can also download the Git Cheat Sheet in PDF format (along with some other resources) for free b... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/git-cheat-sheet-helpful-git-commands-with-examples/</link>
                <guid isPermaLink="false">66c4ac87a052a51b9b7eb096</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Gitcommands ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #codenewbies ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Programming Tips ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Flavio Copes ]]>
                </dc:creator>
                <pubDate>Tue, 20 Aug 2024 14:47:35 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1723993272242/896730cc-3e03-43be-83d9-06d37ebab5a5.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>This Git Cheat Sheet will provide you with a handy list of common (and not so common) commands that will make your life easier when working with Git.</p>
<p>You can also download the Git Cheat Sheet in PDF format (along with some other resources) for free by joining my newsletter at <a target="_blank" href="https://flaviocopes.com/access/">flaviocopes.com/access</a>.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-preface"><strong>Preface</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-basic-git-commands"><strong>Basic Git Commands</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-working-directory-and-the-staging-area"><strong>The Working Directory and the Staging Area</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-working-with-branches"><strong>Working with Branches</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-merging-in-git"><strong>Merging in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-git-remotes"><strong>Git Remotes</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-amending-commits"><strong>Amending Commits</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-stashing-in-git"><strong>Stashing in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-git-tagging"><strong>Git Tagging</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-reverting-changes-in-git"><strong>Reverting Changes in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-viewing-history-logs"><strong>Viewing History Logs</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-git-diffs"><strong>Git Diffs</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-git-flow"><strong>Git Flow</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-exploring-git-references"><strong>Exploring Git References</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-configure-git"><strong>How to Configure Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-git-security"><strong>Git Security</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-aliases-in-git"><strong>How to Set Aliases in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-rebasing-in-git"><strong>Rebasing in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-cherry-picking"><strong>What is Cherry-Picking?</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-patching-in-git"><strong>Patching in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-relative-dates-in-git"><strong>Relative Dates in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-git-blame"><strong>Git Blame</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-archiving-in-git"><strong>Archiving in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-track-files-in-git"><strong>How to Track Files in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-index-manipulation-in-git"><strong>Index Manipulation in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-squashing-in-git"><strong>Squashing in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-data-integrity-in-git"><strong>Data Integrity in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-cleaning-up-in-git"><strong>Cleaning Up in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-git-subtree"><strong>Git Subtree</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-search-in-git"><strong>How to Search in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-bisecting-in-git"><strong>Bisecting in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-git-attributes"><strong>Git Attributes</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-git-checkout-2"><strong>Git Checkout</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-git-reflog"><strong>Git Reflog</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-handle-untracked-files-in-git"><strong>How to Handle Untracked Files in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-force-pushing-in-git"><strong>Force Pushing in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-git-fetching-and-pulling"><strong>Git Fetching and Pulling</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-handle-merge-conflicts-in-git"><strong>How to Handle Merge Conflicts in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-working-trees-in-git"><strong>Working Trees in Git</strong></a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-submodules-in-git"><strong>Submodules in Git</strong></a></p>
</li>
</ul>
<h2 id="heading-preface">Preface</h2>
<p>Welcome to this Git Cheat Sheet! It's an extensive guide I created to help empower both novice and seasoned developers with the knowledge you need to effectively utilize Git, the most popular version control system in the software industry.</p>
<p>This cheat sheet is designed to be your go-to resource, whether you're managing a solo project or collaborating within a large team. By providing clear explanations and practical examples, it should help demystify Git's complexities and transform them into intuitive, actionable insights.</p>
<p>Throughout this guide, you will explore a wide array of Git commands and concepts that form the backbone of software version control. From fundamental operations like initializing repositories and committing changes, to more advanced techniques such as branching, merging, and rebasing, this cheat sheet covers it all.</p>
<p>You'll also delve into specialized topics like squashing commits, bisecting to debug, handling submodules, and implementing subtrees. All this will help ensure that you're well-prepared to tackle any challenge that arises in your development process.</p>
<p>As you progress, you'll learn how to maintain data integrity, manage multiple working trees, and resolve merge conflicts efficiently. By the end, you'll not only have a deeper understanding of Git but also the confidence to use it to streamline your workflow and enhance collaboration with peers.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<p>To fully benefit from this cheat sheet, you should have a foundational knowledge of command-line operations and general programming principles. You should also be familiar with using a terminal or command prompt so you can better understand and apply the examples provided. Finally, having a basic grasp of version control concepts will enhance your ability to navigate through this guide effectively.</p>
<h2 id="heading-basic-git-commands"><strong>Basic Git Commands</strong></h2>
<p>In this section, you'll learn the fundamental Git commands that serve as the building blocks for efficiently managing and navigating your Git repositories.</p>
<p>Git is a distributed version control system that's essential for tracking changes in your codebase, collaborating with other developers, and maintaining the integrity of your project history. Understanding these basic commands is crucial for anyone looking to leverage the full power of Git in their development workflow.</p>
<p>We'll explore a variety of commands that cover key aspects of Git usage, such as initializing new repositories, committing changes, branching, and merging.</p>
<p>Each command is explained with a short sentence that describes its purpose along with its syntax, so you can effectively use it in real-world scenarios. Whether you're setting up a new project or working on an existing codebase, these commands will help you keep your work organized and maintain a seamless workflow.</p>
<h3 id="heading-git-help"><code>git help</code></h3>
<p>The <code>git help</code> command prints Git help information. It provides a quick reference to Git's basic usage and the most commonly used Git commands. This command is useful when you need a quick reminder of Git's functionality or want to explore available commands.</p>
<p>You can also use <code>git help &lt;command&gt;</code> to display help information for any specific Git command. For example, <code>git help git</code> prints the Git help specifically for the Git command itself.</p>
<p>These help commands are valuable resources for both beginners and experienced users to quickly access information about Git's features and usage.</p>
<h3 id="heading-git-version"><code>git version</code></h3>
<p>The <code>git version</code> command displays the version of Git installed on your system. This command is useful for verifying which version of Git you are currently using, which can be important for compatibility with certain features or when troubleshooting issues.</p>
<h3 id="heading-git-init"><code>git init</code></h3>
<p>The command <code>git init</code> is used to initialize a new Git repository in the current directory. This command creates a new subdirectory named <code>.git</code> that contains all the necessary metadata for the new repository. It's typically the first command you run when starting a new project that you want to manage with Git.</p>
<p>After running this command, you can begin tracking files and making commits in your new Git repository.</p>
<h3 id="heading-git-clone"><code>git clone &lt;repository_url&gt;</code></h3>
<p>The <code>git clone &lt;repository_url&gt;</code> command creates a copy of a remote Git repository on your local machine. It downloads all the files, branches, and commit history, allowing you to start working with the project immediately.</p>
<h3 id="heading-git-status"><code>git status</code></h3>
<p>The <code>git status</code> command shows the current state of the Git repository's working directory and staging area. It displays information about which files have been modified, added, or deleted, and whether these changes are staged for the next commit.</p>
<h2 id="heading-the-working-directory-and-the-staging-area"><strong>The Working Directory and the Staging Area</strong></h2>
<p>The working directory and the staging area are fundamental concepts in Git that play crucial roles in the version control process.</p>
<p>The working directory is the environment where you actively make changes to your files, representing the current state of your project. It is essentially a sandbox where you can freely edit, delete, and create files as you develop your project. But these changes are local to your machine and not yet part of the version history.</p>
<p>On the other hand, the staging area, also known as the index, serves as an intermediary space between the working directory and the repository. It acts as a checkpoint where you can selectively organize changes before they are committed to the repository's history. This allows you to prepare a set of changes that are logically related, ensuring that each commit is meaningful and coherent.</p>
<p>The commands below will help you manage changes between the working directory and the staging area. They'll let you add files to the staging area, remove them, or modify the existing ones, giving you control over what will be included in the next commit.</p>
<p>By using these commands, you can ensure that only the intended updates are committed, making your project's history clear and organized. This process is essential for maintaining a clean and understandable history, as it allows you to track the evolution of your project with precision and clarity.</p>
<h3 id="heading-git-checkout"><code>git checkout .</code></h3>
<p>This command discards all changes in the working directory, reverting files to their last committed state. This command is useful for quickly undoing local modifications and restoring the working directory to a clean state.</p>
<h3 id="heading-git-reset-p"><code>git reset -p</code></h3>
<p>This command allows you to interactively reset changes in the working directory. It provides a way to selectively undo modifications, giving you fine-grained control over which changes to keep or discard.</p>
<h3 id="heading-git-add"><code>git add &lt;file&gt;</code></h3>
<p>This command adds a specific file to the staging area in Git. This prepares the file for inclusion in the next commit, allowing you to selectively choose which changes to include in your version history.</p>
<h3 id="heading-git-add-p"><code>git add -p</code></h3>
<p>Allows you to interactively stage changes from your working directory by breaking them into chunks (hunks). This lets you review and selectively add parts of the changes to the index before committing.</p>
<h3 id="heading-git-add-i"><code>git add -i</code></h3>
<p>Enters the interactive mode of adding files. Provides a text-based interactive menu where you can select various actions to perform, such as staging individual changes, updating files, or viewing the status.</p>
<h3 id="heading-git-rm"><code>git rm &lt;file&gt;</code></h3>
<p>Removes a file from the working directory and stages the removal.</p>
<h3 id="heading-git-rm-cached"><code>git rm --cached &lt;file&gt;</code></h3>
<p>Removes the specified file from the staging area (index) but leaves it intact in your working directory. This effectively un-tracks the file from version control.</p>
<h3 id="heading-git-mv"><code>git mv &lt;old_path&gt; &lt;new_path&gt;</code></h3>
<p>This command is used to move or rename a file or directory within a Git repository. It automatically stages the change, making it ready for the next commit.</p>
<h3 id="heading-git-commit-m-message"><code>git commit -m "message"</code></h3>
<p>This command is used to create a new commit in your Git repository. It saves the changes that have been staged (added to the index) along with a descriptive message. This message should briefly explain what changes were made in this commit.</p>
<h2 id="heading-working-with-branches"><strong>Working with Branches</strong></h2>
<p>Git branches are parallel lines of development within a Git repository. They allow you to work on different features, bug fixes, or experiments independently from the main codebase.</p>
<p>Each branch can have its own commit history, and changes made in one branch do not affect others until they are merged. This helps you organize your work, and facilitates collaboration by enabling multiple developers to work on different aspects of a project simultaneously without interfering with each other's progress.</p>
<p>In this section we'll introduce commands that allow you to create, switch, list, rename, and delete branches in your Git repository. These commands help manage parallel lines of development, enabling you to work on different features or bug fixes independently. You'll also learn how to display commit histories and branch relationships, as well as manage remote branches.</p>
<h3 id="heading-git-branch"><code>git branch &lt;branch_name&gt;</code></h3>
<p>Creates a new branch.</p>
<h3 id="heading-git-checkout-1"><code>git checkout &lt;branch_name&gt;</code></h3>
<p>Switches to the specified branch and updates the working directory.</p>
<h3 id="heading-git-branch-1"><code>git branch</code></h3>
<p>Lists all branches.</p>
<h3 id="heading-git-branch-d"><code>git branch -d &lt;branch_name&gt;</code></h3>
<p>Deletes a branch.</p>
<h3 id="heading-git-push-delete"><code>git push --delete &lt;remote&gt; &lt;branch&gt;</code></h3>
<p>Deletes a remote branch.</p>
<h3 id="heading-git-branch-m"><code>git branch -m &lt;old_name&gt; &lt;new_name&gt;</code></h3>
<p>Renames a branch.</p>
<h3 id="heading-git-checkout-b"><code>git checkout -b &lt;new_branch&gt;</code></h3>
<p>Creates and switches to a new branch named <code>&lt;new_branch&gt;</code>, based on the current branch.</p>
<h3 id="heading-git-switch"><code>git switch &lt;branch&gt;</code></h3>
<p>Switches the working directory to the specified branch.</p>
<h3 id="heading-git-show-branch"><code>git show-branch &lt;branch&gt;</code></h3>
<p>Displays a summary of the commit history and branch relationships for all or selected branches, showing where each branch diverged.</p>
<h3 id="heading-git-show-branch-all"><code>git show-branch --all</code></h3>
<p>Same as above, but for all branches and their commits.</p>
<h3 id="heading-git-branch-r"><code>git branch -r</code></h3>
<p>Lists all remote branches that your local repository is aware of.</p>
<h3 id="heading-git-branch-a"><code>git branch -a</code></h3>
<p>Lists all branches in your repository, including both local and remote branches (the ones the local repository is aware of).</p>
<h3 id="heading-git-branch-merged"><code>git branch --merged</code></h3>
<p>Lists all branches that have been fully merged into the current branch, and can be safely deleted if no longer needed.</p>
<h3 id="heading-git-branch-no-merged"><code>git branch --no-merged</code></h3>
<p>Lists all branches that have not been fully merged into your current branch, showing branches with changes that haven't been integrated yet.</p>
<h2 id="heading-merging-in-git"><strong>Merging in Git</strong></h2>
<p>The git merge command is used to combine the changes from one branch into another branch. It integrates the histories of both branches, creating a new commit that includes the changes from both sources.</p>
<p>This process allows multiple lines of development to be brought together, facilitating collaboration and ensuring that all updates are incorporated into the main project.</p>
<p>During a merge, conflicts may arise if changes overlap, requiring manual resolution to ensure a coherent final result.</p>
<h3 id="heading-git-merge"><code>git merge &lt;branch&gt;</code></h3>
<p>Integrates the changes from the specified branch into your current branch, combining their histories.</p>
<h3 id="heading-git-merge-no-ff"><code>git merge --no-ff &lt;branch&gt;</code></h3>
<p>Merges the specified branch into your current branch, always creating a new merge commit even if a fast-forward merge is possible.</p>
<h3 id="heading-git-merge-squash"><code>git merge --squash &lt;branch&gt;</code></h3>
<p>Combines all the changes from the specified branch into a single commit, preparing the changes for a commit in the current branch without merging the branch’s history. This allows you to manually edit the commit message.</p>
<h3 id="heading-git-merge-abort"><code>git merge --abort</code></h3>
<p>Cancels an ongoing merge process and restores the state of your working directory and index to what it was before the merge started.</p>
<h3 id="heading-git-merge-s-ours-or"><code>git merge -s ours &lt;branch&gt;</code> or</h3>
<h3 id="heading-git-merge-strategyours"><code>git merge —-strategy=ours &lt;branch&gt;</code></h3>
<p>These commands are functionally the same, but the second is the expanded (more explicit) version, while <code>git merge -s ours &lt;branch&gt;</code> is the shorthand version (which is commonly used). You'll see this a few times throughout this guide.</p>
<p>The <code>git merge —-strategy=ours &lt;branch&gt;</code> command (<code>git merge -s ours &lt;branch&gt;</code> for short) performs a merge using the "ours" strategy, which keeps the current branch's changes and discards changes from the specified branch. This effectively merges the histories without integrating the changes from the other branch.</p>
<h3 id="heading-git-merge-strategytheirs"><code>git merge --strategy=theirs &lt;branch&gt;</code></h3>
<p>Merges the specified branch into the current branch using the "theirs" strategy, which resolves all conflicts by favoring changes from the branch being merged. Note that the "theirs" strategy is not a built-in strategy and usually requires custom scripting or is used with tools to handle conflict resolution.</p>
<h2 id="heading-git-remotes"><strong>Git Remotes</strong></h2>
<p>Git remotes are references to remote repositories, which are versions of your project hosted on the internet or another network. They enable collaboration by allowing multiple users to share and sync changes with a central repository.</p>
<p>Common operations with remotes include <code>git fetch</code> to retrieve updates, <code>git pull</code> to fetch and merge changes, and <code>git push</code> to upload local commits to the remote repository.</p>
<p>Managing remotes involves adding, removing, and renaming remote connections, as well as configuring URLs for seamless collaboration.</p>
<h3 id="heading-git-fetch"><code>git fetch</code></h3>
<p>Fetches changes from a remote repository but does not merge them into your current branch.</p>
<h3 id="heading-git-pull"><code>git pull</code></h3>
<p>Fetches changes from a remote repository and immediately merges them into your current branch.</p>
<h3 id="heading-git-push"><code>git push</code></h3>
<p>Uploads your local branch's changes to a remote repository.</p>
<h3 id="heading-git-remote"><code>git remote</code></h3>
<p>Lists the names of remote repositories configured for your local repository.</p>
<h3 id="heading-git-remote-v"><code>git remote -v</code></h3>
<p>Displays the URLs of the remote repositories associated with your local repository, showing both the fetched and pushed URLs.</p>
<h3 id="heading-git-remote-add"><code>git remote add &lt;name&gt; &lt;url&gt;</code></h3>
<p>Adds a new remote repository with the specified name and URL to your local repository configuration.</p>
<h3 id="heading-git-remote-remove-or"><code>git remote remove &lt;name&gt;</code> or</h3>
<h3 id="heading-git-remote-rm"><code>git remote rm &lt;name&gt;</code></h3>
<p>Deletes the specified remote repository connection from your local git configuration. <code>git remote rm &lt;name&gt;</code> is the shorthand version of the command.</p>
<h3 id="heading-git-remote-rename"><code>git remote rename &lt;old_name&gt; &lt;new_name&gt;</code></h3>
<p>Changes the name of an existing remote repository connection in your local Git configuration</p>
<h3 id="heading-git-remote-set-url"><code>git remote set-url &lt;name&gt; &lt;newurl&gt;</code></h3>
<p>Changes the URL of an existing remote repository connection in your local Git configuration.</p>
<h3 id="heading-git-fetch-1"><code>git fetch &lt;remote&gt;</code></h3>
<p>Retrieves the latest changes from the specified remote repository, updating your local copy of the remote branches without merging them into your local branches.</p>
<h3 id="heading-git-pull-1"><code>git pull &lt;remote&gt;</code></h3>
<p>Fetches changes from the specified remote repository and merges them into your current branch.</p>
<h3 id="heading-git-remote-update"><code>git remote update</code></h3>
<p>Fetches updates for all remotes tracked by the repository.</p>
<h3 id="heading-git-push-1"><code>git push &lt;remote&gt; &lt;branch&gt;</code></h3>
<p>Uploads the specified branch from your local repository to the given remote repository.</p>
<h3 id="heading-git-push-delete-1"><code>git push &lt;remote&gt; --delete &lt;branch&gt;</code></h3>
<p>Removes the specified branch from the remote repository.</p>
<h3 id="heading-git-remote-show"><code>git remote show &lt;remote&gt;</code></h3>
<p>Displays detailed information about the specified remote repository, including its URL, fetch and push configurations, and the branches it tracks.</p>
<h3 id="heading-git-ls-remote"><code>git ls-remote &lt;repository&gt;</code></h3>
<p>Lists references (such as branches and tags) and their commit IDs from the specified remote repository. This command allows you to view the branches and tags available in a remote repository without cloning it.</p>
<h3 id="heading-git-push-origin-set-upstream"><code>git push origin &lt;branch&gt; --set-upstream</code></h3>
<p>Pushes the local branch &lt;branch&gt; to the remote repository origin and sets up the local branch to track the remote branch. This lets future git push and git pull commands default to this remote branch.</p>
<h3 id="heading-git-remote-add-upstream"><code>git remote add upstream &lt;repository&gt;</code></h3>
<p>Adds a new remote named upstream to your local repository, pointing to the specified &lt;repository&gt;. This is commonly used to track the original repository from which you forked, while origin typically refers to your own fork.</p>
<h3 id="heading-git-fetch-upstream"><code>git fetch upstream</code></h3>
<p>Retrieves updates from the upstream remote repository, updating your local references to the branches and tags from that remote without modifying your working directory or merging changes.</p>
<h3 id="heading-git-pull-upstream"><code>git pull upstream &lt;branch&gt;</code></h3>
<p>Fetches updates from the &lt;branch&gt; of the upstream remote repository and merges those changes into your current branch. This is often used to integrate changes from the original repository into your own local branch.</p>
<h3 id="heading-git-push-origin"><code>git push origin &lt;branch&gt;</code></h3>
<p>Uploads the local branch &lt;branch&gt; to the origin remote repository, making your branch and its commits available on the remote.</p>
<h2 id="heading-amending-commits"><strong>Amending Commits</strong></h2>
<p>Amending Git commits allows you to modify the most recent commit, typically to correct or update its contents or message. You can do this using the <code>git commit --amend</code> command, which opens the commit in your default text editor for changes.</p>
<p>Amending is particularly useful for fixing small mistakes or adding forgotten changes without creating a new commit, resulting in a cleaner and more accurate commit history.</p>
<h3 id="heading-git-commit-amend"><code>git commit --amend</code></h3>
<p>Modifies the most recent commit, combining staged changes.</p>
<h3 id="heading-git-commit-amend-m-new-message"><code>git commit --amend -m "new message"</code></h3>
<p>Amends the commit message of the most recent commit.</p>
<h3 id="heading-git-commit-fixuphead"><code>git commit --fixup=HEAD</code></h3>
<p>Creates a new commit with the <code>--fixup</code> option that is intended to correct or amend the most recent commit (HEAD). The new commit is marked with a <code>fixup!</code> prefix in the commit message and will be used to automatically fix or amend the specified commit during an interactive rebase.</p>
<h2 id="heading-stashing-in-git"><strong>Stashing in Git</strong></h2>
<p>Git stashing is a feature that allows you to temporarily save changes in your working directory that are not yet ready to be committed.</p>
<p>By using the git stash command, you can set aside these changes and revert your working directory to a clean state, enabling you to switch branches or perform other tasks without losing progress. Later, you can reapply the stashed changes with git stash apply or git stash pop, allowing you to continue where you left off.</p>
<p>This functionality is especially useful for managing work in progress when you need to address an urgent issue or experiment with a different code path.</p>
<h3 id="heading-git-stash"><code>git stash</code></h3>
<p>Temporarily saves your uncommitted changes, allowing you to switch branches or perform other operations without committing incomplete work.</p>
<p>There's an older version, <code>git stash save</code>, that allows you to specify a custom message. But it's largely been deprecated in favor of the simpler <code>git stash</code>.</p>
<h3 id="heading-git-stash-m-message"><code>git stash -m "message"</code></h3>
<p>Same as above, but stores changes with a message. It also has an older version, <code>git stash save "message"</code>, but <code>git stash -m "message"</code> is preferred for versions of Git 2.13 and newer.</p>
<h3 id="heading-git-stash-show"><code>git stash show</code></h3>
<p>Displays a summary of the changes in the most recent stash entry, showing which files were modified.</p>
<h3 id="heading-git-stash-list"><code>git stash list</code></h3>
<p>Shows all the stashed changes in your repository, displaying them in a numbered list.</p>
<h3 id="heading-git-stash-pop"><code>git stash pop</code></h3>
<p>Applies the most recent stash and then immediately removes it from the stash list.</p>
<h3 id="heading-git-stash-drop"><code>git stash drop</code></h3>
<p>Removes the most recent stash entry from the stash list without applying it to your working directory.</p>
<h3 id="heading-git-stash-apply"><code>git stash apply</code></h3>
<p>Reapplies the most recently stashed changes to your working directory without removing them from the stash list.</p>
<h3 id="heading-git-stash-clear"><code>git stash clear</code></h3>
<p>Clears and removes all stashed entries, permanently deleting all saved changes in your stash.</p>
<h3 id="heading-git-stash-branch"><code>git stash branch &lt;branch&gt;</code></h3>
<p>Creates a new branch named &lt;branch&gt; from the commit where you were before stashing your changes. Then it applies the stashed changes to that new branch.</p>
<p>This command effectively allows you to continue working on your stashed changes in a separate branch, preserving the original context and changes.</p>
<h2 id="heading-git-tagging"><strong>Git Tagging</strong></h2>
<p>Git tagging is a feature that allows you to mark specific points in your repository's history as important with a meaningful name, often used for releases or significant milestones.</p>
<p>Unlike branches, tags are typically immutable and do not change, serving as a permanent reference to a particular commit.</p>
<p>There are two types of tags in Git: lightweight tags, which are simple pointers to a commit, and annotated tags, which store additional metadata like the tagger's name, email, date, and a message.</p>
<p>Tags can be easily created, listed, pushed to remote repositories, and deleted, providing a convenient way to manage and reference key points in your project's development timeline.</p>
<h3 id="heading-git-tag"><code>git tag &lt;tag_name&gt;</code></h3>
<p>Creates a new tag with the specified name pointing to the current commit (typically used to mark specific points in the commit history, like releases).</p>
<h3 id="heading-git-tag-a-m-message"><code>git tag -a &lt;tag_name&gt; -m "message"</code></h3>
<p>Creates an annotated tag with the specified name and message, which includes additional metadata like the tagger's name, email, and date, and points to the current commit.</p>
<h3 id="heading-git-tag-d"><code>git tag -d &lt;tag_name&gt;</code></h3>
<p>Deletes the specified tag from your local repository.</p>
<h3 id="heading-git-tag-f"><code>git tag -f &lt;tag&gt; &lt;commit&gt;</code></h3>
<p>Forces a tag to point to a different commit.</p>
<h3 id="heading-git-show"><code>git show &lt;tag_name&gt;</code></h3>
<p>Displays detailed information about the specified tag, including the commit it points to and any associated tag messages or annotations.</p>
<h3 id="heading-git-push-origin-1"><code>git push origin &lt;tag_name&gt;</code></h3>
<p>Uploads the specified tag to the remote repository, making it available to others.</p>
<h3 id="heading-git-push-origin-tags"><code>git push origin --tags</code></h3>
<p>Pushes all local tags to the remote repository, ensuring that all tags are synchronized with the remote.</p>
<h3 id="heading-git-push-follow-tags"><code>git push --follow-tags</code></h3>
<p>Pushes both commits and tags.</p>
<h3 id="heading-git-fetch-tags"><code>git fetch --tags</code></h3>
<p>Retrieves all tags from the default remote repository and updates your local repository with them, without affecting your current branches.</p>
<h2 id="heading-reverting-changes-in-git"><strong>Reverting Changes in Git</strong></h2>
<p>Reverting changes in Git involves undoing modifications made to a repository's history. You can do this using several commands, such as <code>git revert</code>. It creates a new commit that negates the changes of a specified previous commit, effectively reversing its effects while preserving the commit history.</p>
<p>Another method is using <code>git reset</code>, which changes the current HEAD to a specified commit and can update the staging area and working directory depending on the chosen options (<code>--soft</code>, <code>--mixed</code>, or <code>--hard</code>).</p>
<p>You can also use <code>git checkout</code> to discard changes in the working directory, reverting files to their state in the last commit.</p>
<p>These tools provide flexibility in managing and correcting changes, ensuring the repository remains accurate and clean.</p>
<h3 id="heading-git-checkout-2"><code>git checkout -- &lt;file&gt;</code></h3>
<p>Discards changes in the specified file from the working directory, reverting it to the state of the last commit and effectively undoing any modifications that haven't been staged.</p>
<h3 id="heading-git-revert"><code>git revert &lt;commit&gt;</code></h3>
<p>Creates a new commit that undoes the changes in the specified commit, effectively reversing its effects while preserving the history.</p>
<h3 id="heading-git-revert-n"><code>git revert -n &lt;commit&gt;</code></h3>
<p>Reverts a commit but does not commit the result.</p>
<h3 id="heading-git-reset"><code>git reset</code></h3>
<p>Resets the current HEAD to the specified state, and optionally updates the staging area and working directory, depending on the options used (<code>--soft</code>, <code>--mixed</code>, or <code>--hard</code>).</p>
<h3 id="heading-git-reset-soft"><code>git reset --soft &lt;commit&gt;</code></h3>
<p>Moves HEAD to the specified commit, while keeping the index (staging area) and working directory unchanged, so all changes after the specified commit remain staged for committing. This is useful when you want to undo commits but keep the changes ready to be committed again.</p>
<h3 id="heading-git-reset-mixed"><code>git reset --mixed &lt;commit&gt;</code></h3>
<p>Moves HEAD to the specified commit and updates the index (staging area) to match that commit. But it leaves the working directory unchanged, so changes after the specified commit are kept but are untracked.</p>
<h3 id="heading-git-reset-hard"><code>git reset --hard &lt;commit&gt;</code></h3>
<p>Moves HEAD to the specified commit and updates both the index (staging area) and working directory to match that commit. It discards all changes and untracked files after the specified commit.</p>
<h2 id="heading-viewing-history-logs"><strong>Viewing History Logs</strong></h2>
<p>Git history refers to the record of all changes made to a repository over time. It includes a chronological sequence of commits, each representing a snapshot of the repository at a specific point.</p>
<p>This history allows you to track modifications, understand the evolution of the codebase, and collaborate effectively by providing a detailed log of who made changes, when, and why.</p>
<p>Tools like git log help you navigate this history, offering insights into the development process and aiding in debugging and project management.</p>
<h3 id="heading-git-log"><code>git log</code></h3>
<p>Displays the commits log.</p>
<h3 id="heading-git-log-oneline"><code>git log --oneline</code></h3>
<p>Displays a summary of commits with one line each.</p>
<h3 id="heading-git-log-graph"><code>git log --graph</code></h3>
<p>Shows a graphical representation of the commit history.</p>
<h3 id="heading-git-log-stat"><code>git log --stat</code></h3>
<p>Displays file statistics along with the commit history.</p>
<h3 id="heading-git-log-prettyformath-s"><code>git log --pretty=format:"%h %s"</code></h3>
<p>Formats the log output according to the specified format.</p>
<h3 id="heading-git-log-prettyformath-an-ar-s"><code>git log --pretty=format:"%h - %an, %ar : %s"</code></h3>
<p>Provides a more human-readable format for logs.</p>
<h3 id="heading-git-log-author"><code>git log --author=&lt;author&gt;</code></h3>
<p>Shows commits made by the specified author.</p>
<h3 id="heading-git-log-before"><code>git log --before=&lt;date&gt;</code></h3>
<p>Shows commits made before the specified date.</p>
<h3 id="heading-git-log-after"><code>git log --after=&lt;date&gt;</code></h3>
<p>Shows commits made after the specified date (same as <code>git log --since=&lt;date&gt;</code>)</p>
<h3 id="heading-git-log-cherry-pick"><code>git log --cherry-pick</code></h3>
<p>Omits commits that are equivalent between two branches.</p>
<h3 id="heading-git-log-follow"><code>git log --follow &lt;file&gt;</code></h3>
<p>Shows commits for a file, including renames.</p>
<h3 id="heading-git-log-show-signature"><code>git log --show-signature</code></h3>
<p>Displays GPG signature information for commits.</p>
<h3 id="heading-git-shortlog"><code>git shortlog</code></h3>
<p>Summarizes git log output by author.</p>
<h3 id="heading-git-shortlog-sn"><code>git shortlog -sn</code></h3>
<p>Summarizes git log output by author, with commit counts.</p>
<h3 id="heading-git-log-simplify-by-decoration"><code>git log --simplify-by-decoration</code></h3>
<p>Shows only commits that are referenced by tags or branches.</p>
<h3 id="heading-git-log-no-merges"><code>git log --no-merges</code></h3>
<p>Omits merge commits from the log.</p>
<h3 id="heading-git-whatchanged"><code>git whatchanged</code></h3>
<p>Lists commit data in a format similar to a commit log.</p>
<h3 id="heading-git-diff-tree-pretty-name-only-root"><code>git diff-tree --pretty --name-only --root &lt;commit&gt;</code></h3>
<p>Shows detailed information for a commit tree.</p>
<h3 id="heading-git-log-first-parent"><code>git log --first-parent</code></h3>
<p>Only shows commits of the current branch and excludes those merged from other branches.</p>
<h2 id="heading-git-diffs"><strong>Git Diffs</strong></h2>
<p>Git diffs are a feature in Git that allows you to see the differences between various states in your repository. This can include differences between your working directory and the staging area, between the staging area and the last commit, or between any two commits or branches.</p>
<p>By displaying line-by-line changes in files, diffs help you review modifications before committing, merging, or applying changes, thus ensuring accuracy and consistency in your codebase.</p>
<h3 id="heading-git-diff"><code>git diff</code></h3>
<p>Shows the differences between various states in your repository, such as between your working directory and the index (staging area), between the index and the last commit, or between two commits. It displays line-by-line changes in files, helping you review modifications before committing or merging.</p>
<h3 id="heading-git-diff-stat"><code>git diff --stat</code></h3>
<p>Shows a summary of changes between your working directory and the index (staging area), helping you see what files have been modified and how many lines have been added or removed.</p>
<h3 id="heading-git-diff-stat-1"><code>git diff --stat &lt;commit&gt;</code></h3>
<p>Views changes between a commit and the working directory.</p>
<h3 id="heading-git-diff-stat-2"><code>git diff --stat &lt;commit1&gt; &lt;commit2&gt;</code></h3>
<p>Provides a summary of changes between two commits, showing which files were altered and the extent of changes between them.</p>
<h3 id="heading-git-diff-stat-3"><code>git diff --stat &lt;branch1&gt; &lt;branch2&gt;</code></h3>
<p>Summarizes the differences between the two branches, indicating the files changed and the magnitude of changes.</p>
<h3 id="heading-git-diff-name-only"><code>git diff --name-only &lt;commit&gt;</code></h3>
<p>Shows only the names of files that changed in the specified commit.</p>
<h3 id="heading-git-diff-cached"><code>git diff --cached</code></h3>
<p>Shows the differences between the staged changes (index) and the last commit, helping you review what will be included in the next commit.</p>
<h3 id="heading-git-diff-head"><code>git diff HEAD</code></h3>
<p>Shows the differences between the working directory and the latest commit (HEAD), allowing you to see what changes have been made since the last commit.</p>
<h3 id="heading-git-diff-1"><code>git diff &lt;branch1&gt; &lt;branch2&gt;</code></h3>
<p>Shows the differences between the tips of two branches, highlighting the changes between the commits at the end of each branch.</p>
<h3 id="heading-git-difftool"><code>git difftool</code></h3>
<p>Launches a diff tool to compare changes.</p>
<h3 id="heading-git-difftool-1"><code>git difftool &lt;commit1&gt; &lt;commit2&gt;</code></h3>
<p>Uses the diff tool to show the differences between two specified commits.</p>
<h3 id="heading-git-difftool-2"><code>git difftool &lt;branch1&gt; &lt;branch2&gt;</code></h3>
<p>Opens the diff tool to compare changes between two branches.</p>
<h3 id="heading-git-cherry"><code>git cherry &lt;branch&gt;</code></h3>
<p>Compares the commits in your current branch against another branch and shows which commits are unique to each branch. It is commonly used to identify which commits in one branch have not been applied to another branch.</p>
<h2 id="heading-git-flow"><strong>Git Flow</strong></h2>
<p>Git Flow is a branching model for Git that provides a robust framework for managing larger projects. It defines a strict branching strategy designed around the project release cycle, with two primary branches (main and develop) and supporting branches for features, releases, and hotfixes.</p>
<p>This model helps in organizing work, ensuring a clean and manageable history, and facilitating collaboration by clearly defining roles and processes for different types of development work.</p>
<h3 id="heading-git-flow-init"><code>git flow init</code></h3>
<p>Initializes a repository for a git-flow branching model.</p>
<h3 id="heading-git-flow-feature-start"><code>git flow feature start &lt;feature&gt;</code></h3>
<p>Starts a new feature branch in git-flow.</p>
<h3 id="heading-git-flow-feature-finish"><code>git flow feature finish &lt;feature&gt;</code></h3>
<p>Finishes a feature branch in git-flow.</p>
<h2 id="heading-exploring-git-references"><strong>Exploring Git References</strong></h2>
<p>Git references, often referred to as refs, are pointers to specific commits or objects within a Git repository. These can include branches, tags, and other references like HEAD, which points to the current commit checked out in your working directory.</p>
<p>References are used to keep track of the structure and history of the repository. They help Git efficiently manage and navigate different points in the project's timeline.</p>
<p>Refs also provide a way to name and refer to particular commits, making it easier to work with and manipulate the repository's history.</p>
<h3 id="heading-git-show-ref-heads"><code>git show-ref --heads</code></h3>
<p>Lists references to all heads (branches).</p>
<h3 id="heading-git-show-ref-tags"><code>git show-ref --tags</code></h3>
<p>Lists references to all tags.</p>
<h2 id="heading-how-to-configure-git"><strong>How to Configure Git</strong></h2>
<p>Git configuration involves setting up various options and preferences that control the behavior of your Git environment. This can include specifying your username and email, setting up default text editors, creating aliases for commonly used commands, and configuring global ignore files.</p>
<p>You can apply configuration settings at different levels: global (affecting all repositories on your system), local (affecting a single repository), and system-wide. These settings ensure a customized and consistent user experience, streamline workflows, and enhance the overall efficiency of version control operations.</p>
<h3 id="heading-git-config-global-usernamehttpusername-your-name"><code>git config --global</code> <a target="_blank" href="http://user.name"><code>user.name</code></a> <code>"Your Name"</code></h3>
<p>Sets the user name on a global level.</p>
<h3 id="heading-git-config-global-useremailhttpuseremail-youremailexamplecom"><code>git config --global</code> <a target="_blank" href="http://user.email"><code>user.email</code></a> <code>"your_email@example.com"</code></h3>
<p>Sets the user email on a global level.</p>
<h3 id="heading-git-config-global-coreeditor"><code>git config --global core.editor &lt;editor&gt;</code></h3>
<p>Sets the default text editor.</p>
<h3 id="heading-git-config-global-coreexcludesfile"><code>git config --global core.excludesfile &lt;file&gt;</code></h3>
<p>Sets the global ignore file.</p>
<h3 id="heading-git-config-list"><code>git config --list</code></h3>
<p>Lists all the configuration settings.</p>
<h3 id="heading-git-config-list-show-origin"><code>git config --list --show-origin</code></h3>
<p>Lists all config variables, showing their origins.</p>
<h3 id="heading-git-config"><code>git config &lt;key&gt;</code></h3>
<p>Retrieves the value for the specified key.</p>
<h3 id="heading-git-config-get"><code>git config --get &lt;key&gt;</code></h3>
<p>Retrieves the value for the specified configuration key.</p>
<h3 id="heading-git-config-unset"><code>git config --unset &lt;key&gt;</code></h3>
<p>Removes the specified configuration key.</p>
<h3 id="heading-git-config-global-unset"><code>git config --global --unset &lt;key&gt;</code></h3>
<p>Removes the specified configuration key globally.</p>
<h2 id="heading-git-security"><strong>Git Security</strong></h2>
<p>Git GPG security involves using GNU Privacy Guard (GPG) to sign commits and tags, ensuring their authenticity and integrity. By configuring a GPG key and enabling automatic signing, you can verify that commits and tags were created by a trusted source. This helps prevent tampering and ensures the integrity of the repository's history.</p>
<p>This practice enhances security by providing cryptographic assurance that the changes come from a legitimate contributor.</p>
<h3 id="heading-git-config-global-usersigningkey"><code>git config --global user.signingKey &lt;key&gt;</code></h3>
<p>Configures the GPG key for signing commits and tags.</p>
<h3 id="heading-git-config-global-commitgpgsign-true"><code>git config --global commit.gpgSign true</code></h3>
<p>Automatically signs all commits with GPG.</p>
<h2 id="heading-how-to-set-aliases-in-git"><strong>How to Set Aliases in Git</strong></h2>
<p>Git aliases are custom shortcuts that you can create to simplify and speed up your workflow by mapping longer Git commands to shorter, more memorable names.</p>
<p>By configuring aliases in your Git settings, you can quickly execute frequently used commands with less typing. This not only enhances productivity but also reduces the likelihood of errors.</p>
<p>For example, you can set an alias like git st to replace git status, or git co to replace git checkout.</p>
<p>You can define aliases globally to apply across all repositories or locally for individual projects, providing flexibility in how you streamline your Git operations.</p>
<h3 id="heading-git-config-global-aliasci-commit"><code>git config --global alias.ci commit</code></h3>
<p>Sets git ci as an alias for git commit.</p>
<h3 id="heading-git-config-global-aliasst-status"><code>git config --global alias.st status</code></h3>
<p>Sets git st as an alias for git status.</p>
<h3 id="heading-git-config-global-aliasco-checkout"><code>git config --global alias.co checkout</code></h3>
<p>Sets git co as an alias for git checkout.</p>
<h3 id="heading-git-config-global-aliasbr-branch"><code>git config --global alias.br branch</code></h3>
<p>Sets git br as an alias for git branch.</p>
<h3 id="heading-git-config-global-aliasgraph-log-graph-all-oneline-decorate"><code>git config --global alias.graph "log --graph --all --oneline --decorate"</code></h3>
<p>Creates an alias for a detailed graph of the repository history.</p>
<h2 id="heading-rebasing-in-git"><strong>Rebasing in Git</strong></h2>
<p>Git rebasing re-applies your changes on top of another branch's history, creating a cleaner and more linear project history.</p>
<p>In practice, this helps integrate updates smoothly by avoiding unnecessary merge commits, ensuring that the commit sequence is straightforward, and making it easier to understand the evolution of the project.</p>
<h3 id="heading-git-rebase"><code>git rebase &lt;branch&gt;</code></h3>
<p>The git rebase command is used to re-apply commits on top of another base tip. It allows you to move or combine a sequence of commits to a new base commit. This is commonly used to:</p>
<ol>
<li><p>Keep a linear project history.</p>
</li>
<li><p>Integrate changes from one branch into another.</p>
</li>
<li><p>Update a feature branch with the latest changes from the main branch.</p>
</li>
</ol>
<p>The basic usage is git rebase &lt;branch&gt;, which will rebase the current branch onto the specified branch.</p>
<h3 id="heading-git-rebase-interactive"><code>git rebase --interactive &lt;branch&gt;</code></h3>
<p>Starts an interactive rebase session, allowing you to modify commits starting from &lt;base&gt; up to the current HEAD. This lets you reorder, squash, edit, or delete commits, providing a way to clean up and refine commit history before pushing changes. Shorter version: <code>git rebase -i &lt;branch&gt;</code></p>
<h3 id="heading-git-rebase-continue"><code>git rebase --continue</code></h3>
<p>Continues the rebase process after resolving conflicts.</p>
<h3 id="heading-git-rebase-abort"><code>git rebase --abort</code></h3>
<p>Aborts the rebase process and returns to the original branch.</p>
<h3 id="heading-git-fetch-rebase"><code>git fetch --rebase</code></h3>
<p>Fetches from the remote repository and rebases local changes.</p>
<h2 id="heading-what-is-cherry-picking"><strong>What is Cherry-Picking?</strong></h2>
<p>Git cherry-picking is a process that allows you to apply the changes introduced by a specific commit from one branch into another branch. This is particularly useful when you want to selectively incorporate individual changes from different branches without merging the entire branch.</p>
<p>By using the git cherry-pick command, you can isolate and integrate only the desired commits, ensuring that specific modifications are included in your current branch while avoiding potential conflicts and unwanted changes from other parts of the branch.</p>
<h3 id="heading-git-cherry-pick"><code>git cherry-pick &lt;commit&gt;</code></h3>
<p>Applies the changes introduced by an existing commit.</p>
<h3 id="heading-git-cherry-pick-continue"><code>git cherry-pick --continue</code></h3>
<p>Continues cherry-picking after resolving conflicts.</p>
<h3 id="heading-git-cherry-pick-abort"><code>git cherry-pick --abort</code></h3>
<p>Aborts the cherry-pick process.</p>
<h3 id="heading-git-cherry-pick-no-commit"><code>git cherry-pick --no-commit &lt;commit&gt;</code></h3>
<p>Cherry-picks a commit without automatically committing and allows further changes. Shorter version: <code>git cherry-pick -n &lt;commit&gt;</code></p>
<h2 id="heading-patching-in-git"><strong>Patching in Git</strong></h2>
<p>Git patching is a method used to apply changes from one repository to another or from one branch to another within the same repository. It involves creating patch files, which are text files representing differences between commits or branches. These patch files can then be applied to a repository using commands like <code>git apply</code> or <code>git am</code>, allowing changes to be transferred and integrated without directly merging branches.</p>
<p>Patching is particularly useful for sharing specific changes or updates across different codebases, ensuring that only the intended modifications are applied.</p>
<h3 id="heading-git-apply"><code>git apply &lt;patch_file&gt;</code></h3>
<p>Applies changes to the working directory from a patch file.</p>
<h3 id="heading-git-apply-check"><code>git apply --check</code></h3>
<p>Checks if patches can be applied cleanly.</p>
<h3 id="heading-git-format-patch"><code>git format-patch &lt;since_commit&gt;</code></h3>
<p>Creates patch files for each commit since the specified commit.</p>
<h3 id="heading-git-am"><code>git am &lt;patch_file&gt;</code></h3>
<p>Applies patches from a mailbox.</p>
<h3 id="heading-git-am-continue"><code>git am --continue</code></h3>
<p>Continues applying patches after resolving conflicts.</p>
<h3 id="heading-git-am-abort"><code>git am --abort</code></h3>
<p>Aborts the patch application process.</p>
<h3 id="heading-git-diff-gt"><code>git diff &gt; &lt;file.patch&gt;</code></h3>
<p>Creates a patch file from differences.</p>
<h2 id="heading-relative-dates-in-git"><strong>Relative Dates in Git</strong></h2>
<p>Git relative dates allow users to refer to specific points in the repository's history using human-readable time expressions. For instance, commands like main@{1.week.ago} or @{3.days.ago} enable you to access the state of a branch or view changes made since a certain time period relative to the current date.</p>
<p>This feature simplifies navigating the repository's timeline by using intuitive terms like "yesterday," "2 weeks ago," or specific dates, making it easier to track and manage the evolution of the codebase without needing to remember exact commit hashes or timestamps.</p>
<h3 id="heading-git-show-main1weekago"><code>git show main@{1.week.ago}</code></h3>
<p>Lets you see the state of your main branch one week ago.</p>
<h3 id="heading-git-diff-3daysago"><code>git diff @{3.days.ago}</code></h3>
<p>Shows what changes you've made in the last 3 days.</p>
<h3 id="heading-git-checkout-main2weeksago"><code>git checkout main@{2.weeks.ago}</code></h3>
<p>Checks out your repository as it was 2 weeks ago.</p>
<h3 id="heading-git-log-1monthagohead"><code>git log @{1.month.ago}..HEAD</code></h3>
<p>Shows you the log of commits from 1 month ago until now.</p>
<h3 id="heading-2024-06-01"><code>@{2024-06-01}</code></h3>
<h3 id="heading-yesterday"><code>@{yesterday}</code></h3>
<h3 id="heading-1-week-2-days-ago"><code>@{"1 week 2 days ago"}</code></h3>
<p>Other usage examples.</p>
<h2 id="heading-git-blame"><strong>Git Blame</strong></h2>
<p>Git blaming is a feature in Git that identifies the last modification made to each line of a file, attributing changes to specific commits and authors. You can do this using the <code>git blame</code> command, which provides a detailed annotation of the file, showing who made changes and when they were made.</p>
<p>This tool is particularly useful for tracking the history of a file, understanding the evolution of the code, and identifying the source of bugs or changes.</p>
<p>By pinpointing the exact commit and author responsible for each line, developers can gain insights into the development process and facilitate better collaboration and accountability within a team.</p>
<h3 id="heading-git-blame-1"><code>git blame &lt;file&gt;</code></h3>
<p>Shows the last modification for each line of a file.</p>
<h3 id="heading-git-blame-l"><code>git blame &lt;file&gt; -L &lt;start&gt;,&lt;end&gt;</code></h3>
<p>Limits the blame output to the specified line range.</p>
<h3 id="heading-git-blame-2"><code>git blame &lt;file&gt; &lt;commit&gt;</code></h3>
<p>Shows the blame information up to the specified commit.</p>
<h3 id="heading-git-blame-c-c"><code>git blame &lt;file&gt; -C -C</code></h3>
<p>Shows which revisions and authors last modified each line of a file, with copying detection.</p>
<p>The <code>-C</code> option detects lines moved or copied within the same file. Using it once (<code>-C</code>) detects lines moved or copied within the same file. Using the <code>-C</code> option twice (<code>-C -C</code>) makes Git inspect unmodified files as candidates for the source of copy. This means it will try to find the origin of copied lines not just in the same file but in other files as well.</p>
<h3 id="heading-git-blame-reverse"><code>git blame &lt;file&gt; --reverse</code></h3>
<p>Works backwards, showing who last altered each line in the specified file.</p>
<h3 id="heading-git-blame-first-parent"><code>git blame &lt;file&gt; --first-parent</code></h3>
<p>Shows who most recently modified each line in a file, following only the first parent commit for merge changes.</p>
<h2 id="heading-archiving-in-git"><strong>Archiving in Git</strong></h2>
<p>Git archiving is a feature that allows you to create archive files, such as .tar or .zip, containing the contents of a specific commit, branch, or tag. This is useful for packaging a snapshot of your repository at a specific point in time, enabling you to distribute or backup the repository's state without including the entire Git history.</p>
<p>The git archive command is typically used for this purpose, providing a convenient way to export the current state of the project into a portable format.</p>
<h3 id="heading-git-archive"><code>git archive &lt;format&gt; &lt;tree-ish&gt;</code></h3>
<p>Creates an archive file (for example, a .tar or .zip file) containing the contents of the specified tree-ish (like a commit, branch, or tag) in the given format. For example:</p>
<ul>
<li><p><code>git archive --format=tar HEAD</code> creates a .tar archive of the current commit (HEAD).</p>
</li>
<li><p><code>git archive --format=zip v1.0</code> creates a .zip archive of the files in the v1.0 tag.</p>
</li>
</ul>
<p>This command is useful for packaging a snapshot of your repository at a specific point in time.</p>
<h2 id="heading-how-to-track-files-in-git"><strong>How to Track Files in Git</strong></h2>
<p>Git tracking refers to the process of monitoring and managing the files in a repository.</p>
<p>The command <code>git ls-files</code> lists all files that are being tracked by Git, providing a clear view of the files that are currently under version control. On the other hand, <code>git ls-tree &lt;branch&gt;</code> displays the contents of a tree object for a specified branch, showing the structure and files at that point in the repository.</p>
<p>Together, these commands help developers understand which files are included in the repository and how they are organized, ensuring efficient tracking and management of the project's codebase.</p>
<h3 id="heading-git-ls-files"><code>git ls-files</code></h3>
<p>Lists all tracked files.</p>
<h3 id="heading-git-ls-tree"><code>git ls-tree &lt;branch&gt;</code></h3>
<p>Lists the contents of a tree object.</p>
<h2 id="heading-index-manipulation-in-git"><strong>Index Manipulation in Git</strong></h2>
<p>Git index manipulation involves managing the staging area (also known as the index) where changes are prepared before committing. This can include marking files as "assume unchanged" to temporarily ignore changes, or resetting these markings to track changes again.</p>
<p>Index manipulation commands, such as <code>git update-index</code>, allow you to control which files are included in the next commit, providing flexibility in handling changes and optimizing the workflow for specific tasks.</p>
<h3 id="heading-git-update-index-assume-unchanged"><code>git update-index --assume-unchanged &lt;file&gt;</code></h3>
<p>Marks a file as assume unchanged.</p>
<h3 id="heading-git-update-index-no-assume-unchanged"><code>git update-index --no-assume-unchanged &lt;file&gt;</code></h3>
<p>Unmarks a file as assume unchanged.</p>
<h2 id="heading-squashing-in-git"><strong>Squashing in Git</strong></h2>
<p>Git squashing is the process of combining multiple commits into a single commit. Devs often do this to clean up the commit history before merging changes into a main branch, making the history more concise and easier to read.</p>
<p>Squashing can be performed using the interactive rebase command (<code>git rebase -i</code>), which lets you selectively merge, reorder, or edit commits. By squashing commits, you can consolidate redundant or minor changes, presenting a clearer narrative of the development process.</p>
<h3 id="heading-git-rebase-i-head"><code>git rebase -i HEAD~&lt;n&gt;</code></h3>
<p>Squashes commits interactively.</p>
<h2 id="heading-data-integrity-in-git"><strong>Data Integrity in Git</strong></h2>
<p>Git data integrity refers to the mechanisms and processes Git employs to ensure the accuracy and consistency of data within a repository.</p>
<p>Git uses cryptographic hashes (SHA-1 or SHA-256) to uniquely identify objects such as commits, trees, and blobs. This hashing not only provides a unique identifier for each object but also ensures that any modification to the object's content will result in a different hash, thus detecting any corruption or tampering.</p>
<p>You can use commands like <code>git fsck</code> to verify the connectivity and validity of objects in the database, ensuring the overall health and integrity of the repository.</p>
<h3 id="heading-git-fsck"><code>git fsck</code></h3>
<p>Verifies the connectivity and validity of objects in the database.</p>
<h3 id="heading-git-fsck-unreachable"><code>git fsck --unreachable</code></h3>
<p>Finds objects in the repository that are not reachable from any reference.</p>
<h3 id="heading-git-prune"><code>git prune</code></h3>
<p>Removes unreachable objects.</p>
<h3 id="heading-git-gc"><code>git gc</code></h3>
<p>Runs a garbage collection process.</p>
<p>Git garbage collection is a maintenance process that cleans up and optimizes the repository by removing unnecessary files and compressing file revisions to save space. This process, triggered by the <code>git gc</code> command, consolidates and deletes unreachable objects, such as orphaned commits and unreferenced blobs, ensuring the repository remains efficient and performant.</p>
<p>Regular garbage collection helps manage storage effectively and keeps the repository's structure organized.</p>
<h2 id="heading-cleaning-up-in-git"><strong>Cleaning Up in Git</strong></h2>
<p>Cleaning up in Git involves removing unnecessary files, references, and branches that are no longer needed. This helps to keep your repository organized and efficient.</p>
<p>Regular cleanup activities, such as pruning remote-tracking branches, deleting untracked files, and removing stale references, ensure that your repository remains manageable and free from clutter.</p>
<p>In practice, these actions can improve performance, reduce storage requirements, and make it easier to navigate and work within your project.</p>
<h3 id="heading-git-fetch-prune"><code>git fetch --prune</code></h3>
<p>Removes references that no longer exist on the remote.</p>
<h3 id="heading-git-remote-prune"><code>git remote prune &lt;name&gt;</code></h3>
<p>Prunes all stale remote-tracking branches.</p>
<h3 id="heading-git-fetch-origin-prune"><code>git fetch origin --prune</code></h3>
<p>Cleans up outdated references from the remote repository.</p>
<h3 id="heading-git-clean-f"><code>git clean -f</code></h3>
<p>Removes untracked files from the working directory, forcing the deletion of files not being tracked by Git.</p>
<h3 id="heading-git-clean-fd"><code>git clean -fd</code></h3>
<p>Removes untracked files and directories from the working directory, including any files and directories not tracked by Git.</p>
<h3 id="heading-git-clean-i"><code>git clean -i</code></h3>
<p>Enters interactive mode for cleaning untracked files.</p>
<h3 id="heading-git-clean-x"><code>git clean -X</code></h3>
<p>Removes only ignored files from the working directory.</p>
<h2 id="heading-git-subtree"><strong>Git Subtree</strong></h2>
<p>Git subtree is a mechanism for managing and integrating subprojects into a main repository. Unlike submodules, which treat the subproject as a separate entity with its own repository, subtrees allow you to include the contents of another repository directly within a subdirectory of your main repository.</p>
<p>This approach simplifies the workflow by eliminating the need for multiple repositories and enabling seamless integration, merging, and pulling of updates from the subproject. Subtrees provide a flexible and convenient way to manage dependencies and collaborate on projects that require incorporating external codebases.</p>
<h3 id="heading-git-subtree-add-prefix"><code>git subtree add --prefix=&lt;dir&gt; &lt;repository&gt; &lt;branch&gt;</code></h3>
<p>Adds a repository as a subtree.</p>
<h3 id="heading-git-subtree-merge-prefix"><code>git subtree merge --prefix=&lt;dir&gt; &lt;branch&gt;</code></h3>
<p>Merges a subtree.</p>
<h3 id="heading-git-subtree-pull-prefix"><code>git subtree pull --prefix=&lt;dir&gt; &lt;repository&gt; &lt;branch&gt;</code></h3>
<p>Pulls in new changes from the subtree's repository.</p>
<h2 id="heading-how-to-search-in-git"><strong>How to Search in Git</strong></h2>
<p><code>git grep</code> is a powerful search command in Git that allows users to search for specific strings or patterns within the files of a repository. It searches through the working directory and the index, providing a quick and efficient way to locate occurrences of a specified pattern across multiple files.</p>
<p>This command is particularly useful for developers looking to find instances of code, comments, or text within a project, enabling them to navigate and understand large codebases with ease. With various options and flags, git grep lets you perform targeted searches, making it an essential tool for code analysis and maintenance.</p>
<h3 id="heading-git-grep"><code>git grep &lt;pattern&gt;</code></h3>
<p>Searches for a string in the working directory and the index.</p>
<h3 id="heading-git-grep-e"><code>git grep -e &lt;pattern&gt;</code></h3>
<p>Searches for a specific pattern.</p>
<h2 id="heading-bisecting-in-git"><strong>Bisecting in Git</strong></h2>
<p>Git bisecting is a powerful debugging tool that helps identify the specific commit that introduced a bug or issue in a project. By performing a binary search through the commit history, git bisect efficiently narrows down the range of potential problem commits.</p>
<p>The process involves marking a known good commit and a known bad commit, and then repeatedly testing intermediate commits to determine whether they are good or bad.</p>
<p>This iterative approach quickly isolates the faulty commit, allowing developers to pinpoint the exact change that caused the problem. This facilitates faster and more accurate debugging.</p>
<h3 id="heading-git-bisect-start"><code>git bisect start</code></h3>
<p>Starts a bisect session.</p>
<h3 id="heading-git-bisect-bad"><code>git bisect bad</code></h3>
<p>Marks the current version as bad.</p>
<h3 id="heading-git-bisect-good"><code>git bisect good &lt;commit&gt;</code></h3>
<p>Marks the specified commit as good.</p>
<h3 id="heading-git-bisect-reset"><code>git bisect reset</code></h3>
<p>Ends a bisect session and returns to the original branch.</p>
<h3 id="heading-git-bisect-visualize"><code>git bisect visualize</code></h3>
<p>Launches a visual tool to assist with bisecting.</p>
<h2 id="heading-git-attributes"><strong>Git Attributes</strong></h2>
<p>Git attributes are settings that define how Git should handle specific files or paths within a repository. These attributes are defined in a file named .gitattributes, and they can control various behaviors such as text encoding, line-ending normalization, merge strategies, and diff algorithms.</p>
<p>By setting attributes, you can ensure consistent behavior across different environments and collaborators, making it easier to manage files with special requirements or complexities.</p>
<p>For example, you can mark certain files as binary to prevent Git from attempting to merge them, or specify custom diff drivers for more meaningful comparisons.</p>
<h3 id="heading-git-check-attr"><code>git check-attr &lt;attribute&gt; -- &lt;file&gt;</code></h3>
<p>Shows the value of a specific attribute for the given file as defined in the .gitattributes configuration, helping you understand how Git is treating the file with respect to attributes like text encoding, merge behavior, or diff handling.</p>
<h2 id="heading-git-checkout-3"><strong>Git Checkout</strong></h2>
<p><code>git checkout</code> is a versatile command in Git used to switch between different branches, tags, or commits within a repository. By updating the working directory and index to match the specified branch or commit, it allows you to view or work with the state of the repository at that point.</p>
<p>You can also use <code>git checkout</code> to create new branches, restore specific files from a commit, or even start a new branch with no history using the <code>--orphan</code> option. This command is essential for navigating and managing different versions of a project's codebase.</p>
<h3 id="heading-git-checkout-4"><code>git checkout &lt;commit&gt;</code></h3>
<p>Updates the working directory and index to match the specified commit, allowing you to view or work with the state of the repository at that commit. Just keep in mind that this leaves you in a "detached HEAD" state, meaning you're not on any branch.</p>
<h3 id="heading-git-checkout-b-1"><code>git checkout -b &lt;branch&gt; &lt;commit&gt;</code></h3>
<p>Creates a new branch named &lt;branch&gt; starting from the specified commit and switches to that branch, allowing you to begin working from that point in the commit history.</p>
<h3 id="heading-git-checkout-5"><code>git checkout &lt;commit&gt; -- &lt;file&gt;</code></h3>
<p>Restores the specified file from a specific commit into your working directory, replacing the current version of the file with the version from that commit without changing the commit history or index.</p>
<h3 id="heading-git-checkout-orphan"><code>git checkout --orphan &lt;new_branch&gt;</code></h3>
<p>Creates a new branch named &lt;new_branch&gt; with no commit history, effectively starting a new branch that begins with a clean working directory and index, as if it were a new repository.</p>
<h2 id="heading-git-reflog"><strong>Git Reflog</strong></h2>
<p>Git reflog is a powerful tool that records all changes made to the tips of branches and the HEAD reference in a Git repository. This includes actions such as commits, checkouts, merges, and resets.</p>
<p>By maintaining a history of these changes, reflog allows users to track recent modifications and recover lost commits, even if they are not part of the current branch history. It provides a way to navigate through the repository's state changes, making it an invaluable resource for debugging and undoing mistakes.</p>
<h3 id="heading-git-reflog-1"><code>git reflog</code></h3>
<p>Displays a log of all the changes to the HEAD reference and branch tips, including commits, checkouts, merges, and resets, allowing you to recover lost commits or track recent changes to the repository's state.</p>
<h3 id="heading-git-reflog-show"><code>git reflog show &lt;ref&gt;</code></h3>
<p>Displays the reflog for the specified reference (&lt;ref&gt;), showing a log of changes to that reference, including updates to HEAD or branch tips, along with associated commit messages and timestamps.</p>
<h2 id="heading-how-to-handle-untracked-files-in-git"><strong>How to Handle Untracked Files in Git</strong></h2>
<h3 id="heading-git-clean"><code>git clean</code></h3>
<p><code>git clean</code> removes untracked files and directories from the working directory. By default, it only shows what would be removed without actually deleting anything.</p>
<p>To perform the actual cleanup, you need to use additional flags:</p>
<ul>
<li><p><code>git clean -f</code>: Removes untracked files.</p>
</li>
<li><p><code>git clean -fd</code>: Removes untracked files and directories.</p>
</li>
<li><p><code>git clean -fx</code>: Removes untracked files, including those ignored by .gitignore.</p>
</li>
<li><p><code>git clean -n</code>: Shows which files would be removed without actually deleting them.</p>
</li>
</ul>
<h2 id="heading-force-pushing-in-git"><strong>Force Pushing in Git</strong></h2>
<h3 id="heading-git-push-force"><code>git push --force</code></h3>
<p>Forces a push of your local branch to the remote repository, even if it results in a non-fast-forward merge. It overwrites the remote branch with your local changes.</p>
<p>This can be necessary when you have rewritten history (for example, with a rebase) and need to update the remote branch to match your local branch. But it can also potentially overwrite others' changes – so use it with caution.</p>
<h2 id="heading-git-fetching-and-pulling"><strong>Git Fetching and Pulling</strong></h2>
<h3 id="heading-git-fetch-all"><code>git fetch --all</code></h3>
<p>Retrieves updates from all remote repositories configured for your local repository, fetching changes from all branches and tags without modifying your local branches.</p>
<h3 id="heading-git-pull-rebase"><code>git pull --rebase</code></h3>
<p>Fetches changes from the remote repository and rebases your local commits on top of the updated remote branch, rather than merging them. This keeps the commit history linear and avoids unnecessary merge commits.</p>
<h2 id="heading-how-to-handle-merge-conflicts-in-git"><strong>How to Handle Merge Conflicts in Git</strong></h2>
<p>Handling merge conflicts in Git is an essential skill for collaborating on projects with multiple contributors.</p>
<p>Merge conflicts occur when changes in different branches or commits overlap or contradict each other, preventing an automatic merge. Resolving these conflicts involves reviewing and manually reconciling the differences to ensure that the final code integrates contributions from all parties accurately.</p>
<p>In practice, effectively managing merge conflicts helps maintain code integrity and facilitates smooth collaboration by ensuring that everyone's changes are correctly incorporated into the project's history.</p>
<h3 id="heading-git-mergetool"><code>git mergetool</code></h3>
<p>This launches a merge tool to help you resolve conflicts that arise during a merge or rebase. It opens a graphical interface or a text-based tool configured in your Git settings, allowing you to manually resolve conflicts and finalize the merge.</p>
<h3 id="heading-git-rerere"><code>git rerere</code></h3>
<p><code>rerere</code> stands for "reuse recorded resolution" and is a feature that helps automatically resolve conflicts in future merges or rebases by reusing conflict resolutions you've previously recorded.</p>
<p>Once enabled, Git records how you resolved conflicts. If the same conflicts arise again, it can apply the same resolutions automatically.</p>
<h2 id="heading-working-trees-in-git"><strong>Working Trees in Git</strong></h2>
<p>Working trees in Git allow you to have multiple working directories associated with a single repository. This is particularly useful for working on multiple branches simultaneously without the need to constantly switch branches in the same directory.</p>
<p>By using working trees, you can easily manage different features, bug fixes, or experiments in isolated environments, improving workflow efficiency and reducing the risk of conflicts.</p>
<h3 id="heading-git-worktree-add-new-branch-feature-branch"><code>git worktree add ../new-branch feature-branch</code></h3>
<p>Creates a new working tree in a directory named "new-branch" based on the "feature-branch".</p>
<h3 id="heading-git-worktree-list"><code>git worktree list</code></h3>
<p>Lists all working trees associated with the current repository, showing their paths and the branches they are checked out to.</p>
<h3 id="heading-git-worktree-remove"><code>git worktree remove &lt;path&gt;</code></h3>
<p>Removes the specified working tree at the given &lt;path&gt;, deleting the working directory and detaching the branch.</p>
<h3 id="heading-git-worktree-prune"><code>git worktree prune</code></h3>
<p>Removes references to nonexistent working trees, cleaning up the working tree list.</p>
<h3 id="heading-git-worktree-lock"><code>git worktree lock &lt;path&gt;</code></h3>
<p>Locks the specified working tree at the given &lt;path&gt;, preventing it from being pruned.</p>
<h3 id="heading-git-worktree-unlock"><code>git worktree unlock &lt;path&gt;</code></h3>
<p>Unlocks the specified working tree at the given &lt;path&gt;, allowing it to be pruned if necessary.</p>
<h2 id="heading-submodules-in-git"><strong>Submodules in Git</strong></h2>
<p>Submodules in Git are a way to include and manage external repositories within your own repository. They are particularly useful for reusing code across multiple projects, maintaining dependencies, or integrating third-party libraries.</p>
<p>By using submodules, you can keep your main repository clean and modular, while still ensuring that all necessary components are included and version-controlled.</p>
<h3 id="heading-git-submodule-init"><code>git submodule init</code></h3>
<p>Initializes submodules in your repository. This command sets up the configuration necessary for the submodules, but doesn't actually clone them.</p>
<h3 id="heading-git-submodule-update"><code>git submodule update</code></h3>
<p>Clones and checks out the submodules into the specified paths. This is typically run after git submodule init.</p>
<h3 id="heading-git-submodule-add"><code>git submodule add &lt;repository&gt; &lt;path&gt;</code></h3>
<p>Adds a new submodule to your repository at the specified path, linking it to the specified repository.</p>
<h3 id="heading-git-submodule-status"><code>git submodule status</code></h3>
<p>Displays the status of all submodules, showing their commit hashes and whether they are up-to-date, modified, or uninitialized.</p>
<h3 id="heading-git-submodule-foreach"><code>git submodule foreach &lt;command&gt;</code></h3>
<p>Runs the specified command in each submodule. This is useful for performing batch operations across all submodules.</p>
<h3 id="heading-git-submodule-sync"><code>git submodule sync</code></h3>
<p>Synchronizes the submodule URLs in your configuration file with those in the .gitmodules file, ensuring they are up-to-date.</p>
<h3 id="heading-git-submodule-deinit"><code>git submodule deinit &lt;path&gt;</code></h3>
<p>Unregisters the specified submodule, removing its configuration. This doesn't delete the submodule's working directory.</p>
<h3 id="heading-git-submodule-update-remote"><code>git submodule update --remote</code></h3>
<p>Fetches and updates the submodules to the latest commit from their remote repositories.</p>
<h3 id="heading-git-submodule-set-url"><code>git submodule set-url &lt;path&gt; &lt;newurl&gt;</code></h3>
<p>Changes the URL of the specified submodule to the new URL.</p>
<h3 id="heading-git-submodule-absorbgitdirs"><code>git submodule absorbgitdirs</code></h3>
<p>Absorbs the submodule's Git directory into the superproject to simplify the structure.</p>
<p>Thank you for reading! I hope this cheatsheet helps you work more easily in Git.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
