<?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[ Git - 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[ Git - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Wed, 20 May 2026 22:46:38 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/git/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Make Your GitHub Profile Stand Out ]]>
                </title>
                <description>
                    <![CDATA[ If you have a Github profile, you might overlook the many ways you can customize it – and that's completely understandable. After all, at its core, GitHub is a home for your code. But beyond repositor ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-make-your-github-profile-stand-out/</link>
                <guid isPermaLink="false">69e2cd3ffd22b8ad62900fb3</guid>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hiring ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #developerportfolio ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chinaza Chukwunweike ]]>
                </dc:creator>
                <pubDate>Sat, 18 Apr 2026 00:15:59 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/db5b026f-24ce-4b59-b133-9326eb8c4c06.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you have a Github profile, you might overlook the many ways you can customize it – and that's completely understandable. After all, at its core, GitHub is a home for your code.</p>
<p>But beyond repositories and commits, your profile can say <em>a lot</em> about you as a developer.</p>
<p>When used intentionally, GitHub becomes more than a code hosting platform. It becomes your <strong>CV for your codebase</strong>. It tells your story, showcases your skills, and gives people a reason to trust your work.</p>
<p>In this article, we'll break down the different ways to make your GitHub profile stand out. From setting up your GitHub account to engaging storytelling for your repositories, there's lots you can do.</p>
<p>Let's get started!</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-sign-up-for-a-github-account">Sign Up for a Github Account</a></p>
</li>
<li><p><a href="#heading-add-a-profile-image">Add a Profile Image</a></p>
</li>
<li><p><a href="#heading-add-profile-details">Add Profile Details</a></p>
</li>
<li><p><a href="#heading-add-a-profile-readme-file">Add a Profile README File</a></p>
</li>
<li><p><a href="#heading-tell-a-story-about-each-repository">Tell a Story About Each Repository</a></p>
</li>
</ul>
<h2 id="heading-step-1-sign-up-for-a-github-account">Step 1: Sign Up for a Github Account</h2>
<p>To begin, you'll need a GitHub account. If you don’t have one, you can <a href="http://GitHub.com">set one up here</a>.</p>
<p>Once you have your account set up and you're logged in, we can move on to the next step.</p>
<h2 id="heading-step-2-add-a-profile-image">Step 2: Add a Profile Image</h2>
<p>Your profile image is often the first thing people notice. It could be a professional photo of yourself, or an image or avatar that represents you or your interests</p>
<p>As long as it’s appropriate, you’re good to go.</p>
<p>To add a profile image, you'll need to:</p>
<ul>
<li><p>Open your profile menu/dashboard</p>
</li>
<li><p>Click on the image icon at the left</p>
</li>
<li><p>Click on the edit text on the image icon</p>
</li>
<li><p>Select the image to set as your profile picture</p>
</li>
<li><p>Click the "Set new profile picture" button</p>
</li>
</ul>
<p>So, you should have something like this:</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/69721aa76d7c64defcdf1b2c/b05395a9-3f7a-44ce-89a8-2e7759f06ad7.png" alt="Image showing the new Profile image added" style="display:block;margin:0 auto" width="2963" height="1457" loading="lazy">

<p><strong>GitHub link to this page:</strong> <a href="https://github.com/settings/profile">https://github.com/settings/profile</a></p>
<p>And there you have it, your GitHub profile image is set.</p>
<p>On to the next one…</p>
<h2 id="heading-step-3-add-profile-details">Step 3: Add Profile Details</h2>
<p>This step is all about credibility and discoverability.</p>
<p>At the center of your profile settings you'll see fields like email, location, social media links and so on. We'll be adding those details so you can take advantage of the discoverability it lends to your profile.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/69721aa76d7c64defcdf1b2c/d3ca4a77-e3a6-4cd5-a139-3059b0dcc802.png" alt="Image showing public profile settings tab" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p><strong>GitHub link to this page:</strong> <a href="https://github.com/settings/profile">https://github.com/settings/profile</a></p>
<p>For this step, you'll want to add as much detail as possible (apart from your home address – I think we both know why).</p>
<p>For the location, you can just put in your city or country so others have a general idea of where you are in the world.</p>
<h2 id="heading-step-4-add-a-profile-readme-file">Step 4: Add a Profile README File</h2>
<p>This is where you introduce yourself properly and tell your story.</p>
<p>A <strong>Profile README</strong> is a special repository named exactly the same as your GitHub username. Your README file appears directly on your profile page.</p>
<p>The READme should answer the following questions:</p>
<ul>
<li><p>Who are you?</p>
</li>
<li><p>What are your project highlights?</p>
</li>
<li><p>What are you currently working on or learning?</p>
</li>
<li><p>Your hobbies or interests (optional)</p>
</li>
</ul>
<p>While answering these questions, you should aim to keep it minimal and yet interesting. You don't want to overwhelm the visitor.</p>
<p>Here's how to create your README:</p>
<ul>
<li><p>Click New repository</p>
</li>
<li><p>Name the repository exactly the same as your GitHub username</p>
</li>
<li><p>Check “Add a README file”</p>
</li>
<li><p>Make sure the repository is public</p>
</li>
<li><p>Click Create repository</p>
</li>
</ul>
<p>Profile README file setup:</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/69721aa76d7c64defcdf1b2c/c4ecd23d-6f0b-41d9-a16c-915cea2e9096.png" alt="Image showing profile README file being created" style="display:block;margin:0 auto" width="2566" height="1692" loading="lazy">

<p><strong>GitHub link to this page:</strong> <a href="https://github.com/new">https://github.com/new</a></p>
<p>So if you answered the questions listed above, your README file should look something like this:</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/69721aa76d7c64defcdf1b2c/a8685c0e-8f97-49b4-b7fc-4efa541acc3b.png" alt="Image showing Profile README section already created" style="display:block;margin:0 auto" width="1960" height="1228" loading="lazy">

<p><strong>GitHub link to this page:</strong> <a href="https://github.com/chinazachisom/chinazachisom">https://github.com/chinazachisom/chinazachisom</a></p>
<p>It should also be showing directly on your GitHub profile like below:</p>
<img src="https://cdn.hashnode.com/uploads/covers/69721aa76d7c64defcdf1b2c/7ed8961e-17aa-4b35-999a-b871f3c27905.png" alt="Github Profile Showing the Newly Added README file" style="display:block;margin:0 auto" width="2978" height="1708" loading="lazy">

<p><strong>GitHub link to this page:</strong> <a href="https://github.com/chinazachisom">https://github.com/chinazachisom</a></p>
<h2 id="heading-step-5-tell-a-story-about-each-repository">Step 5: Tell a Story About Each Repository</h2>
<p>Now, this is where you can tell a story about each of your repositories using a README file.</p>
<p><strong>NB: Each repository should have its own separate README file.</strong></p>
<p>What to include in a repository README:</p>
<ul>
<li><p>Project title</p>
</li>
<li><p>What the project is</p>
</li>
<li><p>The purpose (the “why”)</p>
</li>
<li><p>Key features</p>
</li>
<li><p>Challenges you faced and how you solved them</p>
</li>
<li><p>Setup or usage instructions (or a live link if hosted)</p>
</li>
<li><p>Technical concepts used (e.g., throttling, caching, lazy loading) <em>(optional)</em></p>
</li>
<li><p>Images or video demos</p>
</li>
</ul>
<p>You may also include badges, charts, contribution graphs or other visual enhancements that help highlight project quality, activity and impact.</p>
<p>With the above structure, you can tell the stories behind your projects, show your problem-solving skills, and make your work easier to understand and evaluate.</p>
<p><strong>Repository README File Sample:</strong></p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/69721aa76d7c64defcdf1b2c/63bc276b-798b-4a9e-a094-93330e3eeab0.png" alt="Image showing the README file for the new repository" style="display:block;margin:0 auto" width="2820" height="1711" loading="lazy">

<p><strong>GitHub link to this page:</strong> <a href="https://github.com/chinazachisom/Artsy">https://github.com/chinazachisom/Artsy</a></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Your Github Profile is more than just a storage space for your codebase. It's your developer Identity as well.</p>
<p>Following these basic steps can help turn your Github into a portfolio infused with your personal brand. It makes your GitHub Profile stand out, which can help open doors for more opportunities.</p>
<p>Treat it like a CV for your code and let your work speak for you.</p>
<h3 id="heading-about-the-author">About the Author</h3>
<p>Hi there! I'm Chinaza Chukwunweike, a Software Engineer passionate about building robust, scalable systems that make a real world impact. I'm also an advocate for continuous learning and improvement.</p>
<p>If you found this useful, please share it! And follow me for more Software Engineering tips, AI learning strategies, and productivity frameworks.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ OSS Pull Request Therapy: Learning to Enjoy Code Reviews with npmx ]]>
                </title>
                <description>
                    <![CDATA[ For years, I thought Open Source Software (OSS) just wasn’t for me. I had no plans to join any OSS communities on top of my existing developer community obligations. Curious about the hype I saw on Bl ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learning-to-enjoy-code-reviews-with-npmx/</link>
                <guid isPermaLink="false">69a6f99556428acc6fef7fbc</guid>
                
                    <category>
                        <![CDATA[ Programming Blogs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Open Source ]]>
                    </category>
                
                    <category>
                        <![CDATA[ open source ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abbey Perini ]]>
                </dc:creator>
                <pubDate>Tue, 03 Mar 2026 15:09:09 +0000</pubDate>
                <media:content url="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/5e1e335a7a1d3fcc59028c64/5765f28c-0d0e-46be-bc60-972a4d879b7e.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>For years, I thought Open Source Software (OSS) just wasn’t for me. I had no plans to join any OSS communities on top of my existing developer community obligations.</p>
<p>Curious about the hype I saw on <a href="https://bsky.app/">Bluesky</a>, I recently joined the <a href="https://npmx.dev/">npmx</a> Discord server on a whim. My journey from lurker to contributor taught me a lot about OSS and gave me new confidence going into code reviews.</p>
<p>In this article, I’ll walk you through my journey to give you a little insight into the process of getting involved in Open Source.</p>
<h3 id="heading-heres-what-ill-cover">Here’s what I’ll cover:</h3>
<ul>
<li><p><a href="#heading-my-struggles-with-pull-requests">My Struggles with Pull Requests</a></p>
</li>
<li><p><a href="#heading-my-former-view-of-oss">My Former View of OSS</a></p>
<ul>
<li><p><a href="#heading-the-basics-of-oss">The Basics of OSS</a></p>
</li>
<li><p><a href="#heading-the-dark-side-of-oss">The Dark Side of OSS</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-getting-started-with-npmx">Getting Started with npmx</a></p>
</li>
<li><p><a href="#heading-the-not-so-perfect-pr">The Not So Perfect PR</a></p>
</li>
<li><p><a href="#heading-collaboration-over-perfection">Collaboration Over Perfection</a></p>
</li>
<li><p><a href="#heading-my-current-view-of-oss">My Current View of OSS</a></p>
</li>
<li><p><a href="#heading-tips-for-pr-authors-and-reviewers">Tips for PR Authors and Reviewers</a></p>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-my-struggles-with-pull-requests">My Struggles with Pull Requests</h2>
<p>I’ll admit, I’ve always had a hard time with code reviews. I can be quite the perfectionist. I’ll entertain every nitpick and only hear the criticism.</p>
<p>If reviews go on for days, I easily get overwhelmed. I enjoy pairing and co-working. I want to enjoy Pull Request (PRs), but addressing PR comments takes a lot out of me.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771264593124/b5674020-6b0d-4ad2-bb92-921d05ebecc7.png" alt="Me looking at the bugs that my colleagues pointed out in my pull request Patrick Star from Spongebob looking absolutely horrified and staring at a computer" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Some of my struggle is a need for <a href="https://askjan.org/disabilities/Attention-Deficit-Hyperactivity-Disorder-AD-HD.cfm#spy-scroll-heading-2">accommodations</a> that I rarely get. I also have plenty of lived experience with how hostile code reviews can become (even in a professional setting). Finally, there’s how I was introduced to PR reviews.</p>
<p>Outside of work, I had only ever experienced perfunctory PRs – I’d receive at most one suggestion, but usually just got a “LGTM” (Looks Good to Me) comment. Professionally, I went from no code reviews to incredibly detailed code reviews basically overnight. I still feel like I’m playing catch up.</p>
<p>On the one hand, thinking deeply about every suggestion has made me a better developer. I thrive in collaborative environments with thoughtful code reviews. Developers who have worked with me have told me that they benefit from answering all my “why?” questions.</p>
<p>On the other hand, I demand compliments, gifs, and video calls from my reviewers. I don’t do well with a bombardment of vague comments on my PRs. I’ve spent a lot of time documenting code guidelines and review processes that other people seem to understand and remember much more easily than I do.</p>
<p>Developer communities have helped me navigate all of this. Community is a priceless resource for career changers and new grads. When everyone shares their experience, the uninitiated learn about how things could be and what kinds of things aren’t normal (like very hostile code reviews).</p>
<h2 id="heading-my-former-view-of-oss">My Former View of OSS</h2>
<p>When I’ve talked and written about developer community, I’ve recommended online networking communities, going to meetups, tech conferences, social media, writing, and posting your writing online. The one thing I haven’t written about? OSS.</p>
<p>My first real introduction to OSS was through the online networking group <a href="https://virtualcoffee.io/">Virtual Coffee</a>. By the end of my first <a href="https://hacktoberfest.com/">Hacktoberfest</a>, I knew the basics.</p>
<h3 id="heading-the-basics-of-oss">The Basics of OSS</h3>
<ul>
<li><p>Find a project that interests you.</p>
</li>
<li><p>Check the Contributing Guide.</p>
</li>
<li><p>Claim an issue.</p>
</li>
<li><p>Following the Contributing Guide, make a fork, write the code, and open a PR.</p>
</li>
<li><p>The maintainer merges it.</p>
</li>
<li><p>You did it! That’s OSS.</p>
</li>
</ul>
<h3 id="heading-the-dark-side-of-oss">The Dark Side of OSS</h3>
<p>Over time, I couldn’t help but see the “dark side” of OSS – maintainers <a href="https://github.com/zloirock/core-js/blob/master/docs/2023-02-14-so-whats-next.md">burning out</a>, <a href="https://github.com/tailwindlabs/tailwindcss.com/pull/2388#issuecomment-3717222957">friction between users and maintainers</a>, corporations suddenly trying to assert control over OSS (for example, <a href="https://www.cmswire.com/digital-experience/whats-with-the-open-source-drama-between-wordpress-and-wp-engine/">Wordpress</a>, <a href="https://dev.to/cseeman/what-just-happened-to-rubygems-31n9">Ruby</a>), and the thankless, frustrating job of maintaining a package that everyone uses but no one wants to pay for.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771191134959/871a6a8d-85ea-402a-950e-ec25d4738859.png" alt="A large structure made out of building blocks labelled All Modern Digital Infrastructure. One tiny, integral block is labelled A project some random person in Nebraska has been thanklessly maintaining since 2003" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>I have to be honest: I had begun to think of open source maintainers as <a href="https://www.youtube.com/watch?v=mm8R3u_b0yU">Roz from Monsters Inc.</a> – justifiably fed up with the extra work dumped on them by unappreciative people.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1770053555027/4f38e415-3100-4737-af1c-947725c60b23.png" alt="A slug person wearing a cardigan, holding a pencil and clipboard with the Monsters Inc. logo. She's wearing glasses and lipstick. Her grey hair is styled straight up, she has a mole on her bottom lip. She currently looks disgusted." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Meeting maintainers in-person didn’t contradict my view. Every single one had a story about <a href="https://medium.com/@sohail_saifii/the-open-source-maintainer-burnout-crisis-nobodys-fixing-5cf4b459a72b">burnout and lack of funding</a>. I started to assume that anyone excited about OSS just hadn’t been in it long enough</p>
<p>…so my friends were quite surprised when I suddenly announced that I had joined the OSS project <a href="https://npmx.dev/">npmx</a>.</p>
<h2 id="heading-getting-started-with-npmx">Getting Started with npmx</h2>
<p>It wasn’t the first mention of the npmx project that interested me. It wasn’t the second. It was a <a href="https://bsky.app/profile/erus.dev/post/3mdicpnmijk2o">meme</a>. I’ve known <a href="https://roe.dev/">Daniel Roe</a> long enough to know that he is brilliant. I like learning from people who are smarter than I am.</p>
<p>I reached out to <a href="https://bsky.app/profile/patak.dev">Patak</a>, and got an invite to the <a href="https://chat.npmx.dev/">npmx Discord server</a>. I was amazed by what I saw: a rapidly growing, excited, and inclusive community. I realized that I had only ever contributed to communities with at most a handful of people. My view of OSS immediately changed.</p>
<p>This was it. I was finally going to have fun doing PRs.</p>
<p>So I hopped into the <a href="https://github.com/npmx-dev/npmx.dev">npmx GitHub repository</a> and tried to get my bearings. Very quickly, I was overwhelmed. The project moves <em>so fast.</em> I tried to do step 3 – claim a ticket. As far as I could tell, all the tickets were being claimed in Discord before or as they were being written.</p>
<p><a href="https://bsky.app/profile/jonathanyeong.com">Jono</a> kindly welcomed me into his fork for working on the blog page, but I ran into frustrating and weird issues with running the repository (repo) locally and the pre-commit hooks. Multiple people tried to help me debug and were just as stumped as I was.</p>
<p>The next day, <a href="https://bsky.app/profile/whitep4nth3r.com">Salma</a> arrived. The day after, she was in charge of outreach, and asked me to write a blog. Then life got in the way. I couldn’t keep my promise to <a href="https://www.software.com/devops-guides/context-switching">context switch</a> into a feature branch in a new repo. I felt like my only contribution was going to be a single line change on the blog page and a blog.</p>
<p>It didn’t help that I wasn’t happy with the blog I had started writing. I gave up on keeping up and lurked in the Discord channels. I chimed in on a few conversations, and offered to help with things like failing accessibility tests.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771190012891/ac34a318-46f7-45d8-90c3-10837627ad17.png" alt="check @AbbeyPerini's reaction here, if we manage to set an example on how good an app can be with good #a11y, great #perf, and a good #test story, listening to the #e18e folks on keeping deps clean, the npmx repo will be a great learning resource for folks learning how to build websites Salma If anything I made it MORE accessible with a this react Abbey Perini let me run it locally and see if I can spot something with 3 purple heart reacts God it's nice to look at a repo where a11y wasn't an afterthought 6 100 reacts" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Four days later, the project was officially two weeks old. The maintainers announced a mandatory week of vacation – community members experienced with burnout had seen the writing on the wall. Vacation would start in 10 days, so that’s basically how long I had to get a contribution in before the alpha release.</p>
<h2 id="heading-the-not-so-perfect-pr">The Not So Perfect PR</h2>
<p>An hour later, I finally saw it – my chance to contribute code. <a href="https://bsky.app/profile/alexdln.com">Alex</a> needed <a href="https://github.com/npmx-dev/npmx.dev/issues/1028">a toggle re-written as a checkbox</a>. It was my time to shine. I commented on the ticket to claim it as soon as it was written. I slapped up a draft PR to show I was working on it. Predictably, my focus was once again pulled away from the repo.</p>
<p>A couple days later, <a href="https://bsky.app/profile/knowler.dev">Knowler</a> reviewed my draft PR, and all my PR anxieties came tumbling back. This was going to be The Perfect PR. How dare anyone look at it before I was ready to defend my work. What would they think about my abilities looking at my old copy and pasted portfolio site code that I hadn’t even finished translating from <a href="https://react.dev/">React</a> to <a href="https://vuejs.org/">Vue</a>? I was legitimately embarrassed someone was looking at my code in that state.</p>
<p>Fueled by embarrassment and productive procrastination, I sprung into action. In what little free time I had, I must have toggled my toggle a thousand times. Three days later, it was finally in a state I was happy with. It was time to open up my PR for review.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771263500393/64bc78f5-dd9c-48b7-805b-fcba0456753a.png" alt=" Mona-Lisa Saperstein, played by Jenny Slate, hand outstretched, saying &quot;money please,&quot; but the meme is captioned &quot;review please&quot;" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>A couple dozen comments came in. Overwhelmed, I tried to remember that I had asked for this. I resolved most of the comments and left a comment saying I’d get to the last item, <a href="https://polypane.app/blog/forced-colors-explained-a-practical-guide/">forced colors mode</a>, in the morning. Frustrated with the code for the forced colors and myself for forgetting a few tiny things, I went to play games with friends.</p>
<p>A few hours later, I got a DM from Daniel. He had some code for my PR. I agreed with his reasoning for all the changes and found out an entire tooltip had been added while I was blissfully ignoring the rest of the repo. (I’m confident in my ability to merge or rebase my way out of any situation.)</p>
<p>Splitting my attention between <a href="https://store.steampowered.com/app/1203620/Enshrouded/">Enshrouded</a> and talking to Daniel, I felt defeated. I knew I finish the forced colors fix the next day, but also adding a tooltip felt daunting. Still, it felt like I needed to do it all.</p>
<h2 id="heading-collaboration-over-perfection">Collaboration Over Perfection</h2>
<p>And then I remembered, this wasn’t work and it wasn’t going to come up on a performance review. I wasn’t alone – Knowler and Daniel were taking the time to help me get this PR merged because they wanted to. I had the opportunity to collaborate with some brilliant people and see how they would write the same thing.</p>
<p>So I pushed through my perfectionism, demanded compliments, and asked Daniel to push his changes. I told him I’d review them in the morning.</p>
<p>Reviewing Daniel’s code, I found that he had forgotten a couple tiny things, just like I had. The code I was frustrated with the night before was legitimately frustrating. <a href="https://cssence.com/2024/forced-colors-mode-strategies/">Emulating forced colors on a Mac</a> was giving me weird and contradictory results. I needed to test on a Windows machine to finally get it right.</p>
<p>Then, six days after I opened the PR, I finally merged it. I was on top of the world. I had gotten my contribution in before our vacation (and more importantly, I had received multiple compliments). Finally, I knew what to write this blog about.</p>
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1771191470445/caeb7ab5-d54b-4dd9-907c-a95a85e650b1.png" alt="Abbey Perini Bluesky Elder I'd like to thank @knowler.dev and @danielroe.dev and my confidence in my git skills because this is the fastest moving repo I've ever been in. Quoted post - npmx @npmx.dev @abbeyperini.dev at chat.npmx.dev#contributing. A screenshot of the npmx Discord server. The npmx APP posted @Abbey Perini (abbeyperini) is now a contributor! Abbey Perini NERD responds with a gif of Jim Carrey as the Mask giving an acceptance speech and saying Thank You! with 6 raised hands reacts, 2 trophy reacts, and 2 clapping hands reacts 4:10 PM Feb 11, 2026" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<h2 id="heading-my-current-view-of-oss">My Current View of OSS</h2>
<p>When you’re looking for a project that interests you, the code isn’t the only thing to evaluate. Early in my career, I learned three rules for evaluating software tools.</p>
<ol>
<li><p>Check the date of the last update to make sure it’s actively maintained.</p>
</li>
<li><p>Look at the documentation. Is it up to date and easy to follow?</p>
</li>
<li><p>Check out the community. Do people get fairly quick responses to their questions?</p>
</li>
</ol>
<p>After joining npmx, I’ve discovered that, with a few tweaks, these rules also apply to evaluating an OSS project.</p>
<ol>
<li><p>Check out the last few tickets and PRs to see how fast the repo moves. If it’s fairly slow, you can probably claim an issue in GitHub easily. If it’s rapid, start by getting to know the community and how they’re assigning tickets.</p>
</li>
<li><p>You should always check the repo for a code of conduct, contributing guide, and sufficient documentation. Also evaluate the tickets. Are contributors expected to research solutions on their own or given strict requirements? How do maintainers respond to comments on issues?</p>
</li>
<li><p>Check out the community. An active, inclusive community makes contributing a lot more fun.</p>
</li>
</ol>
<p>Now, my view of OSS is much more nuanced. Yes, there are issues with OSS as whole, but there’s a reason people want to fix them. OSS can be collaborative, inspirational, and enjoyable.</p>
<h2 id="heading-tips-for-pr-authors-and-reviewers">Tips for PR Authors and Reviewers</h2>
<p>People underestimate the importance of the relationship between PR author and reviewer. A collaborative OSS code review process doesn’t happen in a vacuum. It takes careful cultivation by the PR author, PR reviewer, and project community.</p>
<p>For a long time, I focused on the responsibility of the reviewer to make the PR author comfortable (for example, compliments, gifs). Don’t get me wrong – I think one of the most important parts of a senior developer’s job is to provide constructive, actionable feedback.</p>
<p>But I now understand that the PR author’s sense of agency and desire to learn are just as important.</p>
<p>A sense of agency is a sense of control over actions and consequences. In other words, the PR author needs to feel that they have control over what goes into their PR. Before npmx, I understood this a little bit. I always ask “why?” because I’m not putting my name on code that I don’t understand and agree with. I have counseled my own junior developer that it’s his job to get PRs he’s authored reviewed and merged.</p>
<p>After experiencing an in-depth code review outside of work, I finally understand that a PR is a process. Reviews exist to get consensus, so “perfect” is far more subjective than I originally thought. There’s a reason you get a conversation, not a grade.</p>
<p>Maybe I’ll even ignore some nitpicks in the future.</p>
<p>A desire to learn makes remaining open to a reviewer’s suggestions and requests a lot easier. During my first npmx PR, it was only when my desire to learn outweighed my desire to prove something that I started having fun.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Today, March 3rd, 2026, is <a href="https://npmx.dev/blog/alpha-release">the alpha release of npmx</a>, and I am very proud to be a contributor and member of the community.</p>
<p>I look forward to learning about OSS from Patak, fancy, smart code from Daniel, outreach from Salma, and accessibility from Knowler. I know I’ll learn many things outside of that list, too. I’m grateful I’m not the smartest person in the room and that I finally get to have fun with Pull Requests.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Save Multiple Drafts in Git: A Guide to Using Stash ]]>
                </title>
                <description>
                    <![CDATA[ Writing code can be similar to writing tutorials. In both cases, you’ll typically need to create and work on multiple drafts before reaching the final version. In an ideal setting, you would write cod ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-save-multiple-drafts-in-git-a-guide-to-using-stash/</link>
                <guid isPermaLink="false">6989f72cfec80c4e91c007a4</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ version control ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chidiadi Anyanwu ]]>
                </dc:creator>
                <pubDate>Mon, 09 Feb 2026 15:03:08 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1770649372924/7c949e9d-627a-4b06-99fe-40ce0e7c8507.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Writing code can be similar to writing tutorials. In both cases, you’ll typically need to create and work on multiple drafts before reaching the final version.</p>
<p>In an ideal setting, you would write code for a feature, add that code to the staging area, and then commit it before going to the next part. This helps keep your commit history clean. (Don't worry if you don't have a clean history. Many of us don’t.)</p>
<p>But now, imagine a scenario where you have multiple features to build. You've committed the first. You've started the third, but then you found out you needed to build the second one first, because the third depends on it. It might seem like you have to go back in time and build out that second feature without mixing in the code changes for the third, and without deleting the code changes for the third.</p>
<p>So how do you do that?</p>
<p>In this article, you’re going to learn about Git stash, what it is, and the basic commands you need to be able to use it.</p>
<h2 id="heading-what-well-cover">What We’ll Cover:</h2>
<ul>
<li><p><a href="#heading-what-is-git-stash">What is Git Stash?</a></p>
</li>
<li><p><a href="#heading-how-to-use-git-stash">How to Use Git Stash</a></p>
<ul>
<li><p><a href="#heading-pushing-commands-to-the-stash">Pushing Commands To The Stash</a></p>
</li>
<li><p><a href="#heading-applying-changes-from-the-stash-to-the-working-directory">Applying Changes From The Stash To The Working Directory</a></p>
</li>
<li><p><a href="#heading-listing-the-items-in-the-stash-list">Listing The Items In The Stash List</a></p>
</li>
<li><p><a href="#heading-removing-items-from-the-stash">Removing Items From The Stash</a></p>
</li>
<li><p><a href="#heading-creating-a-new-branch-from-stash">Creating A New Branch From Stash</a></p>
</li>
<li><p><a href="#heading-showing-the-changes-in-the-stash">Showing The Changes In The Stash</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<p>To understand and get the most out of this tutorial, you’ll need to have a basic understanding of Git.</p>
<h2 id="heading-what-is-git-stash">What is Git Stash?</h2>
<p>Git stash provides storage (in the form of a stack) where you can store changes to your code. It lets you keep these changes separate from the current working directory until you're ready to apply them.</p>
<p><code>git stash</code> is a relatively simple command, and has a few variations like:</p>
<ul>
<li><p><code>git stash push</code></p>
</li>
<li><p><code>git stash pop</code></p>
</li>
<li><p><code>git stash apply</code></p>
</li>
<li><p><code>git stash drop</code></p>
</li>
<li><p><code>git stash clear</code></p>
</li>
<li><p><code>git stash show</code></p>
</li>
<li><p><code>git stash list</code></p>
</li>
</ul>
<h2 id="heading-how-to-use-git-stash">How to Use Git Stash</h2>
<h3 id="heading-pushing-code-changes-to-the-stash">Pushing Code Changes to the Stash</h3>
<p>To push uncommitted changes from the working directory to the stash, you can use <code>git stash push.</code> When you do that, the changes disappear from the working directory and are saved in the stash. The working directory is then set back to the last commit (which, in the example below, is the Feature one).</p>
<pre><code class="language-bash">git stash push
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/5fc16e412cae9c5b190b6cdd/7652801b-cb1e-45cc-ac94-281512252f37.png" alt="7652801b-cb1e-45cc-ac94-281512252f37" style="display:block;margin:0 auto" width="1019" height="382" loading="lazy">

<p>You can also write the <code>git stash push</code> command as just <code>git stash</code> – it means the same thing and performs the same way. You can also add a message to it with the <code>-m</code> or <code>--message</code> flag:</p>
<pre><code class="language-bash">git stash push -m "Feature two I was working on"
</code></pre>
<p>You can use the <code>-u</code> flag or <code>--include-untracked</code> to include untracked changes in the stash. This way, the changes not yet tracked by Git can be included in the stash.</p>
<pre><code class="language-bash">git stash push -u
git stash push --include-untracked
</code></pre>
<p>On the other hand, you can decide to push only staged changes to the stash with the <code>-s</code> or <code>--staged</code> flag:</p>
<pre><code class="language-bash">git stash push -s
</code></pre>
<p>You can also suppress feedback messages with the <code>-q</code> or <code>--quiet</code> flag:</p>
<pre><code class="language-bash">git stash push -q
</code></pre>
<p>When you're done with your edits on the current working directory, you can commit and push without the older changes bleeding into it. They're safely stowed away in the stash.</p>
<p>Anytime you use the git stash command, you add a stash to the stash list. The stashes are identified by their index numbers.</p>
<h3 id="heading-applying-changes-from-the-stash-to-the-working-directory">Applying Changes from the Stash to the Working Directory</h3>
<p>Let’s say you had a quick fix to do. You’re done committing that, and you want to continue with what you were working on. You can restore the changes from the stash to continue working on them.</p>
<p>You can do this by using the <code>git stash apply</code> command or the <code>git stash pop</code> command:</p>
<pre><code class="language-bash">git stash apply
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/5fc16e412cae9c5b190b6cdd/89d30b86-ba75-412f-8aba-b8bf1ac32933.png" alt="89d30b86-ba75-412f-8aba-b8bf1ac32933" style="display:block;margin:0 auto" width="1005" height="475" loading="lazy">

<p><code>git stash apply</code> applies the latest changes from the stash to the working directory, but doesn’t delete the code from the stash. You can select a particular entry to apply by index number:</p>
<pre><code class="language-bash">git stash apply --index stash@{1}
# You'd need to use quotes "stash@{1}" if you're writing this in PowerShell
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/5fc16e412cae9c5b190b6cdd/4a26b84c-9bf0-4bd2-9687-7ebb94046f5d.png" alt="4a26b84c-9bf0-4bd2-9687-7ebb94046f5d" style="display:block;margin:0 auto" width="1001" height="212" loading="lazy">

<p><code>git stash pop</code>, on the other hand, applies the latest changes from the stash, then deletes them from the stash. Basically, popping from a stack. You can select a particular stash entry to pop by index number.</p>
<pre><code class="language-bash">git stash pop
</code></pre>
<pre><code class="language-bash">git stash pop --index stash@{1}
# You'd need to use quotes "stash@{1}" if you're writing this in PowerShell
</code></pre>
<h3 id="heading-listing-the-items-in-the-stash-list">Listing the Items in the Stash List</h3>
<p>You can use <code>git stash list</code> to list out the stashes in the stash list. It’s arranged by index number (like {0}, {1}, and so on). Any time you do a git stash push, it adds a stash to the stash list.</p>
<pre><code class="language-bash">git stash list
stash@{0}: WIP on master: b2a2709 Feature one
stash@{1}: WIP on master: b2a2709 Feature one
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/5fc16e412cae9c5b190b6cdd/46c7b4a8-6701-4227-8d48-9da354c9d1b7.png" alt="46c7b4a8-6701-4227-8d48-9da354c9d1b7" style="display:block;margin:0 auto" width="1014" height="156" loading="lazy">

<h3 id="heading-removing-items-from-the-stash">Removing Items from the Stash</h3>
<p>You can use <code>git stash clear</code> to clear the stash list. But if you just want to drop a particular entry from the stash list, you can use <code>git stash drop</code> and specify the entry you want to drop by the index number. This doesn’t apply its changes to the working directory.</p>
<pre><code class="language-bash">git stash clear
</code></pre>
<pre><code class="language-bash">git stash drop stash@{0}
# You'd need to use quotes "stash@{0}" if you're writing this in PowerShell
</code></pre>
<h3 id="heading-creating-a-new-branch-from-stash">Creating a New Branch from Stash</h3>
<p>You can also create a new branch from a stash using <code>git stash branch</code>. The syntax is <code>git stash branch &lt;branchname&gt; [&lt;stash&gt;].</code></p>
<pre><code class="language-bash">git stash branch premium-branch stash@{0}
# You'd need to use quotes "stash@{0}" if you're writing this in PowerShell
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/5fc16e412cae9c5b190b6cdd/a14db1c1-b0ac-4a81-ae4d-4b4859989489.png" alt="a14db1c1-b0ac-4a81-ae4d-4b4859989489" style="display:block;margin:0 auto" width="1018" height="232" loading="lazy">

<p>If you don’t add the stash index, it will just use the last stash.</p>
<pre><code class="language-bash">git stash branch premium-branch
</code></pre>
<h3 id="heading-showing-the-changes-in-the-stash">Showing the Changes in the Stash</h3>
<p>You can use <code>git stash show</code> to show the changes you’ve made in your stashed changes.</p>
<pre><code class="language-bash">C:\file-path\git_stash_example&gt; git stash show
 text.md | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/5fc16e412cae9c5b190b6cdd/9d5a5e83-7c2f-4a2d-a004-f406b5ed1af7.png" alt="9d5a5e83-7c2f-4a2d-a004-f406b5ed1af7" style="display:block;margin:0 auto" width="1008" height="196" loading="lazy">

<h2 id="heading-conclusion">Conclusion</h2>
<p>Git stash is one of those quiet tools that becomes indispensable once your workflow starts to get messy. It allows you to shelve unfinished ideas, switch context without panic, and keep your commits clean. With it, you can safely carry out urgent fixes, and juggle dependent features without muddling up your commit history.</p>
<p>If you enjoyed this article, share it with others. You can also reach me on <a href="https://linkedin.com/in/chidiadi-anyanwu">LinkedIn</a> or <a href="https://linkedin.com/in/chidiadi-anyanwu">X.</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <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 & GitHub Crash Course for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ Git is important for any developer. We just posted a course that will help you learn Git and GitHub from scratch with clear examples, real workflows, branching, merging, stashing, rebase, pull requests, and more. This course is great for beginners wh... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/git-and-github-crash-course-for-beginners/</link>
                <guid isPermaLink="false">6931ef1a5feb2860f3beafd6</guid>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Thu, 04 Dec 2025 20:29:14 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1764880033392/03198f4c-c7c0-4ba1-a383-24c546a418cf.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Git is important for any developer.</p>
<p>We just posted a course that will help you learn Git and GitHub from scratch with clear examples, real workflows, branching, merging, stashing, rebase, pull requests, and more. This course is great for beginners who want strong foundations. Sumit Saha developed this course.</p>
<p>Here are the things you will learn in this video:</p>
<ul>
<li><p>The difference between Git and GitHub in the simplest way</p>
</li>
<li><p>How Git tracks your work using the working directory, staging area, and repository</p>
</li>
<li><p>Core Git commands: add, commit, status, log, reset, restore, rm</p>
</li>
<li><p>How to work with branches, merge updates, and fix merge conflicts</p>
</li>
<li><p>How to push, pull, and sync your code with GitHub</p>
</li>
<li><p>Using stash, revert, and rebase to handle real-world workflows</p>
</li>
<li><p>How pull requests work and why teams use them</p>
</li>
</ul>
<p>Watch the full course on the freeCodeCamp.org YouTube channel (1-hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/mAFoROnOfHs" 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>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is the GitHub CLI? How to Use GitHub from the Command Line ]]>
                </title>
                <description>
                    <![CDATA[ The GitHub CLI (Command Line Interface) is a powerful tool developed by GitHub that allows developers to interact with GitHub directly from the terminal. It provides a simple way to perform many GitHub tasks without leaving the command line interface... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-github-from-the-command-line/</link>
                <guid isPermaLink="false">68d6c4873324dabb31fd7214</guid>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ terminal ]]>
                    </category>
                
                    <category>
                        <![CDATA[ command line ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ AYUSH MISHRA ]]>
                </dc:creator>
                <pubDate>Fri, 26 Sep 2025 16:51:19 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1758905411969/b1506cff-650a-4098-bd70-e8bb3b0bcb9a.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The GitHub CLI (Command Line Interface) is a powerful tool developed by GitHub that allows developers to interact with GitHub directly from the terminal. It provides a simple way to perform many GitHub tasks without leaving the command line interface, such as managing repositories, handling pull requests and issues, working with GitHub Actions, and more.</p>
<p>In this tutorial, you’ll to learn what the GitHub CLI is, how to install and set it up, and how to use it for everyday tasks such as creating repositories, managing issues and pull requests, working with GitHub Actions, and automating tasks using custom aliases. You’ll learn how to replace some functionalities on GitHub’s web interface with quick commands in your terminal.</p>
<h2 id="heading-heres-what-well-cover"><strong>Here’s what we’ll cover:</strong></h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-overview-of-github-cli">Overview of GitHub CLI</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-key-features-of-github-cli">Key Features</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-benefits-of-using-github-cli">Benefits of Using GitHub CLI</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-installation-and-setup">Installation and Setup</a></p>
</li>
<li><p><a class="post-section-overview" href="#authenticating-with-a-github-account">Authenticating with a GitHub Account</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-navigating-the-github-cli">Navigating the GitHub CLI</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-manage-repositories-with-the-github-cli">Managing Repositories</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-managing-branches-and-pull-requests">Working with Pull Requests and Issues</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-pushing-and-pulling-changes">Pushing and Pulling Changes</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-working-with-github-actions">Working with GitHub Actions</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-manage-gists-with-the-github-cli">Managing Gists</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-interacting-with-releases-and-tags">Releases and Tags</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-extend-the-github-cli-with-custom-scripts-and-aliases">Custom Scripts and Aliases</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-troubleshooting-common-issues">Troubleshooting</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-overview-of-github-cli">Overview of GitHub CLI</h2>
<p>You can use the GitHub CLI to bridge the gap between GitHub's web interface and your local environment. You can perform various tasks such as creating issues, managing repositories, or even checking the status of your GitHub Actions workflows using the CLI. Using the CLI, you can perform almost all the tasks that you might complete on the GitHub website.</p>
<h3 id="heading-key-features-of-github-cli">Key Features of GitHub CLI</h3>
<ul>
<li><p><strong>Repository management:</strong> Easily create, clone, view, and manage repositories.</p>
</li>
<li><p><strong>Pull requests and issues:</strong> Manage pull requests and issues directly from the terminal, including creating, merging, and listing them.</p>
</li>
<li><p><strong>GitHub Actions:</strong> Interact with workflows and manage workflow runs.</p>
</li>
<li><p><strong>Authentication:</strong> Provides a secure way to authenticate with your GitHub account, supporting SSH keys, tokens, and OAuth.</p>
</li>
<li><p><strong>Custom scripting:</strong> Lets you create custom scripts and aliases to automate repetitive tasks and streamline development processes.</p>
</li>
</ul>
<h3 id="heading-benefits-of-using-github-cli">Benefits of Using GitHub CLI</h3>
<p>Suppose you’re working on a project, and you need to create a new issue on GitHub. Normally, you would switch to your browser, log in to GitHub, navigate to the repository, click on the “Issues” tab, and then click “New Issue.” With GitHub CLI, you can do all of this by typing a single command, without ever leaving your terminal. This makes your workflow faster and saves time.</p>
<h2 id="heading-installation-and-setup">Installation and Setup</h2>
<p>To install GitHub CLI on Windows, you can use the winget package manager. Winget is a command-line tool that allows you to install software easily.</p>
<h3 id="heading-installing-github-cli-on-windows-macos-and-linux"><strong>Installing GitHub CLI on Windows, macOS, and Linux</strong></h3>
<h3 id="heading-windows"><strong>Windows:</strong></h3>
<p>Run the command given below:</p>
<pre><code class="lang-plaintext">winget install --id GitHub.cli
</code></pre>
<ul>
<li><p><code>winget install</code><strong>:</strong> Tells Windows to install a new software package.</p>
</li>
<li><p><code>--id GitHub.cli</code><strong>:</strong> Specifies the exact package ID for GitHub CLI.</p>
</li>
</ul>
<p>After running this command, GitHub CLI will be installed on your Windows system.</p>
<h3 id="heading-macos">macOS:</h3>
<p>You can use Homebrew to install GitHub CLI on macOS. Open your terminal and run:</p>
<pre><code class="lang-plaintext">brew install gh
</code></pre>
<h3 id="heading-linux">Linux:</h3>
<p>On Linux, you can use your package manager. For example, on Ubuntu, you can run:</p>
<pre><code class="lang-plaintext">sudo apt install gh
</code></pre>
<h3 id="heading-authenticating-with-a-github-account">Authenticating with a GitHub Account</h3>
<p>After installing GitHub CLI, the next step is to authenticate it with your GitHub account.</p>
<h4 id="heading-run-authentication-command">Run Authentication Command:</h4>
<p>Type <code>gh auth login</code> in the terminal and press Enter.</p>
<pre><code class="lang-plaintext">gh auth login
</code></pre>
<p>You’ll then be prompted to select an authentication method. The recommended option is to authenticate via a web browser.</p>
<p>If you select the browser method, GitHub CLI will open a link in your default browser, where you can log in to GitHub.</p>
<h4 id="heading-complete-authentication">Complete Authentication:</h4>
<p>After logging in, the browser will confirm that the GitHub CLI is connected to your account.</p>
<p>You can verify the authentication status by running:</p>
<pre><code class="lang-plaintext">gh auth status
</code></pre>
<h2 id="heading-navigating-the-github-cli">Navigating the GitHub CLI</h2>
<p>The GitHub CLI is easy to navigate, and its command structure is intuitive.</p>
<h3 id="heading-command-structure-and-syntax">Command Structure and Syntax</h3>
<p>GitHub CLI commands follow a simple and straightforward pattern:</p>
<pre><code class="lang-plaintext">gh [command] [subcommand] [flags]
</code></pre>
<ul>
<li><p><strong>Command:</strong> The main action you want to perform (for example, repo, issue, pr).</p>
</li>
<li><p><strong>Subcommand:</strong> A specific task within the command (for example, create, list, view).</p>
</li>
<li><p><strong>Flags:</strong> Optional parameters that modify the command's behavior (for example, --title, --body).</p>
</li>
</ul>
<h3 id="heading-commonly-used-commands-and-flags">Commonly Used Commands and Flags</h3>
<p>Here are some common GitHub CLI commands:</p>
<ul>
<li><p><strong>Creating a repository:</strong> <code>gh repo create</code></p>
</li>
<li><p><strong>Listing issues:</strong> <code>gh issue list</code></p>
</li>
<li><p><strong>Creating a pull request:</strong> <code>gh pr create</code></p>
</li>
<li><p><strong>Viewing a repository's details:</strong> <code>gh repo view</code></p>
</li>
</ul>
<p>To see all available commands and options, you can always run:</p>
<pre><code class="lang-plaintext">gh help
</code></pre>
<h2 id="heading-how-to-manage-repositories-with-the-github-cli">How to Manage Repositories with the GitHub CLI</h2>
<p>Let’s go through examples of some of the commands you’ll use the most often.</p>
<h3 id="heading-creating-and-cloning-repositories">Creating and Cloning Repositories</h3>
<p>To create a new GitHub repository directly from the terminal, just use the following command:</p>
<pre><code class="lang-plaintext">gh repo create my-repo-name
</code></pre>
<p>To clone an existing repository, use the following command:</p>
<pre><code class="lang-plaintext">gh repo clone owner/repo-name
</code></pre>
<h3 id="heading-managing-branches-and-pull-requests">Managing Branches and Pull Requests</h3>
<p>GitHub CLI allows you to handle issues and pull requests (PRs) without leaving the terminal.</p>
<p>Switching branches or creating pull requests is simple. To create a new branch:</p>
<pre><code class="lang-plaintext">git checkout -b new-branch-name
</code></pre>
<p>Then, to create a pull request:</p>
<pre><code class="lang-plaintext">gh pr create --title "Your PR Title" --body "Description of your PR"
</code></pre>
<h3 id="heading-pushing-and-pulling-changes">Pushing and Pulling Changes</h3>
<p>Push your changes to GitHub with this command:</p>
<pre><code class="lang-plaintext">git push origin branch-name
</code></pre>
<p>And pull the latest changes with:</p>
<pre><code class="lang-plaintext">git pull
</code></pre>
<h3 id="heading-working-with-github-actions">Working with GitHub Actions</h3>
<p>GitHub CLI also supports GitHub Actions, allowing you to manage workflows directly from your terminal.</p>
<p>You can manually trigger workflows using the following:</p>
<pre><code class="lang-plaintext">gh workflow run workflow-name
</code></pre>
<p>And you can monitor the status of workflows with:</p>
<pre><code class="lang-plaintext">gh run list
</code></pre>
<p>To see detailed logs of a workflow, run this:</p>
<pre><code class="lang-plaintext">gh run view run-id --log
</code></pre>
<h3 id="heading-cloning-and-forking-repositories">Cloning and Forking Repositories</h3>
<p>Cloning and forking are essential tasks when working on projects from other repositories.</p>
<p>To clone a repository, use this command:</p>
<pre><code class="lang-plaintext">gh repo clone &lt;repository-name&gt;
</code></pre>
<p>To fork a repository, do this:</p>
<pre><code class="lang-plaintext">gh repo fork &lt;repository-url&gt;
</code></pre>
<h4 id="heading-example"><strong>Example:</strong></h4>
<p>Here’s what it would look like:</p>
<pre><code class="lang-plaintext">gh repo clone example-repo
</code></pre>
<pre><code class="lang-plaintext">gh repo fork https://github.com/username/repository-name
</code></pre>
<h3 id="heading-how-to-work-with-github-actions">How to Work with GitHub Actions</h3>
<p>Using the GitHub CLI, you can also manage GitHub Actions, which are automated tasks you can run in response to certain events in your repository.</p>
<h4 id="heading-triggering-and-monitoring-workflows">Triggering and Monitoring Workflows</h4>
<p>You can trigger a workflow manually like this:</p>
<pre><code class="lang-plaintext">gh workflow run &lt;workflow-name&gt;
</code></pre>
<p>And you can monitor workflow runs with this:</p>
<pre><code class="lang-plaintext">gh run list
</code></pre>
<h4 id="heading-managing-workflow-runs-and-logs">Managing Workflow Runs and Logs</h4>
<p>If you want to check the details of a specific workflow run, you can view logs directly from the CLI:</p>
<pre><code class="lang-plaintext">gh run view &lt;run-id&gt; --log
</code></pre>
<p>You can also use GitHub CLI commands to enhance your Continuous Integration/Continuous Deployment (CI/CD) pipelines, ensuring smooth automation and better control over our workflows.</p>
<h3 id="heading-how-to-update-the-github-cli">How to Update the GitHub CLI</h3>
<p>To make sure that you’re using the latest version of GitHub CLI with all the latest features and fixes, you can update it using winget.</p>
<pre><code class="lang-plaintext">winget upgrade --id GitHub.cli
</code></pre>
<ul>
<li><p><strong>winget upgrade:</strong> Checks for updates for the specified package.</p>
</li>
<li><p><strong>--id GitHub.cli:</strong> Identifies the GitHub CLI package for the upgrade.</p>
</li>
</ul>
<h2 id="heading-advanced-github-cli-features-and-integrations">Advanced GitHub CLI Features and Integrations</h2>
<p>The GitHub CLI is not only useful for performing basic tasks. You can also perform some advanced operations with its help.</p>
<h3 id="heading-how-to-manage-gists-with-the-github-cli">How to Manage Gists with the GitHub CLI</h3>
<p>Gists are a simple way to share snippets of code. You can create, list, and manage your Gists right from the CLI. Here’s how you can create a gist:</p>
<pre><code class="lang-plaintext">gh gist create my-code-snippet.py
</code></pre>
<p>To list your gists:</p>
<pre><code class="lang-plaintext">gh gist list
</code></pre>
<h3 id="heading-interacting-with-releases-and-tags">Interacting with Releases and Tags</h3>
<p>To manage releases and tags, GitHub CLI provides commands to create, list, and delete releases. Here’s an example of creating a release:</p>
<pre><code class="lang-plaintext">gh release create v1.0.0
</code></pre>
<h3 id="heading-how-to-extend-the-github-cli-with-custom-scripts-and-aliases">How to Extend the GitHub CLI with Custom Scripts and Aliases</h3>
<p>You can write your own scripts and integrate them into GitHub CLI, or create aliases for commands you use frequently to save time. Aliases let you create shortcuts for commands that you use often. For example, the command given below creates an alias <code>prlist</code> that will show all pull requests, regardless of their state:</p>
<pre><code class="lang-plaintext">gh alias set prlist "pr list --state all"
</code></pre>
<p>In the same manner, you can create a shortcut <code>co</code> to quickly check out a pull request branch without typing the full command each time. The command is given below:</p>
<pre><code class="lang-plaintext">gh alias set co "pr checkout"
</code></pre>
<h3 id="heading-troubleshooting-common-issues">Troubleshooting Common Issues</h3>
<p>If you face any issues, you can troubleshoot by checking the command syntax, ensuring your GitHub CLI is up to date, or consulting the documentation using the command:</p>
<pre><code class="lang-plaintext">gh help &lt;command&gt;
</code></pre>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>GitHub CLI is an excellent tool that helps developers work directly from the terminal. It lets you manage repositories, handle pull requests and issues, trigger and monitor GitHub Actions, and even work with Gists.</p>
<p>You can save time and improve productivity as developers using this powerful tool. Keep exploring its new features and stay updated with the latest version.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Lazygit to Improve Your Git Workflow ]]>
                </title>
                <description>
                    <![CDATA[ Lazygit is an open-source command line terminal UI for Git commands that I’ve used for the last couple of years, and it’s become my new best friend. Basically, the Lazygit tool is a wrapper for the Git command line that replaces it with a UI. Instead... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-lazygit-to-improve-your-git-workflow/</link>
                <guid isPermaLink="false">67f7cc7aaf72aa46d378eaa0</guid>
                
                    <category>
                        <![CDATA[ Lazygit-tutorial ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Lazygit ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ version control ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Rajdeep Singh ]]>
                </dc:creator>
                <pubDate>Thu, 10 Apr 2025 13:49:46 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1744293114488/5332db88-bff6-4aef-91eb-3423f3b95e1a.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><a target="_blank" href="https://github.com/jesseduffield/lazygit">Lazygit</a> is an open-source command line terminal UI for Git commands that I’ve used for the last couple of years, and it’s become my new best friend.</p>
<p>Basically, the Lazygit tool is a wrapper for the Git command line that replaces it with a UI. Instead of typing out Git commands again and again in your terminal, you can use keyboard shortcuts to commit, push, pull, create, edit, and delete branches in your project.</p>
<p>In simple terms, Lazygit helps you increase your productivity while working with Git.</p>
<p>In this article, we'll walk through the essential features of Lazygit, and I’ll show you how it works.</p>
<h2 id="heading-table-of-contents">Table of Contents:</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-how-to-install-lazygit">How to Install Lazygit</a></p>
</li>
<li><p><a class="post-section-overview" href="#how-to-use-lazygit">How to Use Lazygit</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-shortcuts-and-key-mappings-in-lazygit">Shortcuts and Key Mappings in Lazygit</a></p>
</li>
<li><p><a class="post-section-overview" href="#other-keybindings-in-lazygit">Other Keybindings in Lazygit</a></p>
</li>
<li><p><a class="post-section-overview" href="#conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-how-to-install-lazygit">How to Install Lazygit</h2>
<p>Before we start, you’ll need to make sure it’s installed on your machine. You can install the tool in your system using the following methods (depending on your system):</p>
<h3 id="heading-homebrew">Homebrew</h3>
<p>You can <a target="_blank" href="https://formulae.brew.sh/formula/lazygit#default">install lazygit</a> in macOS using Homebrew like this:</p>
<pre><code class="lang-bash">brew install lazygit
</code></pre>
<h3 id="heading-scoop-windows">Scoop (Windows)</h3>
<p>You can <a target="_blank" href="https://scoop.sh/#/apps?q=lazygit">install lazygit</a> in Windows using Scoop like this:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Add the extras bucket</span>
scoop bucket add extras

<span class="hljs-comment"># Install lazygit</span>
scoop install lazygit
</code></pre>
<h3 id="heading-arch-linux">Arch Linux</h3>
<p>You can <a target="_blank" href="https://aur.archlinux.org/packages/lazygit-git">install lazygit</a> in Arch using Pacman like this:</p>
<pre><code class="lang-bash">sudo pacman -S lazygit
</code></pre>
<h3 id="heading-ubuntu-and-debian">Ubuntu and Debian</h3>
<p>You can install lazygit in Ubuntu and Debian using the following command:</p>
<pre><code class="lang-bash">LAZYGIT_VERSION=$(curl -s <span class="hljs-string">"https://api.github.com/repos/jesseduffield/lazygit/releases/latest"</span> | \grep -Po <span class="hljs-string">'"tag_name": *"v\K[^"]*'</span>)
curl -Lo lazygit.tar.gz <span class="hljs-string">"https://github.com/jesseduffield/lazygit/releases/download/v<span class="hljs-variable">${LAZYGIT_VERSION}</span>/lazygit_<span class="hljs-variable">${LAZYGIT_VERSION}</span>_Linux_x86_64.tar.gz"</span>
tar xf lazygit.tar.gz lazygit
sudo install lazygit -D -t /usr/<span class="hljs-built_in">local</span>/bin/
</code></pre>
<p>Verify the correct installation of lazygit:</p>
<pre><code class="lang-bash">lazygit --version
</code></pre>
<p>The command output looks like this:</p>
<pre><code class="lang-bash">➜  lazygit --version
commit=, build date=, build <span class="hljs-built_in">source</span>=nix, version=0.44.1, os=linux, arch=amd64, git version=2.47.0
</code></pre>
<h3 id="heading-fedora-and-rhel">Fedora and RHEL</h3>
<p>You can install lazygit in Fedora and RHEL using DNF like this:</p>
<pre><code class="lang-bash">sudo dnf copr <span class="hljs-built_in">enable</span> atim/lazygit -y
sudo dnf install lazygit
</code></pre>
<h3 id="heading-nixos">NixOS</h3>
<p>You can <a target="_blank" href="https://search.nixos.org/packages?channel=24.11&amp;from=0&amp;size=50&amp;sort=relevance&amp;type=packages&amp;query=lazygit">install lazygit</a> in NixOS using the following method:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># with nix-shell</span>
nix-shell -p lazygit

<span class="hljs-comment"># with nix-env</span>
nix-env -iA lazygit

<span class="hljs-comment"># with /etc/nixos/configuration.nix</span>
environment.systemPackages = [
  pkgs.lazygit
];
<span class="hljs-comment"># or with enable lazygit flakes</span>
nix run nixpkgs<span class="hljs-comment">#lazygit</span>
</code></pre>
<h2 id="heading-how-to-use-lazygit">How to Use Lazygit</h2>
<p>To use Lazygit, you don’t need any advanced knowledge about Lazygit or the Git CLI. If you are a beginner, that’s okay – I’ll walk you through the process and the basics here.</p>
<p>The main thing to understand is how the key mappings (shortcut keys) work. In this tutorial, I won’t discuss every key mapping, but I’ll teach you about some of the most common Lazygit key mappings which you’ll use on a daily basis. They’ll help you build a solid base for using the tool effectively.</p>
<p>To use Lazygit, first open the terminal you use. For example, I’m using the GNOME distro, so I’ll use the <a target="_blank" href="https://gitlab.gnome.org/chergert/ptyxis">Ptyxis terminal</a>.</p>
<p>Type the <code>lazygit</code> command in your terminal:</p>
<pre><code class="lang-bash">lazygit
</code></pre>
<p>The command output should look like this in your terminal:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743685042853/ab3f10f0-0d13-44d3-a86a-a58676cf30a5.gif" alt="Lazygit cli demo" class="image--center mx-auto" width="1000" height="545" loading="lazy"></p>
<p>The Lazygit UI is divided into six panels, or sections. Each panel serves a specific use case. Let’s explore these panels in more detail. You can see them highlighted in the image below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743687006438/5ca2451e-d4a0-42a7-89b2-0b94fd4ca162.png" alt="Explore the Lazygit panels" class="image--center mx-auto" width="1920" height="1048" loading="lazy"></p>
<h3 id="heading-panels-or-sections-in-lazygit">Panels or Sections in Lazygit</h3>
<p>As I mentioned above, there are six main panels in Lazygit. They are:</p>
<ol>
<li><p>Status</p>
</li>
<li><p>Files</p>
</li>
<li><p>Branches</p>
</li>
<li><p>Commits</p>
</li>
<li><p>Stash</p>
</li>
<li><p>Previews</p>
</li>
</ol>
<p>The most important panels in Lazygit are files, branches, and commits, but we’ll examine each of the six now.</p>
<h4 id="heading-status-panel">Status panel</h4>
<p>The status panel provides an overview of your current repository and the current checked-out branch, including local and remote changes.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743759630157/a7ef738b-5353-4941-9eb5-073d3235aaba.png" alt="Status panel in Lazygit" class="image--center mx-auto" width="648" height="98" loading="lazy"></p>
<p>Also, when you click on the status panel text, it opens a new tab or panel where it shows the recently opened repository list.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743760171736/8edb2f41-86ad-4e64-95f2-b1310d8c6f57.png" alt="Recently opened repos" class="image--center mx-auto" width="1920" height="1048" loading="lazy"></p>
<h4 id="heading-files-panel">Files panel</h4>
<p>The Files panel shows lists of the files in your repository that have been modified or changed. You can see files that you’ve deleted or discarded and unstaged.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743760570130/c891940b-4ba2-4fcb-a867-817b74e53618.png" alt="Files panel in Lazygit" class="image--center mx-auto" width="652" height="305" loading="lazy"></p>
<h4 id="heading-branches-panel">Branches panel</h4>
<p>The Branches panel shows lists of local and remote branches which are available in this repository.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743761276628/b34dc945-11c8-482d-8c4d-51783c68bf55.png" alt="Branches panel in lazygit" class="image--center mx-auto" width="649" height="256" loading="lazy"></p>
<h4 id="heading-commits-panel">Commits panel</h4>
<p>The Commits panel shows a list of commits in the current branch, which allows you to view, checkout, or interact with (view/undo/and so on) specific commits.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743761671236/80a7321a-8d16-4add-bc4a-db52d2987836.png" alt="commits panel in lazygit" class="image--center mx-auto" width="649" height="300" loading="lazy"></p>
<h4 id="heading-stashes-panel">Stashes panel</h4>
<p>The Stashes panel helps you manage your stashed changes, allowing you to apply, drop, or view them. Git stash is a location for storing uncommitted changes (modified, staged, or untracked files) in a hidden place, letting you switch branches without committing or discarding them.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743764679570/d7233d92-cfb0-4757-a338-bcc3d9fec2b8.png" alt="Stashes panel in laygit" class="image--center mx-auto" width="650" height="220" loading="lazy"></p>
<h4 id="heading-preview-panel">Preview panel</h4>
<p>The preview panel lets you preview unstaged changes, commits, logs, file content, and so on in Lazygit.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743765844602/7c492361-bbcf-4d2c-8588-b0c3e8704132.png" alt="Preview panel in lazygit" class="image--center mx-auto" width="1920" height="1048" loading="lazy"></p>
<p>To switch between panels, use the left and right arrow keys or the specific keybindings displayed at the top of each panel.</p>
<p>Press <code>1</code> to open the Status panel, <code>2</code> for Files, <code>3</code> for Branches, <code>4</code> for Commits, and <code>5</code> for the Stash panel.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743766590099/91689f4d-eba3-47cf-80a6-e18307c326cd.gif" alt="Navigation between panels in lazygit" class="image--center mx-auto" width="1000" height="545" loading="lazy"></p>
<h2 id="heading-shortcuts-and-key-mappings-in-lazygit"><strong>Shortcuts and Key Mappings in Lazygit</strong></h2>
<p>Lazygit is especially popular because of its shortcuts. You don’t need to write the same Git commands in the terminal over and over. Rather, you just need to use a shortcut.</p>
<p>For example, usually when you commit a file, you’ll first add the file using <code>git add</code> and then commit the file using <code>git commit</code>.</p>
<p>But in Lazygit, you just have to select the file using your mouse or the up and down keys and press space to commit the file.</p>
<p>In Lazygit, everything works around the shortcut commands, and you use shortcuts to perform common Git operations. Here are a few essential commands we’ll go over in this tutorial:</p>
<ul>
<li><p><code>a</code> – Stage or unstage all the files available in the Files panel.</p>
</li>
<li><p><code>space</code> (file panel) – Stage or unstage a single file in the Files panel.</p>
</li>
<li><p><code>c</code> – Commit staged changes by opening a commit message editor.</p>
</li>
<li><p><code>p</code> – Push commits to the remote repository.</p>
</li>
<li><p><code>P</code> – Pull changes from the remote repository.</p>
</li>
<li><p><code>z</code> – Undo the commit.</p>
</li>
<li><p><code>s</code> – Stash changes, allowing you to switch branches or perform other operations.</p>
</li>
<li><p><code>S</code> – View and apply stashed changes.</p>
</li>
<li><p><code>n</code> – Create a new branch.</p>
</li>
<li><p><code>d</code> – Delete your branch.</p>
</li>
<li><p><code>y</code> – Copy to clipboard.</p>
</li>
<li><p><code>M</code> – Merge branch.</p>
</li>
<li><p><code>space</code> (branches panel) – Check out the selected target branch.</p>
</li>
<li><p><code>e</code> – Edit or open the file in an external editor.</p>
</li>
<li><p><code>q</code> – Quit Lazygit and return to the terminal.</p>
</li>
<li><p><code>d</code> – Discard any changes in the file.</p>
</li>
<li><p><code>?</code> – Open the keybinding menu.</p>
</li>
</ul>
<p>Now let’s go over these shortcuts so you can understand how they work and see them in action.</p>
<h3 id="heading-how-to-commit-a-file">How to Commit a File</h3>
<p>To commit a file in Lazygit, first select the file you need by pressing the <code>space</code> key or the <code>a</code> key or double-clicking on the file. Then press <code>c</code>, and a new panel should open. There, you can add a message and hit enter to commit the file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743770682782/cbd83578-a286-482f-aeaa-31a9715a5483.gif" alt="cbd83578-a286-482f-aeaa-31a9715a5483" class="image--center mx-auto" width="1000" height="545" loading="lazy"></p>
<h3 id="heading-how-to-pull-and-push-code">How to Pull and Push Code</h3>
<p>To pull remote code from the Git server (Github, GitLab, Gitea, and so on), you can press <code>p</code> (lower case p):</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743774642242/decec44c-7622-432a-9da5-81b14b60ef8a.gif" alt="decec44c-7622-432a-9da5-81b14b60ef8a" class="image--center mx-auto" width="680" height="371" loading="lazy"></p>
<p>To push local code into a Git server, you can press <code>P</code> (upper case P):</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743842516002/37647a76-afe5-4d4b-acfc-fc85f1010749.gif" alt="37647a76-afe5-4d4b-acfc-fc85f1010749" class="image--center mx-auto" width="1000" height="545" loading="lazy"></p>
<h3 id="heading-how-to-create-and-delete-a-branch">How to Create and Delete a Branch</h3>
<p>To create a new branch in Lazygit, press <code>n</code>. A new panel will open where you’ll add the name of the branch and hit Enter.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743843881624/6c4db14e-0102-4333-be56-5d3796ab1c50.gif" alt="Create a new branch in lazygit" class="image--center mx-auto" width="1000" height="545" loading="lazy"></p>
<p>To delete a branch, press <code>d</code> and then specify whether you want to delete the branch in a local or remote repository. In the following example, I’m deleting a local branch.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743847541934/34e378b6-03ac-4e6d-93d0-35aaeda39e57.gif" alt="34e378b6-03ac-4e6d-93d0-35aaeda39e57" class="image--center mx-auto" width="1000" height="545" loading="lazy"></p>
<blockquote>
<p>Note: To delete and create a new branch in Lazygit, first select the branch panel and then press the corresponding shortcut key for deleting a branch. Press the d key to delete, and then to create a branch press the n key. Otherwise, it won’t work.</p>
</blockquote>
<h3 id="heading-how-to-undo-a-commit">How to Undo a Commit</h3>
<p>To undo the last commit in Lazygit, just press <code>z</code>. A new panel will open, showing the details of the commit you are undoing. Then, hit Enter.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743852917448/a3f2cab7-2806-48e4-a749-90f821b537dc.gif" alt="Undo commit in lazygit" class="image--center mx-auto" width="1000" height="545" loading="lazy"></p>
<h3 id="heading-how-to-merge-a-branch">How to Merge a Branch</h3>
<p>To merge a branch, press <code>M</code> (capital M). To open the merge options, choose the merge type, then hit Enter.</p>
<h4 id="heading-merge-type">Merge type:</h4>
<ul>
<li><p><strong>Merge:</strong> A standard merge, preserving the branch history.</p>
</li>
<li><p><strong>Squash merge:</strong> Combines all commits from the branch into a single commit on the target branch.</p>
</li>
<li><p><strong>Squash merge and leave uncommitted</strong>: Same as squash merge, but leaves the changes uncommitted.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743921595283/e46e0c89-b69a-4462-acd3-295045c99dfd.gif" alt="Merge branch in lazygit" class="image--center mx-auto" width="1000" height="545" loading="lazy"></p>
<h3 id="heading-how-to-resolve-merge-conflicts">How to Resolve Merge Conflicts</h3>
<p>To resolve merge conflicts in Lazygit, first merge a branch by pressing <code>M</code>, then choose the merge type (which I describe in the subsection on how to merge a branch) and hit Enter.</p>
<p>If any merge conflicts occur, the conflicting file(s) appear in the files panel. Press Enter to view the merge conflicts in the preview panel and navigate between conflicts using the up and down keys. Select the correct merge conflicts, press the space key, and your merge issue will be resolved.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743921640247/e5b7f971-f027-47df-be4c-a90b356e24f8.gif" alt="resolve merge conflicts in lazygit" class="image--center mx-auto" width="1000" height="545" loading="lazy"></p>
<h3 id="heading-how-to-discard-changes">How to Discard Changes</h3>
<p>To discard or drop any changes in a file or commit, press <code>d</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743774406564/bc5b91fb-2d33-41d0-95b9-667478c4c8db.gif" alt="bc5b91fb-2d33-41d0-95b9-667478c4c8db" class="image--center mx-auto" width="1000" height="545" loading="lazy"></p>
<h3 id="heading-how-to-copy">How to Copy</h3>
<p>To copy a file name, path, commit hash, message, URL, author, or any other details, first select the commit or file, then press <code>y</code> to copy the information.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743856793802/e23d9e5c-b0b4-40a0-8124-f94669b377c0.gif" alt="e23d9e5c-b0b4-40a0-8124-f94669b377c0" class="image--center mx-auto" width="1000" height="545" loading="lazy"></p>
<h2 id="heading-other-keybindings-in-lazygit">Other Keybindings in Lazygit</h2>
<p>There are other keybindings in Lazygit which I did not discuss in this article. To learn about every keybinding, you can check out the keybindings menu. Open the keybindings menu and press the <code>?</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743843262905/a4aba097-999b-4ff8-bd00-661181d96aad.gif" alt="a4aba097-999b-4ff8-bd00-661181d96aad" class="image--center mx-auto" width="1000" height="545" loading="lazy"></p>
<p>When you open the keybindings help menu, it changes according to the panel you’re in.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743915037200/9339b7b1-b2a4-45e5-8a51-5be0a9f2a319.gif" alt="9339b7b1-b2a4-45e5-8a51-5be0a9f2a319" class="image--center mx-auto" width="1000" height="545" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Lazygit helps you become more productive when working with Git or Git commands. As a beginner, starting with Lazygit can be somewhat challenging because of its key mappings, but once you get the hang of them, they’re pretty easy to remember and use.</p>
<p>If you are a first-time Lazygit user, my suggestion is to avoid using Lazygit on a working repository. Instead, create a demo repository and try it out/practice.</p>
<p>To learn more about <a target="_blank" href="https://github.com/jesseduffield/lazygit/blob/master/docs/keybindings/Keybindings_en.md">LazyGit keybindings or shortcuts</a>, you can refer to the Lazygit documentation. You can also check out the following YouTube tutorials for beginners:</p>
<ul>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=A6F_8ajlrYQ">LazyGIt - A Faster, Easier Way to Use Git on Terminal &amp; NeoVim</a></p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=Ihg37znaiBo">Lazygit - The Best Way To Use Git On The Terminal &amp; Neovim</a></p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=06lEP59XAgM">My new favorite way to use Git</a></p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=dSWJKcEiAaM">LazyGit: Effortless Git in Your Terminal!</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Git through Gamification – A Visual Guide to Key Version Control Concepts ]]>
                </title>
                <description>
                    <![CDATA[ Git has many concepts and commands that you’ll need to understand before you feel confident using it. Some of these concepts may sound trivial, especially to someone who has worked with Git before. But like most Git and coding concepts, even the “sim... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-git-through-gamification/</link>
                <guid isPermaLink="false">67c1cfa78df3594301bc3fef</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ gamification  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learn coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ visualization ]]>
                    </category>
                
                    <category>
                        <![CDATA[ version control ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jacob Stopak ]]>
                </dc:creator>
                <pubDate>Sun, 02 Mar 2025 06:00:00 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1740686401633/ffd9ac3c-668a-47bf-b2ba-f7cee14e74a8.webp" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Git has many concepts and commands that you’ll need to understand before you feel confident using it. Some of these concepts may sound trivial, especially to someone who has worked with Git before. But like most Git and coding concepts, even the “simple” ones tend to be abstract.</p>
<p>The three concepts that stand out to me as the most fundamental for being able to effectively work with Git at a basic level are:</p>
<ol>
<li><p>The <strong>working directory</strong></p>
</li>
<li><p>The <strong>staging area</strong></p>
</li>
<li><p>The <strong>commit history</strong></p>
</li>
</ol>
<p>In this article, we’ll take a new approach to representing these three concepts: by <em>visualizing them in an immersive, 3D game world!</em></p>
<p>I’ll provide a tangible, visual representation of these key Git concepts which are almost always described in an abstract and confusing way. I hope that this will make them much more intuitive for you to grasp.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-visualize-your-working-directory">Visualize your Working Directory</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-demystify-your-staging-area">Demystify your Staging Area</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-literally-walk-through-your-commit-history">Literally Walk through your Commit History</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-summary">Summary</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-try-it-yourself">Try it Yourself</a></p>
</li>
</ol>
<h2 id="heading-visualize-your-working-directory">Visualize your Working Directory</h2>
<p>What does your brain picture when you think of the “working directory”? I assume it’s something like a folder structure starting at the project root, containing the code files and subfolders that make up the project.</p>
<p>While that is a fair description of the working directory, it is a bit hard to imagine and misses the segmentation that Git applies to your project. Although the current state of your entire project, folder structure, and code files do reside in the working directory, Git doesn’t really need to do much about that unless certain <em>changes</em> are detected in those files.</p>
<p>Git detects and reports changes to the working directory with the <a target="_blank" href="https://initialcommit.com/blog/git-status">Git status command</a>, which shows output like this:</p>
<pre><code class="lang-bash">Jack@RAPTOR ~/my-project (main)&gt; git status
On branch main
Your branch is up to date with <span class="hljs-string">'origin/main'</span>.

Changes not staged <span class="hljs-keyword">for</span> commit:
  (use <span class="hljs-string">"git add &lt;file&gt;..."</span> to update what will be committed)
  (use <span class="hljs-string">"git restore &lt;file&gt;..."</span> to discard changes <span class="hljs-keyword">in</span> working directory)
        modified:   main.py
        modified:   settings.py

Untracked files:
  (use <span class="hljs-string">"git add &lt;file&gt;..."</span> to include <span class="hljs-keyword">in</span> what will be committed)
        one.py
        three.py
        two.py

no changes added to commit (use <span class="hljs-string">"git add"</span> and/or <span class="hljs-string">"git commit -a"</span>)
</code></pre>
<p>The two relevant sections here are:</p>
<ol>
<li><p><strong>Changes not staged for commit:</strong> Lists existing files tracked by Git which currently contain code changes. In the example above, we see two “modified files”: <code>main.py</code> and <code>settings.py</code>.</p>
</li>
<li><p><strong>Untracked files:</strong> Lists new files in your project that Git doesn’t know about yet. In the example above, we see three new, untracked files: <code>one.py</code>, <code>two.py</code>, and <code>three.py</code>.</p>
</li>
</ol>
<p>When it comes to understanding Git, thinking of the working directory as the changes Git sees in these two sections – <strong>Untracked files</strong> and <strong>Modified files</strong> – is quite helpful.</p>
<p>But the <code>git status</code> command reports these details in the terminal in a purely text-based way, which doesn’t do newer Git users any favors when it comes to wrapping their heads around Git.</p>
<p>Some Git GUI’s do a better job with this (they do provide a safer point-and-click interface, after all), but in my experience, none of them make things <em>obvious at a glance</em>.</p>
<p>Instead, imagine that as a new Git user, you saw this:</p>
<p><a target="_blank" href="https://devlands.com"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740587730262/375bef09-b8b8-43e3-a18c-5b1e589b6097.png" alt="Image captured from Devlands, the gamified Git interface and tutorial, showing the untracked files and modified files sections of the working directory wall" class="image--center mx-auto" width="600" height="400" loading="lazy"></a></p>
<p>A nice big wall with clearly delineated sections for <strong>Untracked files</strong> and <strong>Modified files</strong>. Files corresponding to each section are represented as blocks on the wall within that section, clearly labelled with their filename.</p>
<p>More specifically, the blocks representing files <code>one.py</code>, <code>two.py</code>, and <code>three.py</code> are all sitting neatly in the <strong>Untracked files</strong> section, and the blocks representing the files <code>main.py</code> and <code>settings.py</code> are in the <strong>Modified files</strong> section.</p>
<p>This makes it abundantly clear to even a total novice that Git is interpreting these files differently and categorizing them in a logical way. It takes the abstract Git concept of the “working directory” and transforms it into a form that almost anyone can wrap their heads around at a glance.</p>
<p>But something is missing here. Let’s say you run the command <code>git add one.py</code>. This stages the untracked file <code>one.py</code> to be included in the next commit. What happens to the block labelled <code>one.py</code> on the wall?</p>
<h2 id="heading-demystify-your-staging-area">Demystify your Staging Area</h2>
<p>To answer that, let’s move on to the mysterious <a target="_blank" href="https://initialcommit.com/blog/git-add">Git “staging area”</a>. But first, where exactly IS the staging area?</p>
<p>Well, technically any staged file changes are still just sitting in the working directory, which makes things a bit confusing.</p>
<p>Here is how Git reports this in the terminal:</p>
<pre><code class="lang-bash">Jack@RAPTOR ~/D/git-worlds (main)&gt; git status
On branch main
Your branch is up to date with <span class="hljs-string">'origin/main'</span>.

Changes to be committed:
  (use <span class="hljs-string">"git restore --staged &lt;file&gt;..."</span> to unstage)
        new file:   one.py
</code></pre>
<p>As you can see from Git’s output, it now includes the section <strong>Changes to be committed</strong>, which includes the file <code>one.py</code> that was staged with the <code>git add</code> command.</p>
<p>But this is still a bit unclear. Are the staged file changes in <code>one.py</code> still a part of the working directory? Or does Git store them elsewhere?</p>
<p>Well, the answer is… BOTH:</p>
<p><a target="_blank" href="https://devlands.com"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740592262850/dc65c06d-0ec6-4de6-bbe9-53307d523e68.png" alt="Image captured from Devlands, the gamified Git interface and tutorial, adding the staged files section onto the working directory wall" class="image--center mx-auto" width="600" height="400" loading="lazy"></a></p>
<p>Here you can see that we zoomed out a bit from the previous image, to reveal a third section of the wall labeled <strong>Staged files</strong>.</p>
<p>Since we ran the command <code>git add one.py</code>, you can see that the corresponding block representing the <code>one.py</code> file moved from the Untracked files column to the Staged files column.</p>
<p>This conveys quite clearly that a file sitting in the staging area is still a part of the working directory (because it is a part of the overall wall), while also being segmented into its own designated space.</p>
<p>From a technical perspective, Git’s staging area is just a file named <strong>index</strong> which lives in the <code>.git/</code> folder. Git builds up the code changes specified by the <code>git add</code> command in this file, which is used as the source for those changes the next time the <code>git commit</code> command is run.</p>
<p>But from a workflow perspective, representing the staging area as a section on the “working directory wall” as in the image above makes things more intuitive to understand.</p>
<p>Next, let’s explore how we might visualize things once the staged changes are turned into a new Git commit and become a part of the active branch.</p>
<h2 id="heading-literally-walk-through-your-commit-history">Literally Walk through your Commit History</h2>
<p>What does your mind’s eye see when you think of Git’s “commit history”?</p>
<p>Well, the prettiest way Git does it in the terminal is by using the <a target="_blank" href="https://initialcommit.com/blog/git-log">Git log command</a>, such as <code>git log --graph --all</code>, which provides output like:</p>
<pre><code class="lang-bash">* commit 88085cff3e2d7657f26eb6479b308526df7d2bba (HEAD -&gt; dev, origin/dev)
| Author: Jacob Stopak &lt;jacob@initialcommit.io&gt;
| Date:   Tue Apr 23 20:31:24 2024 -0700
|
|     Fix <span class="hljs-built_in">command</span> as title clip, ellipses and arrow length <span class="hljs-keyword">in</span> rebase subcommand
|
|     Signed-off-by: Jacob Stopak &lt;jacob@initialcommit.io&gt;
|
*   commit e264605ea26a808c34d4dc2fbc6dad65a8e28c5f
|\  Merge: cb3fa5f b8c071c
| | Author: Jacob Stopak &lt;jacob@initialcommit.io&gt;
| | Date:   Wed Mar 20 19:51:06 2024 -0700
| |
| |     Merge branch <span class="hljs-string">'main'</span> into dev
| |
* | commit cb3fa5f3bdbdcff3d9a8c844cda99d46bf64e337
| | Author: Jacob Stopak &lt;jacob@initialcommit.io&gt;
| | Date:   Sat Mar 9 22:00:49 2024 -0800
| |
| |     Add --staged flag to git restore subcommand
| |
| |     Signed-off-by: Jacob Stopak &lt;jacob@initialcommit.io&gt;
| |
| * commit b8c071cb9a1653748525aa01c2b6bafe06ed9100
|/  Author: Jacob Stopak &lt;jacob@initialcommit.io&gt;
|   Date:   Wed Mar 20 19:50:53 2024 -0700
|
|       Correct license specified <span class="hljs-keyword">in</span> pyproject.toml from MIT to GNU GPLv2
|
|       Signed-off-by: Jacob Stopak &lt;jacob@initialcommit.io&gt;
|
* commit 32a3a3fca583f6c68225b974716e74b557a1a094
| Author: Jacob Stopak &lt;49353917+initialcommit-io@users.noreply.github.com&gt;
| Date:   Tue Aug 22 11:31:38 2023 -0700
|
|     Update README.md
</code></pre>
<p>Unfortunately, this is not so pretty at all. This long, garbled list of commit IDs, names, dates, and commit messages is definitely not something most folks would consider user-friendly.</p>
<p>The <code>--graph</code> option supplied above does show the commit relationships by drawing little lines connecting each commit in the terminal, but the purely text-based nature of this is just not intuitive to most people at a glance.</p>
<p>Now consider the following gamified representation of Git’s commit history:</p>
<p><a target="_blank" href="https://devlands.com"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740594184258/8d5a33c8-ad60-4496-a50d-a27fc6b8e752.png" alt="Image captured from Devlands, the gamified Git interface and tutorial, showing the project's commit history and branches" class="image--center mx-auto" width="600" height="400" loading="lazy"></a></p>
<p>Now we’re talkin’! In this image, each Git commit is represented by a white block with a shortened 6-character commit ID.</p>
<p>Each white commit block points back to its parent commit with an arrow, forming very clear chains of commits that make up Git branches.</p>
<p>You might have noticed that some of the white commit blocks have colored blocks sitting on top of them. The green blocks are <a target="_blank" href="https://initialcommit.com/blog/git-branches">branch names</a>, the yellow blocks are <a target="_blank" href="https://initialcommit.com/blog/git-tag">Git tags</a>, the blue block is <a target="_blank" href="https://initialcommit.com/blog/what-is-git-head">Git’s HEAD pointer</a>, and the red blocks are remote-tracking branches. These are collectively referred to as <a target="_blank" href="https://initialcommit.com/blog/what-is-git-head#git-refs-and-heads">Git refs</a>.</p>
<p>Besides being able to easily distinguish between them, representing ref types as different colored blocks clarifies another often-confusing Git concept. In Git, branches (along with other refs types) are just “pointers” to a specific commit. It is tempting to think of a branch as a series of connected commits that share a history – and conceptually this is correct – but in Git, a branch is really just a glorified label pointing to a specific commit.</p>
<p>In this gamified world, you can <em>literally walk through your commit history</em> to see, interact with, and examine the code changes in any commit.</p>
<h2 id="heading-summary">Summary</h2>
<p>In this article, we explored how Git’s fundamental concepts - the working directory, staging area, and commit history - can be difficult to grasp due to their abstract nature.</p>
<p>To make these concepts more accessible, we introduced a gamified, visual approach that transforms them into something tangible: an immersive game world where files and commits are represented as interactive blocks.</p>
<p>By presenting Git this way, beginner coders, students, and developers of all experience levels can intuitively learn Git concepts and commands, and confidently apply them in professional projects.</p>
<h2 id="heading-try-it-yourself">Try it Yourself</h2>
<p>The images in this post were captured in <a target="_blank" href="https://devlands.com">Devlands</a>, the first and only <em>gamified Git interface and tutorial</em>, which I’m building in Python.</p>
<p>In Devlands, not only can you walk through your codebase… You can also learn Git concepts and commands with a character-guided tutorial, simulate and run Git commands directly in the game, see their results applied in the game world in real time, and use AI to explain code you don’t understand.</p>
<p>If you or someone you know is a visual learner, beginner coder, or newer Git user, <a target="_blank" href="https://devlands.com">consider checking it out!</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Simplify Your Git Commands with Git Aliases ]]>
                </title>
                <description>
                    <![CDATA[ As a developer, you probably use the Git CLI (Command Line Interface) daily. However, writing the same old commands repeatedly can be laborious, especially when the commands are lengthy. This is where Git aliases come in to help out. In this article,... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-simplify-your-git-commands-with-git-aliases/</link>
                <guid isPermaLink="false">673342b4d519e9b4d12f23d8</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Grant Riordan ]]>
                </dc:creator>
                <pubDate>Tue, 12 Nov 2024 11:57:40 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1730061609849/a3f3e8f3-102e-4dde-bec7-660be0121fad.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As a developer, you probably use the Git CLI (Command Line Interface) daily. However, writing the same old commands repeatedly can be laborious, especially when the commands are lengthy. This is where Git aliases come in to help out.</p>
<p>In this article, you’ll learn how to simplify your Git commands by using aliases.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-are-git-aliases">What Are Git Aliases?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-add-git-aliases-via-the-global-git-configuration-file-recommended">How to Add Git Aliases Via the Global Git Configuration File (Recommended)</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-set-your-preferred-git-editor">How to Set Your Preferred Git Editor</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-open-the-git-config-file">How to Open the Git Config File</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-add-a-git-alias-via-your-config-file">How to Add a Git Alias Via Your Config File</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-add-aliases-in-the-cli">How to Add Aliases in the CLI</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-custom-commands-for-more-complex-shortcuts">How to Create Custom Commands for More Complex Shortcuts</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-how-to-use-parameters-in-all-commands">How to Use Parameters in All Commands</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-other-useful-aliases">Other Useful Aliases</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-summary">Summary</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li><p>Knowledge of Git.</p>
</li>
<li><p>Git Bash installed (optional but recommended Windows users).</p>
</li>
<li><p>An IDE like VS Code (this is also optional).</p>
</li>
</ul>
<h2 id="heading-what-are-git-aliases">What Are Git Aliases?</h2>
<p>Git aliases are custom shortcuts for existing Git commands, making common tasks quicker and easier. They let you define your commands, allowing you to tailor shortcuts exactly how you want.</p>
<p>You have two main options for adding/creating git aliases in your git configuration, using your Git configuration file or adding them directly via the CLI (terminal/command line).</p>
<h2 id="heading-how-to-add-git-aliases-via-the-global-git-configuration-file-recommended">How to Add Git Aliases Via the Global Git Configuration File (Recommended)</h2>
<p>This option involves opening your global git config file and appending your git aliases to the bottom of the file.</p>
<h3 id="heading-how-to-set-your-preferred-git-editor">How to Set Your Preferred Git Editor</h3>
<p>Set your default Git config editor software, for example, I use VS Code to edit my Git configuration file, but you can use whatever text editor/code editor you prefer.</p>
<p>Run this command to set Notepad as your preferred editor on Windows (CMD/PowerShell):</p>
<pre><code class="lang-bash">git config --global core.editor <span class="hljs-string">"notepad"</span>
</code></pre>
<p>Run this command to set VS Code as your preferred editor on Windows &amp; MacOS /Linux:</p>
<pre><code class="lang-bash">git config --global core.editor <span class="hljs-string">"code --wait"</span>
</code></pre>
<p>To set a different default editor, search online for “Set {editor} as default Git editor,” and replace <code>{editor}</code> with your preferred app.</p>
<h3 id="heading-how-to-open-the-git-config-file">How to Open the Git Config File</h3>
<p>Open your terminal of choice and enter the following command. This will open the global Git config file (<code>git config —global</code>), in edit mode (<code>-e</code>).</p>
<pre><code class="lang-bash">git config --global -e
</code></pre>
<p>You can open the git configuration file directly from the following locations:</p>
<p><strong>Mac Os</strong>: Home Directory → show hidden (Cmd + Shift + H) → <code>.gitconfig</code>  </p>
<p><strong>Windows</strong>: <code>C:\Users\YourUsername\</code> → then show hidden files (in View) → and find <code>.gitconfig</code>  </p>
<p><strong>Linux:</strong> Home Directory → show hidden (Ctrl + H) → <code>.gitconfig</code></p>
<h3 id="heading-how-to-add-a-git-alias-via-your-config-file">How to Add a Git Alias Via Your Config File</h3>
<p>If you're adding Git aliases for the first time, open your <code>.gitconfig</code> file, add <code>[alias]</code> at the end, and then list your shortcuts below. This tells Git these are aliases. Add your preferred alias (the shortened command you wish to run).</p>
<p>The format of a git alias is <code>&lt;alias&gt; = &lt;command&gt;</code>, so we have:</p>
<pre><code class="lang-bash">co = checkout
cob = checkout -b
</code></pre>
<p><strong>Explanation of the above examples:</strong></p>
<p><code>co = checkout</code> this maps the <code>git checkout</code> command to a shorter <code>git co</code> command. You’d then call <code>git co feature/123</code> in your terminal.</p>
<p>You do not need to type <code>git</code> in front of the command, as the configuration will pre-pend this automatically as it knows the command you’re mapping is a Git command.  </p>
<p><strong>Note</strong>: Any parameters passed to the command will be applied to the final command called within the alias only.  </p>
<p>More aliases can be added in this way, mapping shortcuts to existing git commands. Saving and closing the file will then make the aliases available within your terminal.</p>
<h2 id="heading-how-to-add-aliases-in-the-cli">How to Add Aliases in the CLI</h2>
<p>If you want a more streamlined approach to adding Git aliases, you can add them directly from within the terminal/command line.</p>
<p>Taking the examples above, we can add these directly in the following way:</p>
<p>The format of the command is: <code>git config --global alias.{alias} "{original command}"</code>:</p>
<pre><code class="lang-bash">git config --global alias.co <span class="hljs-string">"checkout"</span>
<span class="hljs-comment">#or</span>
git config --global alias.cob <span class="hljs-string">"checkout -b"</span>
</code></pre>
<p>It’s as easy as that!</p>
<h2 id="heading-how-to-create-custom-commands-for-more-complex-shortcuts">How to Create Custom Commands for More Complex Shortcuts</h2>
<p>Ok, this seems great, but it’s not really that impressive – we’re only removing a few characters. However, we can make them much more helpful, we can create our commands using shell commands.</p>
<p>Let’s take the following example, a command I use a lot!</p>
<pre><code class="lang-bash">new-work = !git checkout main &amp;&amp; git pull &amp;&amp; git cob
</code></pre>
<p>This alias combines multiple Git commands into one shell command. The <code>!</code> character tells Git to treat it as a shell command, not a standard Git command.  </p>
<p>Without <code>!</code>, Git treats the alias as a Git command (for example, <code>checkout</code> becomes <code>git checkout</code>). With <code>!</code>, Git knows to run it as a shell command without adding <code>git</code> in front.</p>
<p>By chaining these commands, we can write much more useful aliases. The one above will:</p>
<ul>
<li><p>First, check out the <code>main</code> branch.</p>
</li>
<li><p>Using the <code>&amp;&amp;</code> operator, it means the other commands will only run if the previous one has been successful.</p>
</li>
<li><p>Secondly, it will pull down the changes from <code>main</code>.</p>
</li>
<li><p>Finally, create a new branch from the <code>main</code> branch using our other alias <code>git cob</code>.</p>
</li>
</ul>
<p>The final command can then accept parameters (as the original Git command would), so it can be used like so:</p>
<pre><code class="lang-bash">git new-work <span class="hljs-string">'feature/new-work-from-main'</span>
</code></pre>
<h3 id="heading-how-to-use-parameters-in-all-commands">How to Use Parameters in All Commands</h3>
<p>Up until now, we’ve only been able to pass our parameters to the final git command in our alias. However, what if we want to pass parameters to some, if not all of the commands within the alias? We can achieve this by using a shell function.</p>
<p>Take the following example:</p>
<pre><code class="lang-bash">new-work = <span class="hljs-string">"!f() { git checkout \"<span class="hljs-variable">$1</span>\" &amp;&amp; git pull &amp;&amp; git checkout -b \"<span class="hljs-variable">$2</span>\"; }; f"</span>
</code></pre>
<p>Above we’re using a shell function that processes input parameters.</p>
<p><strong>Explanation:</strong></p>
<ol>
<li><p><code>!f()</code>:</p>
<ul>
<li><p>The <code>!</code> tells Git to interpret the alias as a shell command rather than a standard Git command.</p>
</li>
<li><p><code>f()</code> defines a shell function <code>f</code> that will allow us to execute multiple commands in sequence.</p>
</li>
</ul>
</li>
<li><p>Everything inside <code>{ }</code> is what will be executed within the <code>f()</code> function.</p>
</li>
<li><p><code>git checkout \”$1”'\</code>: Will run a parameterized Git command, where <code>$1</code> is escaped and will be replaced with the 1st parameter passed to the alias. The <code>\"</code> escape sequences around <code>$1</code> allow for branch names with spaces.</p>
</li>
<li><p><code>&amp;&amp;</code> is a logical operator that ensures each command only runs if the previous one succeeds. If <code>git checkout "$1"</code> fails, the commands that follow won’t run.</p>
</li>
<li><p><code>git checkout -b \”$2”\</code> : Creates a new branch with the name of the second parameter as before.</p>
</li>
<li><p><code>;</code>: Marks the end of the <code>f()</code> function;</p>
</li>
<li><p><code>f</code>: The final <code>f</code> calls the alias function immediately, meaning that when you call the alias, it declares the function and then calls it immediately.</p>
</li>
</ol>
<p><strong>Usage:</strong></p>
<pre><code class="lang-bash">git new-work development task/feat-123
</code></pre>
<h2 id="heading-other-useful-aliases">Other Useful Aliases</h2>
<pre><code class="lang-bash">[<span class="hljs-built_in">alias</span>]
     co = checkout
    cob = checkout -b
    s = status
    tidy-up = !git checkout main &amp;&amp; git branch | grep -v <span class="hljs-string">"main"</span> | xargs git branch -D
    latest = !git checkout main &amp;&amp; git pull
    new-work = <span class="hljs-string">"!f() { git checkout \"<span class="hljs-variable">$1</span>\" &amp;&amp; git pull &amp;&amp; git checkout -b \"<span class="hljs-variable">$2</span>\"; }; f"</span>
    <span class="hljs-keyword">done</span> = !git push -u origin HEAD
    save = !git add -A &amp;&amp; git commit
    saveM = !git add -A &amp;&amp; git commit -m
    br = branch --format=<span class="hljs-string">'%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(contents:subject) %(color:green)(%(committerdate:relative)) [%(authorname)]'</span> --sort=-committerdate
</code></pre>
<h2 id="heading-summary">Summary</h2>
<p><code>co:</code> Checkout given branch → <code>git co task/feat-123</code>  </p>
<p><code>cob</code>: Creates a new branch from the current branch → <code>git cob feature/123</code>  </p>
<p><code>s</code>: Calls <code>git status</code> to view the status of the current git branch → <code>git s</code>  </p>
<p><code>tidy-up</code>: Deletes all local branches other than <code>main</code> → <code>git tidy-up</code>  </p>
<p><code>latest</code>: Gets the latest changes from remote <code>main</code> branch → <code>git latest</code>  </p>
<p><code>new-work</code>: Creates a new branch (2nd param) from 1st param branch → <code>git new-work main feat/123</code></p>
<p><code>git done</code>: Pushes the current branch to the remote repository (<code>origin</code>) and sets it as the upstream branch. This can be helpful when pushing your first commit and you get the error:<br><code>fatal: The current branch has no upstream branch. To push the current branch and set the remote as upstream, use git push --set-upstream origin</code></p>
<p><code>save</code>: Will simply add all changed files, and commit them, opening your default Git editor and requesting a commit message → <code>git save</code></p>
<p><code>savem</code>: Will do as above, but instead of opening your editor, you can pass in a commit message inline → <code>git savem ‘Task123: add index.html</code></p>
<p><code>br:</code> This one looks complicated, but it’s not as complicated as it seems but does highlight the power of aliases. In essence, it customizes the output format of <code>git branch</code> to display a detailed, color-coded list of branches, sorted by the most recent commit date, it will look something like the image below for each branch you have locally.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730060113591/36008ee8-e54e-4b06-8a84-2a20885a1255.png" alt="36008ee8-e54e-4b06-8a84-2a20885a1255" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>There you have it, an introduction to Git aliases and some useful examples of aliases you can add as a starter to your configuration.</p>
<p>As always if you want to chat about it, or hear about future articles you can follow me on <a target="_blank" href="https://x.com/grantdotdev">Twitter</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Improve and Restructure Your Codebase with AI Tools & Version Control ]]>
                </title>
                <description>
                    <![CDATA[ A codebase can become messy and hard to manage over time. This happens because of quick fixes, outdated features, or just not enough time to clean things up. When code becomes difficult to read or change, it slows down progress and can even cause bug... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/improve-and-restructure-codebase-with-ai-tools/</link>
                <guid isPermaLink="false">6720f7fb2e452955f9433899</guid>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Programming Tips ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ optimization ]]>
                    </category>
                
                    <category>
                        <![CDATA[ improve performance ]]>
                    </category>
                
                    <category>
                        <![CDATA[ version control ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Pull Requests ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oluwadamisi Samuel ]]>
                </dc:creator>
                <pubDate>Tue, 29 Oct 2024 14:58:03 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1730194934749/feb606d0-bbbd-43ae-a58c-5932d8c2d76c.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>A codebase can become messy and hard to manage over time. This happens because of quick fixes, outdated features, or just not enough time to clean things up.</p>
<p>When code becomes difficult to read or change, it slows down progress and can even cause bugs. To keep a codebase healthy and easy to work with, you’ll need to take care of it.</p>
<p>Improving and organizing old code can feel like a big task, but there are tools and methods that can make it easier. This guide will show how to refresh your codebase step by step which will make it simpler to work with and less likely to cause issues.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-how-to-review-your-code-effectively">How to Review Your Code Effectively</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-identify-technical-debt-and-problem-areas-in-code">How to Identify Technical Debt and Problem Areas in Code</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-measure-code-quality-with-code-analysis-tools">How to Measure Code Quality with Code Analysis Tools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-ai-tools-to-help-you-improve-your-code">AI Tools to Help You Improve Your Code</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-version-control-best-practices-for-code-changes">Version Control Best Practices for Code Changes</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-how-to-review-your-code-effectively">How to Review Your Code Effectively</h2>
<p>Code reviews are essential for catching issues early, improving readability, and ensuring long-term maintainability. Reviewing your own code or someone else’s involves more than just scanning for errors – you’ll also want to make sure each part is clear, efficient, and follows good practices.</p>
<p>Here’s a step-by-step approach to help you review code effectively, with practical strategies, tools, and what to look for during the process.</p>
<h3 id="heading-strategies-for-effective-code-review">Strategies for Effective Code Review</h3>
<ol>
<li><p><strong>Break Down the Review Process:</strong> Reviewing code all at once can be overwhelming, especially in large projects. Focus on small sections of the codebase at a time, such as individual functions or modules. This approach helps you examine each part closely and avoids missing issues that could be overlooked in a quick scan.</p>
</li>
<li><p><strong>Review for Clarity and Simplicity:</strong> Good code should be easy to read and understand. When reading through the code:</p>
<ul>
<li><p><strong>Variable and Function Names:</strong> Are variable names descriptive enough to convey their purpose? Long, unclear names make code harder to follow.</p>
</li>
<li><p><strong>Function Length:</strong> Keep functions short and focused on one task. Long functions are harder to debug and maintain.</p>
</li>
<li><p><strong>Comments and Documentation:</strong> Comments should explain <em>why</em> something is done rather than <em>what</em> is happening, which should be clear from the code itself. For instance, avoid excessive commenting on trivial lines and focus on complex logic or business rules.</p>
</li>
</ul>
</li>
<li><p><strong>Check for Code Reusability and Modularity:</strong> Look for repeated code or functions performing multiple tasks. By modularizing code, you make it easier to test, update, and reuse. In a review, look for:</p>
<ul>
<li><p><strong>Duplicate Code:</strong> Repeated code can often be refactored into a function.</p>
</li>
<li><p><strong>Single Responsibility:</strong> Each function should handle one task, making it easier to maintain and update.</p>
</li>
</ul>
</li>
<li><p><strong>Examine Error Handling and Edge Cases:</strong> Robust code should handle unexpected inputs or errors gracefully. During a review, think about potential edge cases that could break the code:</p>
<ul>
<li><p><strong>Null or Undefined Values:</strong> Does the code check for undefined values where needed?</p>
</li>
<li><p><strong>Out-of-Range Errors:</strong> Ensure array indexes and calculations won’t produce errors with edge cases.</p>
</li>
<li><p><strong>Error Messages:</strong> Make sure error handling is meaningful, with clear error messages where applicable.</p>
</li>
</ul>
</li>
<li><p><strong>Look for Performance Issues:</strong> Performance may not always be critical, but it’s good to check for potential bottlenecks. Look for:</p>
<ul>
<li><p><strong>Loop Optimization:</strong> Avoid deeply nested loops or repeated work inside loops.</p>
</li>
<li><p><strong>Database Queries:</strong> Minimize unnecessary database calls.</p>
</li>
<li><p><strong>Heavy Computation in the Main Thread:</strong> Move any heavy processing outside the main application thread if possible.</p>
</li>
</ul>
</li>
<li><p><strong>Ensure Consistency with Coding Standards:</strong> Following a consistent coding style improves readability across the team. Many teams use linters or style guides to enforce these standards. Look for:</p>
<ul>
<li><p><strong>Code Format:</strong> Consistent indentation, spacing, and use of braces.</p>
</li>
<li><p><strong>Naming Conventions:</strong> Follow agreed naming conventions (camelCase, snake_case, and so on) consistently.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-tools-to-assist-with-code-reviews">Tools to Assist with Code Reviews</h3>
<p>There are a number of tools out there that can help streamline your code reviews, whether you’re checking your own code or collaborating with others:</p>
<h4 id="heading-1-linters-like-eslint-and-pylint"><strong>1. Linters (like ESLint and Pylint)</strong></h4>
<p>Linters check for syntax errors, code smells, and style guide violations. They are especially useful for catching minor issues, like inconsistent formatting or unused variables. We will discuss ESLint more in an upcoming section.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Example: Run ESLint on a JavaScript project</span>
npx eslint src/
</code></pre>
<h4 id="heading-2-static-analysis-tools-like-sonarqube"><strong>2. Static Analysis Tools (like SonarQube)</strong></h4>
<p>These tools analyze code for deeper issues like security vulnerabilities, code duplication, and complex functions that might need refactoring.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Configuring SonarQube to scan a project</span>
sonar.projectKey=my_project
sonar.sources=src
sonar.host.url=http://localhost:9000
sonar.login=my_token
</code></pre>
<h4 id="heading-3-automated-testing-tools"><strong>3. Automated Testing Tools</strong></h4>
<p>Running tests can verify that code changes don’t introduce new bugs. Use testing frameworks like Jest for JavaScript, PyTest for Python, or JUnit for Java to confirm your code behaves as expected.</p>
<h3 id="heading-example-of-refactoring-during-code-review">Example of Refactoring During Code Review</h3>
<p>Let’s say you encounter a long function with multiple responsibilities. The goal is to split it into smaller, focused functions. Here’s how you can do that:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Original: A single function that handles everything</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processOrder</span>(<span class="hljs-params">order</span>) </span>{
    <span class="hljs-comment">// Calculate total price</span>
    <span class="hljs-keyword">let</span> total = <span class="hljs-number">0</span>;
    order.items.forEach(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> {
        total += item.price * item.quantity;
    });

    <span class="hljs-comment">// Apply discount</span>
    <span class="hljs-keyword">if</span> (order.discountCode) {
        total = total * <span class="hljs-number">0.9</span>; <span class="hljs-comment">// 10% discount</span>
    }

    <span class="hljs-comment">// Send order confirmation email</span>
    sendEmail(order.customerEmail, <span class="hljs-string">'Order Confirmation'</span>, <span class="hljs-string">'Your order total is '</span> + total);
}

<span class="hljs-comment">// Improved: Break into smaller functions for readability and reusability</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateTotal</span>(<span class="hljs-params">order</span>) </span>{
    <span class="hljs-keyword">return</span> order.items.reduce(<span class="hljs-function">(<span class="hljs-params">sum, item</span>) =&gt;</span> sum + item.price * item.quantity, <span class="hljs-number">0</span>);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">applyDiscount</span>(<span class="hljs-params">total, discountCode</span>) </span>{
    <span class="hljs-keyword">return</span> discountCode ? total * <span class="hljs-number">0.9</span> : total;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sendConfirmationEmail</span>(<span class="hljs-params">email, total</span>) </span>{
    sendEmail(email, <span class="hljs-string">'Order Confirmation'</span>, <span class="hljs-string">'Your order total is '</span> + total);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processOrder</span>(<span class="hljs-params">order</span>) </span>{
    <span class="hljs-keyword">let</span> total = calculateTotal(order);
    total = applyDiscount(total, order.discountCode);
    sendConfirmationEmail(order.customerEmail, total);
}
</code></pre>
<p>Breaking down the process into smaller functions makes the code cleaner, more readable, and easier to test. Each function now has a single responsibility, which helps reduce bugs and makes future updates simpler.</p>
<h2 id="heading-how-to-identify-technical-debt-and-problem-areas-in-code">How to Identify Technical Debt and Problem Areas in Code</h2>
<p>Technical debt refers to the accumulation of issues within a codebase that arise when development shortcuts are taken, often to meet tight deadlines or speed up releases. While these shortcuts may enable quicker progress initially, they lead to complications down the line.</p>
<p>Technical debt requires proactive management. If you leave it unchecked, it can reduce productivity, create bugs, and slow down development.</p>
<p>Think of technical debt like financial debt: taking on debt can be helpful in the short term, but failing to address it or pay it down will lead to greater challenges.</p>
<p>Common causes of technical debt include:</p>
<ul>
<li><p><strong>Rushed development cycles:</strong> When teams prioritize quick delivery over thorough design and testing, they may produce incomplete or hastily written code.</p>
</li>
<li><p><strong>Lack of planning for future changes:</strong> Sometimes, code is written without accounting for scalability, leading to issues as the project grows.</p>
</li>
<li><p><strong>Insufficient documentation or testing:</strong> Without proper documentation and test coverage, codebases become difficult to understand and validate over time.</p>
</li>
<li><p><strong>Outdated frameworks and dependencies:</strong> When frameworks or libraries aren’t updated, they can become incompatible with newer components or security standards, introducing risk and hindering future updates.</p>
</li>
</ul>
<h3 id="heading-types-of-technical-debt">Types of Technical Debt</h3>
<p>Technical debt manifests in different ways. Here are some common examples:</p>
<p><strong>1. Code Duplication:</strong></p>
<p>Repeated code across multiple places within a project can lead to inconsistencies, as fixing an issue or updating a feature in one area may not carry over to others. Refactoring duplicate code into reusable functions or components is an effective way to reduce this debt.</p>
<p><strong>Example:</strong> In a web application, you might find similar code for user authentication scattered across different modules. Instead, centralizing this logic into a single authentication module ensures consistent updates.</p>
<p><strong>2. Outdated Dependencies and Frameworks:</strong></p>
<p>Using old libraries or frameworks can slow down development and introduce security vulnerabilities. Over time, dependencies may lose support or become incompatible with new features, making them costly to maintain.</p>
<p><strong>Solution:</strong> Regularly update libraries and frameworks, and monitor for deprecations or vulnerabilities. This can be streamlined by using dependency managers, which help check for updates and security patches.</p>
<p><strong>3. Complex, Long Functions with Multiple Responsibilities:</strong></p>
<p>Large, complex functions that handle multiple tasks are difficult to understand, test, and modify. Known as “God functions,” these make debugging cumbersome and increase the risk of introducing new bugs.</p>
<p><strong>Solution:</strong> Follow the <strong>Single Responsibility Principle (SRP)</strong>. This means that each function or method should accomplish one task. Breaking down large functions into smaller, focused units makes the code easier to read and test.</p>
<p><strong>Example:</strong> Instead of having a single <code>processUserRequest</code> function that handles authentication, logging, and database queries, split it into three functions: <code>authenticateUser</code>, <code>logRequest</code>, and <code>queryDatabase</code>.</p>
<p><strong>4. Insufficient Error Handling:</strong></p>
<p>Code that lacks proper error handling can lead to bugs and unexpected behavior, especially in larger systems. Without clear error messages, diagnosing and fixing issues can be challenging.</p>
<p><strong>Solution:</strong> Include comprehensive error handling and ensure that meaningful error messages are displayed. Log errors in a way that helps developers track and diagnose issues.</p>
<p><strong>5. Hardcoded Values:</strong></p>
<p>Hardcoding values directly into code makes it difficult to adjust settings without modifying the source code. For example, using fixed URLs or credentials directly in the codebase can create security risks and maintenance headaches.</p>
<p><strong>Solution:</strong> Use configuration files or environment variables to store values that might change. This improves security and allows for easy updates.</p>
<p><strong>6. Lack of Documentation and Testing:</strong></p>
<p>Documentation and testing are often neglected when time is short. But without proper documentation and test coverage, the code becomes challenging to understand and validate, slowing down development and increasing the risk of bugs.</p>
<p><strong>Solution:</strong> Implement test-driven development (TDD) or include time in the development cycle for creating documentation and writing tests. Aim for at least basic test coverage for critical paths and functions.</p>
<h3 id="heading-how-to-identify-and-manage-technical-debt">How to Identify and Manage Technical Debt</h3>
<p>Identifying technical debt is crucial if you want to address and improve it. Here are some strategies you can follow:</p>
<ol>
<li><p><strong>Code Reviews:</strong> Regular peer reviews help uncover areas of potential debt. In reviews, team members can flag complex code, lack of tests, or unclear logic, helping address these issues early.</p>
</li>
<li><p><strong>Automated Static Code Analysis:</strong> Tools like SonarQube, Code Climate, and ESLint (for JavaScript) analyze codebases for code smells, vulnerabilities, and complexity. They’re effective for spotting issues like duplicate code, long functions, and outdated dependencies.</p>
</li>
<li><p><strong>Regular Refactoring Sessions:</strong> Scheduling dedicated time for refactoring allows the team to improve existing code quality. During these sessions, focus on simplifying code, breaking down large functions, and removing duplicates.</p>
</li>
<li><p><strong>Technical Debt Backlog:</strong> Track technical debt items in a backlog, prioritizing them alongside feature development. This backlog helps balance feature work with debt reduction and keeps everyone aware of existing debt.</p>
</li>
</ol>
<h3 id="heading-how-to-deal-with-technical-debt-in-code">How to Deal with Technical Debt in Code</h3>
<p>Here’s a practical example to demonstrate how refactoring can help address technical debt, specifically by removing code duplication.</p>
<h4 id="heading-example-removing-duplicate-code">Example: Removing Duplicate Code</h4>
<p>Let’s say we have two functions that send different types of emails but use repeated code:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Duplicate code example</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_welcome_email</span>(<span class="hljs-params">user</span>):</span>
    send_email(user.email, <span class="hljs-string">"Welcome!"</span>, <span class="hljs-string">"Thanks for joining!"</span>)

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_password_reset_email</span>(<span class="hljs-params">user</span>):</span>
    send_email(user.email, <span class="hljs-string">"Password Reset"</span>, <span class="hljs-string">"Click here to reset your password."</span>)
</code></pre>
<p>Each function has a similar structure, so refactoring can make the code cleaner and reduce duplication.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Refactored code</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_email_to_user</span>(<span class="hljs-params">user, subject, message</span>):</span>
    send_email(user.email, subject, message)

<span class="hljs-comment"># Use the refactored function</span>
send_email_to_user(new_user, <span class="hljs-string">"Welcome!"</span>, <span class="hljs-string">"Thanks for joining!"</span>)
send_email_to_user(existing_user, <span class="hljs-string">"Password Reset"</span>, <span class="hljs-string">"Click here to reset your password."</span>)
</code></pre>
<p>This example demonstrates how consolidation can reduce repetition and make the code more flexible.</p>
<h3 id="heading-how-to-avoid-technical-debt">How to Avoid Technical Debt</h3>
<p>Proactively managing technical debt helps reduce it over time. Here are ways to avoid accumulating more debt:</p>
<ul>
<li><p><strong>Establish Code Standards:</strong> Create and enforce coding standards within the team. Consistent practices reduce complexity, improve readability, and make it easier to identify issues early.</p>
</li>
<li><p><strong>Refactor Regularly:</strong> Rather than waiting for debt to accumulate, make minor improvements during routine work. A “leave it better than you found it” approach ensures code quality remains high over time.</p>
</li>
<li><p><strong>Encourage Thorough Testing:</strong> Strong test coverage identifies potential problems early, reducing the likelihood of code with hidden issues. Testing tools like Jest for JavaScript or PyTest for Python make it easy to add tests to each function and module.</p>
</li>
<li><p><strong>Plan for Scalability:</strong> Think about future needs when designing code. Avoid shortcuts that might restrict scalability and performance as the application grows.</p>
</li>
<li><p><strong>Limit Workarounds and Temporary Fixes:</strong> If temporary fixes are necessary, document them and prioritize removing them as soon as possible. Keeping track of these “quick fixes” ensures they don’t become long-term issues.</p>
</li>
</ul>
<h2 id="heading-how-to-measure-code-quality-with-code-analysis-tools">How to Measure Code Quality with Code Analysis Tools</h2>
<p>Code quality tools can help you find issues that might not be obvious. They can point out things like unused variables, code that’s hard to read, or security problems. Popular tools include <code>ESLint</code> for <code>JavaScript</code>, <code>Pylint</code> for <code>Python</code>, and <code>SonarQube</code> for different programming languages.</p>
<p>Here’s how to set up a simple code check with ESLint:</p>
<ol>
<li><p><strong>Install ESLint</strong>:</p>
<pre><code class="lang-bash"> npm install eslint --save-dev
</code></pre>
</li>
<li><p><strong>Initialize ESLint</strong>:</p>
<pre><code class="lang-bash"> npx eslint --init
</code></pre>
<p> This command will prompt you to answer a few configuration questions. You can choose your preferred style guide and select a few options about your environment and file format.</p>
</li>
<li><p><strong>Example Code with Issues</strong></p>
<p> Here’s a sample JavaScript file (<code>example.js</code>) with a few common issues:</p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// example.js</span>

 <span class="hljs-keyword">var</span> x = <span class="hljs-number">10</span>;   <span class="hljs-comment">// Unused variable</span>
 <span class="hljs-keyword">let</span> y = <span class="hljs-number">5</span>;
 <span class="hljs-keyword">const</span> z = <span class="hljs-string">'Hello World'</span>

 <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateSum</span>(<span class="hljs-params">a, b</span>) </span>{
     <span class="hljs-keyword">return</span> a + b
 }

 calculateSum(<span class="hljs-number">3</span>, <span class="hljs-number">4</span>);

 <span class="hljs-comment">// Missing semicolon and inconsistent indentation</span>
 <span class="hljs-keyword">if</span>(y &gt; <span class="hljs-number">3</span>){
     <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Y is greater than 3"</span>)
 }
</code></pre>
</li>
<li><p><strong>Run ESLint</strong>:</p>
<pre><code class="lang-bash"> npx eslint example.js
</code></pre>
<p> After running this command, ESLint will analyze <code>example.js</code> and report any issues based on the configured rules.</p>
</li>
<li><p><strong>ESLint Output</strong></p>
<p> ESLint provides detailed feedback about the issues it detects:</p>
<pre><code class="lang-plaintext"> /path/to/example.js
   1:5  warning  'x' is assigned a value but never used          no-unused-vars
   3:12  error    Missing semicolon                               semi
   6:25  error    Missing semicolon                               semi
   10:1  error    Expected indentation of 4 spaces but found 3    indent
   11:26 error    Missing semicolon                               semi

 ✖ 5 problems (4 errors, 1 warning)
</code></pre>
<p> Here’s a breakdown of each issue detected by ESLint:</p>
<ul>
<li><p><strong>Unused Variable</strong>: ESLint identifies that <code>x</code> is declared but never used (<code>no-unused-vars</code> rule).</p>
</li>
<li><p><strong>Missing Semicolons</strong>: ESLint flags lines where semicolons are missing at the end of statements (<code>semi</code> rule).</p>
</li>
<li><p><strong>Inconsistent Indentation</strong>: ESLint notices that line 10 doesn’t follow consistent indentation (<code>indent</code> rule).</p>
</li>
</ul>
</li>
<li><p><strong>Fixing the Code</strong></p>
<p> Based on ESLint’s feedback, here’s the corrected code:</p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// example.js</span>

 <span class="hljs-keyword">let</span> y = <span class="hljs-number">5</span>;
 <span class="hljs-keyword">const</span> z = <span class="hljs-string">'Hello World'</span>;

 <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateSum</span>(<span class="hljs-params">a, b</span>) </span>{
     <span class="hljs-keyword">return</span> a + b;
 }

 calculateSum(<span class="hljs-number">3</span>, <span class="hljs-number">4</span>);

 <span class="hljs-keyword">if</span> (y &gt; <span class="hljs-number">3</span>) {
     <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Y is greater than 3"</span>);
 }
</code></pre>
<ul>
<li><p>We removed the unused variable <code>x</code>.</p>
</li>
<li><p>We added missing semicolons.</p>
</li>
<li><p>And we adjusted indentation for consistent spacing.</p>
</li>
</ul>
</li>
<li><p><strong>Re-run ESLint to Verify Fixes</strong></p>
<p> After making these changes, you can run <code>npx eslint example.js</code> again to confirm that there are no remaining issues. ESLint will return no output if everything is now clean, confirming that the code adheres to the configured standards.</p>
</li>
</ol>
<h3 id="heading-additional-tip-auto-fixing-with-eslint">Additional Tip: Auto-Fixing with ESLint</h3>
<p>ESLint can automatically fix some issues for you. To do this, use the <code>--fix</code> flag:</p>
<pre><code class="lang-bash">npx eslint example.js --fix
</code></pre>
<p>This command will automatically correct issues like indentation, unused variables, and missing semicolons where possible. But it’s important to review the changes to ensure they align with your intended functionality.</p>
<p>Reviewing code, spotting technical debt, and using quality tools help keep the codebase healthy. If you follow these steps, your project will be easier to manage and less likely to break.</p>
<h2 id="heading-ai-tools-to-help-you-improve-your-code">AI Tools to Help You Improve Your Code</h2>
<p>Using AI tools to restructure code makes improving code quality much faster and easier. These tools help find issues, suggest changes, and can even automate some parts of the refactoring process.</p>
<p>I'll share some AI tools that can help you with code analysis, refactoring, and dependency management, based on my own experience and what I've found useful.</p>
<h3 id="heading-best-ai-tools-for-code-restructuring">Best AI Tools for Code Restructuring</h3>
<p>AI-powered tools are becoming more common, and they offer different ways to boost code quality and simplify refactoring. Here are some I've found helpful:</p>
<h4 id="heading-1-github-copilot"><strong>1. GitHub Copilot</strong></h4>
<p>GitHub Copilot is like a coding assistant that provides smart suggestions as you write code. It can complete code snippets, suggest new functions, and help rework existing code to make it more efficient. I’ve found it useful for writing repetitive code blocks or coming up with quick refactorings.</p>
<p>For example, let’s say you need to rewrite a function to be more efficient:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Original function that checks if a number is prime</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">is_prime</span>(<span class="hljs-params">n</span>):</span>
    <span class="hljs-keyword">if</span> n &lt; <span class="hljs-number">2</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">2</span>, n):
        <span class="hljs-keyword">if</span> n % i == <span class="hljs-number">0</span>:
            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
</code></pre>
<p>GitHub Copilot might suggest optimizing the function like this:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Optimized version suggested by Copilot</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">is_prime</span>(<span class="hljs-params">n</span>):</span>
    <span class="hljs-keyword">if</span> n &lt; <span class="hljs-number">2</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">2</span>, int(n**<span class="hljs-number">0.5</span>) + <span class="hljs-number">1</span>):
        <span class="hljs-keyword">if</span> n % i == <span class="hljs-number">0</span>:
            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
</code></pre>
<p>The updated version checks factors only up to the square root of <code>n</code>, making it faster for large numbers.</p>
<h4 id="heading-2-qodogen"><strong>2. QodoGen</strong></h4>
<p>QodoGen provides automated suggestions for refactoring and can detect common code issues, like unused variables or large functions doing too many tasks. It also helps split complex code into smaller, more manageable pieces and can explain sections of the code base or the entire codebase which will facilitate the restructuring process.</p>
<p>This tool is capable of doing this because, unlike other AI assistants and general purpose code generation tools, Qodo focuses on code integrity, while generating tests that help you understand how your code behaves. This can help you discover edge cases and suspicious behaviors, and make your code more robust.</p>
<p>For example, if you have a function handling multiple tasks, QodoGen might suggest breaking it down:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Before refactoring</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">handle_user_data</span>(<span class="hljs-params">user_data</span>):</span>
    validate_data(user_data)
    save_to_database(user_data)
    send_welcome_email(user_data)

<span class="hljs-comment"># After refactoring</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">handle_user_data</span>(<span class="hljs-params">user_data</span>):</span>
    validated_data = validate_data(user_data)
    save_data(validated_data)
    notify_user(validated_data)
</code></pre>
<p>Separating the steps makes the code easier to maintain and test.</p>
<h4 id="heading-3-chatgpt-for-code-assistance"><strong>3. ChatGPT for Code Assistance</strong></h4>
<p>ChatGPT can act as a helpful companion when working on code restructuring tasks. Arguably the most used coding assistant, it provides advice on refactoring strategies, explains how to implement changes, or offers example snippets. It’s like having an expert to consult whenever you need guidance or ideas.</p>
<p>For instance, if you’re unsure how to optimize a function or restructure a class, ChatGPT can provide sample code or describe best practices. You can also ask it for help with understanding errors or fixing specific problems in your code.</p>
<p>Just make sure you double-check the code it provides (same goes for all these AI assistants) as it can hallucinate and make mistakes.</p>
<h3 id="heading-automated-tools-for-refactoring-and-analysis">Automated Tools for Refactoring and Analysis</h3>
<p>AI tools not only assist with writing code but also with analyzing it for quality improvements:</p>
<h4 id="heading-1-sonarqube"><strong>1. SonarQube</strong></h4>
<p>SonarQube scans the code to detect bugs, vulnerabilities, and code smells. It generates reports with suggestions on what to fix, helping maintain a healthy codebase.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Sample SonarQube configuration</span>
sonar.projectKey=my_project
sonar.sources=src
sonar.host.url=http://localhost:9000
sonar.login=my_token
</code></pre>
<h4 id="heading-2-resharper"><strong>2. ReSharper</strong></h4>
<p>This tool integrates with Visual Studio and offers automatic refactoring options. It highlights code that can be simplified or cleaned up and suggests ways to optimize the codebase.</p>
<h4 id="heading-3-depcheck-for-dependency-management"><strong>3. DepCheck for Dependency Management</strong></h4>
<p>AI tools like DepCheck help find unused dependencies in JavaScript projects, keeping package files clean.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Running DepCheck to find unused dependencies</span>
npx depcheck
</code></pre>
<h3 id="heading-how-these-tools-help-with-code-restructuring">How These Tools Help with Code Restructuring</h3>
<p>Using AI tools like GitHub Copilot, QodoGen, and ChatGPT speeds up the process of code restructuring. They provide suggestions that save time and catch issues early, making the code easier to maintain.</p>
<p>Combining these tools with automated analysis tools like SonarQube and ReSharper ensures all aspects of the codebase are covered, from quality checks to refactoring.</p>
<p>These AI tools have other features that facilitate this process: for example, they all have a chat feature that lets you ask questions and get replies about your code and any best practices you should be following. Also, QodoGen allows you to add parts of or the whole codebase for context with the click of a button, along with other features for test generation and pull request reviews.</p>
<p>When restructuring your codebase, having a variety of AI tools can make the process smoother and more efficient. This is AI usage at its best.</p>
<h2 id="heading-version-control-best-practices-for-code-changes">Version Control Best Practices for Code Changes</h2>
<p>Version control keeps track of code changes, making it easier to manage updates, collaborate with others, and fix issues. Following some best practices can help maintain a clean and organized codebase.</p>
<p>Let’s look at how to manage code changes, track updates, and ensure quality through code reviews.</p>
<h3 id="heading-using-git-branching-strategies-to-manage-code-changes">Using Git Branching Strategies to Manage Code Changes</h3>
<p>Git branching helps keep different versions of the code separate, allowing multiple developers to work without affecting the main codebase. Here are some common strategies:</p>
<h4 id="heading-1-feature-branching"><strong>1. Feature Branching</strong></h4>
<p>Feature branches allow developers to work on a new feature without changing the main codebase. Each feature gets its own branch, and once complete, it can be merged into the main branch.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Creating a new feature branch</span>
git checkout -b feature/new-login-page

<span class="hljs-comment"># Working on the new feature and then committing changes</span>
git add .
git commit -m <span class="hljs-string">"Added login page UI"</span>

<span class="hljs-comment"># Merging the feature branch into the main branch</span>
git checkout main
git merge feature/new-login-page
</code></pre>
<h4 id="heading-2-gitflow-strategy"><strong>2. GitFlow Strategy</strong></h4>
<p>This strategy involves using multiple branches for different stages of development, such as feature, develop, and release. It separates development work and allows smoother integration and deployment.</p>
<ul>
<li><p><strong>Main Branch</strong>: Contains production-ready code.</p>
</li>
<li><p><strong>Develop Branch</strong>: Holds the latest completed work, ready for the next release.</p>
</li>
<li><p><strong>Feature Branches</strong>: Created from the develop branch for new features.</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Switch to the develop branch</span>
git checkout develop

<span class="hljs-comment"># Create a new branch for a feature</span>
git checkout -b feature/upgrade-search

<span class="hljs-comment"># Commit changes and push the feature branch</span>
git add .
git commit -m <span class="hljs-string">"Improved search feature"</span>
git push origin feature/upgrade-search
</code></pre>
<h3 id="heading-how-to-track-and-document-code-updates">How to Track and Document Code Updates</h3>
<p>Documenting code changes helps keep the team informed and makes it easier to understand what was done later. Here are some tips for tracking updates:</p>
<h4 id="heading-1-writing-clear-commit-messages"><strong>1. Writing Clear Commit Messages</strong></h4>
<p>Commit messages should explain what was changed and why. A clear message helps others know the purpose of each update.</p>
<p>Example:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Good commit message</span>
git commit -m <span class="hljs-string">"Fixed bug that caused login failure on mobile devices"</span>

<span class="hljs-comment"># Bad commit message</span>
git commit -m <span class="hljs-string">"Fixed bug"</span>
</code></pre>
<h4 id="heading-2-using-tags-to-mark-releases"><strong>2. Using Tags to Mark Releases</strong></h4>
<p>Tags can be used to label important points in the project’s history, such as release versions. This makes it easier to find stable versions of the code.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create a tag for version 1.0</span>
git tag v1.0

<span class="hljs-comment"># Push the tag to the remote repository</span>
git push origin v1.0
</code></pre>
<h4 id="heading-3-creating-and-using-changelogs"><strong>3. Creating and Using Changelogs</strong></h4>
<p>A changelog lists the changes made in each version, helping developers and users see what was updated or fixed.</p>
<p>Example format for a changelog:</p>
<pre><code class="lang-plaintext">## [1.0.1] - 2024-10-01
### Added
- New login feature

### Fixed
- Resolved search issue on homepage

### Changed
- Updated user dashboard layout
</code></pre>
<h3 id="heading-importance-of-code-reviews-in-maintaining-code-quality">Importance of Code Reviews in Maintaining Code Quality</h3>
<p>Code reviews help catch errors, share knowledge, and ensure code stays clean and maintainable. Here are some practices to follow for effective code reviews:</p>
<h4 id="heading-1-keep-code-changes-small"><strong>1. Keep Code Changes Small</strong></h4>
<p>Smaller changes are easier to review, making it more likely to spot mistakes. Large changes can be broken down into smaller parts.</p>
<h4 id="heading-2-use-pull-requests-for-reviews"><strong>2. Use Pull Requests for Reviews</strong></h4>
<p>Pull requests create a space for discussion around changes. Team members can review the changes, suggest improvements, and approve the updates.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Push the feature branch to the remote repository</span>
git push origin feature/new-feature

<span class="hljs-comment"># Create a pull request on GitHub, GitLab, or Bitbucket</span>
</code></pre>
<h4 id="heading-3-provide-constructive-feedback"><strong>3. Provide Constructive Feedback</strong></h4>
<p>Code reviews should aim to improve the code without discouraging the developer. Suggest better ways to solve problems and explain the reasoning.</p>
<p>Example comments during a code review:</p>
<ul>
<li><p>"Consider using a list instead of a dictionary for this data structure, as it simplifies the code."</p>
</li>
<li><p>"This function is doing multiple tasks. It might be clearer if we split it into two separate functions."</p>
</li>
</ul>
<p>Using these practices helps ensure code changes are managed effectively, updates are well-documented, and the quality of the codebase remains high. Regular code reviews and proper branching strategies make it easier for teams to collaborate and keep the project on track.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Reviving and restructuring a codebase can seem like a big task, but taking small, planned steps makes it manageable. Start by checking the current state of the code and making a list of areas that need work. Set clear goals and create a plan to improve the code, step by step.</p>
<p>Using the tools we discussed here can help find issues, suggest changes, and even automate some tasks. Version control practices, such as branching strategies and code reviews, keep changes organized and ensure the quality stays high.</p>
<p>With a solid approach, even the messiest codebase can become clean, efficient, and easier to work with.</p>
<h3 id="heading-resources">Resources</h3>
<ul>
<li><p>AI tools have been developed to assist with the Git branching, Pull Request reviews and approval. Check out <a target="_blank" href="https://dev.to/oluwadamisisamuel1/merge-mastery-elevating-your-pull-request-game-in-open-source-projects-25fo">this article</a> to read more on one of my favorites.</p>
</li>
<li><p>If you want a step by step tutorial on how to revive and refactor your code, check out <a target="_blank" href="https://youtu.be/yMQJUaUtiJo?si=CGd2WBcD117p7lrS">this youtube video</a>.</p>
</li>
<li><p>Check out <a target="_blank" href="https://www.freecodecamp.org/news/best-practices-for-refactoring-code/">this freecodecamp article</a> on code restructuring to dive deeper.</p>
</li>
</ul>
<p>Connect with me on <a target="_blank" href="https://www.linkedin.com/in/samuel-oluwadamisi-01b3a4236/?lipi=urn%3Ali%3Apage%3Ad_flagship3_feed%3BxAUJMbSgQTeDtb7n2d0mQQ%3D%3D">LinkedIn</a>, <a target="_blank" href="https://twitter.com/Data_Steve_">Twitter</a>, and <a target="_blank" href="https://dev.to/dashboard">my peronal blog</a> if you found this helpful.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Git Stash to Efficiently Manage Your Code ]]>
                </title>
                <description>
                    <![CDATA[ Sometimes when you’re coding, you need to leave a particular task incomplete to focus on another task – but you don't want to lose your progress. So what do you do? Fortunately, git stash comes to the rescue. In this article, you’ll learn all about t... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-git-stash-to-manage-code/</link>
                <guid isPermaLink="false">67092ab15a02c36736216d67</guid>
                
                    <category>
                        <![CDATA[ gitpop ]]>
                    </category>
                
                    <category>
                        <![CDATA[ gitapply ]]>
                    </category>
                
                    <category>
                        <![CDATA[ git stash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ code management ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Okoro Emmanuel Nzube ]]>
                </dc:creator>
                <pubDate>Fri, 11 Oct 2024 13:40:01 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1728563160215/147e5b8d-960d-4a90-ad2f-6d71337ac0ce.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Sometimes when you’re coding, you need to leave a particular task incomplete to focus on another task – but you don't want to lose your progress. So what do you do? Fortunately, <code>git stash</code> comes to the rescue.</p>
<p>In this article, you’ll learn all about the <a target="_blank" href="https://git-scm.com/docs/git-stash">git stash</a> command and why it’s important to stash your code. By the end of this article, you will have firsthand knowledge of how to use the <code>git stash</code> command in your projects.</p>
<h3 id="heading-heres-what-well-cover">Here’s what we’ll cover:</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-why-do-we-stash">Why do we stash?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-pros-and-cons-of-using-git-stash">Pros and cons of using git stash</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-a-stash-in-git-step-by-step-guide">How to create a stash in Git (step-by-step guide)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-other-git-stash-commands-like-list-apply-and-pop">Other git stash commands like list, apply, and pop</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-handle-multiple-stashes-in-your-project">How to handle multiple stashes in your project</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-real-use-cases-for-git-stash">Real use cases for git stash</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-why-do-we-stash">Why Do We Stash?</h2>
<p><a target="_blank" href="https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F">Git</a> has provided us with the stash command, which makes our lives easier. The <code>git stash</code> command helps you save a draft of your current task, temporarily giving you time to attend to your new task without losing your progress on the previous task.</p>
<p>There are so many reasons why stashing is important. Here are some of them:</p>
<ul>
<li><p><strong>Resolving Conflicts within a Project</strong>: In a collaboration setting, you, as a developer, get to work with other developers on a particular project. A merge conflict might occur, which might require you to pause your current task to handle the conflict. You can easily stash your current task and focus fully on resolving the merge conflict without having to worry about losing your progress.</p>
</li>
<li><p><strong>Clean Working Environment</strong>: You might want to start up a new task or want to pull a repository into your working environment. With stashing, you can clear your current working environment temporarily, making your work environment clean and ready to perform another task.</p>
</li>
<li><p><strong>Switching branches</strong>: <code>Git stash</code> is very useful in this situation. You might be in the middle of something and it's not ready to be committed, but at that moment, you need to switch branches. With <code>git stash</code>, you can easily move to another branch and perform your other tasks.</p>
</li>
</ul>
<h2 id="heading-pros-and-cons-of-stashing">Pros and Cons of Stashing</h2>
<p>Here are some of the pros (advantages) of using stash:</p>
<ul>
<li><p>It’s easy to use and understand</p>
</li>
<li><p>It helps you save a draft of your current task and focus on another task.</p>
</li>
<li><p>It comes in handy when trying to resolve conflicts like merge conflicts, <code>git fork</code>, and so on when working with other collaborators in a project.</p>
</li>
<li><p>You can reapply your draft file not only on the branch you stashed it from but also on other branches.</p>
</li>
</ul>
<p>As the saying goes "Anything that has an advantage also has a disadvantage". Here are some of the cons (disadvantages) of using stash:</p>
<ul>
<li><p>Stashing can lead to a merge conflict: A merge conflict can occur when reapplying your stashed draft to a branch which already has similar content to the draft, and you’ll need to resolve this manually.</p>
</li>
<li><p>Cluster and Confusion: In a situation where you are working on a huge project with multiple sub-tasks, applying the stash command at various points might lead to a cluster of saved drafts. This can lead to confusion on the particular saved draft you would want to continue working on.</p>
</li>
</ul>
<p>Now that we have seen some of the pros and cons of using <code>git stash</code>, let’s look at how <code>git stash</code> works and how to apply it to our project.</p>
<h2 id="heading-how-git-stash-works">How Git Stash Works</h2>
<p>As we just discussed, <code>git stash</code> helps you save a draft of your current uncommitted changes. Now let's see how this happens using the analogy below.</p>
<p>When you run the <code>git stash</code> command, it puts your tracked file in a box and then removes/hides that box, making the environment/branch clean and free to use for another task. When you apply the stash command to the current branch you are working on, it saves a draft of all tracked files in that branch and reverts that branch to a clean slate.</p>
<p>To explain better, here’s an example:</p>
<p><img src="https://hackmd.io/_uploads/S1x5zSPhR.gif" alt="Image of How Git Stash Works" width="600" height="400" loading="lazy"></p>
<p>From the image above, we created a new project and already initialized <code>git</code> in it. We are currently on the "main" branch which is the default branch.</p>
<p>If we modify a file in the <code>main</code> branch and apply the <code>git stash</code> command, the modified file will be saved as a draft and your working environment will be reverted to the last commit you made (making it look like there was no modification in the first place).</p>
<p>Note: By default, you can only apply the stash command to tracked files in <code>git</code>.</p>
<h3 id="heading-how-to-create-a-stash">How to Create a Stash</h3>
<p>Here is how you can go about creating a stash in your project.</p>
<p>Create a file you want to work on, maybe an <code>index.html</code> file or a <code>style.css</code> file. Initialize <code>git</code> in your project by running the command <code>git init</code>. Add the file to the Git tracking stage by running <code>git add .</code> Then at this point, if you make any modifications and would like to come back later to complete it, you can run:</p>
<pre><code class="lang-bash">git stash
</code></pre>
<p>Here is a visual representation of the above process:</p>
<p><img src="https://hackmd.io/_uploads/HJg8cHDh0.gif" alt="Visual Representation of How to Create a stash" width="600" height="400" loading="lazy"></p>
<p>There are other stash commands you should know in order to control your stashed project. They include <a target="_blank" href="https://git-scm.com/docs/git-stash#Documentation/git-stash.txt-listltlog-optionsgt">List</a>, <a target="_blank" href="https://git-scm.com/docs/git-stash#Documentation/git-stash.txt-pop--index-q--quietltstashgt">Pop</a>, <a target="_blank" href="https://git-scm.com/docs/git-stash#Documentation/git-stash.txt-clear">Clear</a>, <a target="_blank" href="https://git-scm.com/docs/git-stash#Documentation/git-stash.txt-apply--index-q--quietltstashgt">Apply</a>, <a target="_blank" href="https://git-scm.com/docs/git-stash#Documentation/git-stash.txt-show-u--include-untracked--only-untrackedltdiff-optionsgtltstashgt">Show</a>, and a few others.</p>
<ul>
<li><p><strong>List</strong>: The list command is mainly used to display the number of stashes made in a particular project. Just like an array, the stashed draft is numbered from 0 upwards. To use this command, run <code>git stash list</code>. Note: The stash command is arranged in such a way that when a change is stashed, it takes up the first position i.e."stash@{0}" while the other changes are pushed down.</p>
</li>
<li><p><strong>Pop</strong>: This command is used to retrieve an already stashed draft back into your project. When you apply the pop command, it automatically retrieves the latest stashed draft back into your working project and removes it from the stash list. Run the following command to pop a stash: <code>git stash pop</code>.</p>
</li>
<li><p><strong>Clear</strong>: When applied, this command is used to remove/delete all the stash entries. It is important to note that, when you use the clear command, you can recover the cleared stash again. You can use it by running this command: <code>git stash clear</code>.</p>
</li>
<li><p><strong>Apply</strong>: This command works just like the pop command, but the only difference is that the stashed draft is not removed from the list after it has been retrieved. This means that when you use the apply command, it retrieves the latest stashed draft back into your project but doesn't remove it from the stash list. Run the following to use the apply command: <code>git stash apply</code>.</p>
</li>
<li><p><strong>Show</strong>: This command is important because it helps show you the changes you made in the stashed draft. Use the following command to show a stash: <code>git stash show</code>.</p>
</li>
</ul>
<h2 id="heading-how-to-handle-multiple-stashes-in-your-project">How to Handle Multiple Stashes in Your Project</h2>
<p>Knowing how to handle multiple stashes in your project is important, as there may be times when you have more than 3-4 stashed drafts in your project.</p>
<p>Here is how to handle multiple stashes:</p>
<h3 id="heading-step-one-customize-each-stash-with-a-specific-message">Step One: Customize each stash with a specific message</h3>
<p>This step is very important if you would like to avoid being confused in situations where you have multiple stashes.</p>
<p><img src="https://hackmd.io/_uploads/BkVtICNIA.png" alt="Multiple stashes with the Same messages" width="600" height="400" loading="lazy"></p>
<p>From the image above, we have a total of four stashes (that is, "stash@{0}" to "stash@{3)") and each stash bears the same message of "first commit". This might be confusing when we might want to pop or apply one of these stashes later in the future.</p>
<p>To sort this issue, all we have to do is assign a specific stash message to the next stash. We can do this by running the following command:</p>
<pre><code class="lang-bash">git stash save <span class="hljs-string">"New message/name goes here"</span>
</code></pre>
<p>Here is how it looks:</p>
<p><img src="https://hackmd.io/_uploads/HJH3IRNLA.png" alt="Multiple stashes with the different messages" width="600" height="400" loading="lazy"></p>
<p>From the image above, you can clearly see the difference between the two latest stashes (that is, "stash@{0}" and "stash@{1}") and the others. The first two stashes have their own specific message, which makes it very easy to differentiate them from the rest.</p>
<h3 id="heading-step-two-retrieve-a-specific-stash-instead-of-the-latest-stash">Step Two: Retrieve a specific stash instead of the latest stash</h3>
<p>There are situations when you might want to retrieve a specific stashed draft rather than the latest stashed draft you just made. You can do this by using either:</p>
<pre><code class="lang-bash">git stash pop stash@{n}
</code></pre>
<p>or</p>
<pre><code class="lang-bash">git stash apply stash@{n}
</code></pre>
<p>Where <code>n</code> indicates the stash ID you want to retrieve. This also works when you want to delete or clear a specific stashed draft.</p>
<h3 id="heading-step-three-preview-your-stashed-draft-before-you-retrieve-it">Step Three: Preview your stashed draft before you retrieve it.</h3>
<p>Before you restore a stashed draft, it is important to preview it to ensure that it's the exact draft you want to restore. The <code>show</code> command helps you review the changes in the draft before restoring it. To do this, run the following command:</p>
<pre><code class="lang-bash">git stash show stash@{n}
</code></pre>
<h2 id="heading-real-use-cases-for-git-stash">Real Use Cases for <code>git stash</code></h2>
<p>Here are some real-life case scenarios of when the git stash command is important.</p>
<ul>
<li><p><strong>During Debugging</strong>: This happens a lot when you are in a collaboration setting. Let's say you are working with extra two developers on a project and one of them happens to encounter an error that needs your urgent attention. Using the <code>git stash</code> command is ideal in this situation.</p>
</li>
<li><p><strong>When you are not ready to Commit</strong>: This occurs often. There are situations where you are not ready to commit your changes to the repository. Stashing those changes is the best next step.</p>
</li>
<li><p><strong>Returning the directory to its original state</strong>: Returning the directory to its original state simply means cleaning out all changes made to the directory and making it look as if nothing was done to it. The <code>git stash</code> command helps you achieve this.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The <code>git stash</code> command effortlessly helps you manage your project properly whether you are working alone or you’re in a collaboration setting.</p>
<p>This tool is vital to every developer who wants to flow freely and effortlessly while working on a project.</p>
<p>At this point, I believe you know what <code>git stash</code> is all about, why it is important and how to make use of it in your project.</p>
<p>Thank you for reading.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Start Your Open Source Journey: A Beginner's Guide to Contributing ]]>
                </title>
                <description>
                    <![CDATA[ Open source software has become the backbone of modern technology, powering everything from small startups to giant corporations. Contributing to open source projects is not just a way to give back to the community – it's also an excellent opportunit... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-start-your-open-source-journey-beginners-guide/</link>
                <guid isPermaLink="false">66feb1cb585b533e05ec318d</guid>
                
                    <category>
                        <![CDATA[ Open Source ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ open source ]]>
                    </category>
                
                    <category>
                        <![CDATA[ opensource ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Sahil ]]>
                </dc:creator>
                <pubDate>Thu, 03 Oct 2024 15:01:31 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727909892455/221e81fb-d41d-463a-a1fa-d5ef2d316eaf.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Open source software has become the backbone of modern technology, powering everything from small startups to giant corporations.</p>
<p>Contributing to open source projects is not just a way to give back to the community – it's also an excellent opportunity to enhance your skills, build your portfolio, and connect with like-minded developers from around the world.</p>
<p>But for many beginners, the prospect of contributing to open source can be daunting. Common barriers include not knowing where to start, fear of making mistakes, or feeling intimidated by complex codebases.</p>
<p>This guide aims to break down these barriers and provide you with a clear path to making your first open source contribution.</p>
<h3 id="heading-what-well-cover">What we’ll cover:</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-understanding-open-source">Understanding Open Source</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-prepare-for-your-first-contribution">How to Prepare for Your First Contribution</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-find-the-right-open-source-project">How to Find the Right Open Source Project</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-understand-the-project-guidelines">Understand the Project Guidelines</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-make-your-first-contribution">How to Make Your First Contribution</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-best-practices-for-open-source-contribution">Best Practices for Open Source Contribution</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-practical-tools-for-getting-started">Practical Tools for Getting Started</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-continuing-your-open-source-journey">Continuing Your Open Source Journey</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-understanding-open-source">Understanding Open Source</h2>
<h3 id="heading-what-is-open-source">What is open source?</h3>
<p>Open source refers to software whose source code is freely available for anyone to view, modify, and distribute. This collaborative approach to software development has led to the creation of many powerful tools and platforms we use daily, such as Linux, WordPress, and TensorFlow.</p>
<h3 id="heading-benefits-of-contributing-to-open-source-projects">Benefits of contributing to open source projects</h3>
<p>Contributing to open source projects offers numerous advantages for developers. It's an excellent way to improve your skills, exposing you to diverse coding styles and best practices. Your contributions can also help you build a strong portfolio, providing tangible proof of your abilities to potential employers.</p>
<p>The open source community offers valuable networking opportunities, connecting you with developers worldwide and potentially leading to job opportunities or mentorships. By contributing, you also give back to the community, helping improve tools that you and others rely on daily.</p>
<p>Lastly, you gain insights into project management, learning how large-scale software projects are coordinated and maintained. These benefits collectively enhance your technical skills, career prospects, and understanding of the software development ecosystem.</p>
<h2 id="heading-how-to-prepare-for-your-first-contribution">How to Prepare for Your First Contribution</h2>
<h3 id="heading-set-up-your-development-environment">Set up your development environment</h3>
<ol>
<li><p>Choose a code editor or IDE (Integrated Development Environment) that you're comfortable with. Popular options include Visual Studio Code, Sublime Text, or JetBrains IDEs.</p>
</li>
<li><p>Install Git on your computer. Git is the most widely used version control system in open source projects.</p>
</li>
</ol>
<h3 id="heading-learn-version-control-basics-git">Learn version control basics (Git):</h3>
<p>Understanding Git is crucial for contributing to open source. Here are some key concepts to start with:</p>
<ul>
<li><p>Repository: A project's folder containing all files and version history.</p>
</li>
<li><p>Clone: Creating a local copy of a repository on your machine.</p>
</li>
<li><p>Branch: A separate line of development for new features or bug fixes.</p>
</li>
<li><p>Commit: Saving changes to your local repository.</p>
</li>
<li><p>Push: Uploading your local changes to the remote repository.</p>
</li>
<li><p>Pull Request: Proposing your changes to be merged into the main project.</p>
</li>
</ul>
<p>Take some time to practice these concepts on a personal project before diving into open source contributions.</p>
<h2 id="heading-how-to-find-the-right-open-source-project">How to Find the Right Open Source Project</h2>
<h3 id="heading-identify-your-skills-and-interests">Identify your skills and interests:</h3>
<p>Start by listing your skills (programming languages, frameworks, design, documentation) and areas of interest. This will help you find projects that align with your abilities and passions.</p>
<h3 id="heading-explore-resources-for-finding-projects">Explore resources for finding projects:</h3>
<p>While we'll introduce some specific tools later in this guide, here are some general platforms you can explore to find open source projects:</p>
<ol>
<li><p>GitHub's "Explore" section</p>
</li>
<li><p>CodeTriage</p>
</li>
<li><p>Up For Grabs</p>
</li>
<li><p>First Timers Only</p>
</li>
<li><p>Your favorite software's repository (look for "good first issue" labels)</p>
</li>
</ol>
<p>Remember, the key is to find a project you're genuinely interested in, as this will keep you motivated throughout the contribution process.</p>
<h2 id="heading-understand-the-project-guidelines">Understand the Project Guidelines</h2>
<p>Before you start contributing to an open source project, it's crucial to understand the project's guidelines. These guidelines are typically found in files like <a target="_blank" href="http://CONTRIBUTING.md">CONTRIBUTING.md</a>, CODE_OF_<a target="_blank" href="http://CONDUCT.md">CONDUCT.md</a>, or in the project's README file.</p>
<h3 id="heading-read-the-contribution-guidelines">Read the Contribution Guidelines</h3>
<p>The <a target="_blank" href="http://CONTRIBUTING.md">CONTRIBUTING.md</a> file is your roadmap to becoming a valuable contributor. It usually contains information on:</p>
<ul>
<li><p>How to set up the project locally</p>
</li>
<li><p>The process for submitting contributions</p>
</li>
<li><p>Coding standards and style guides</p>
</li>
<li><p>How to report bugs or suggest new features</p>
</li>
<li><p>Communication channels for the project</p>
</li>
</ul>
<p>For example, the popular open source library React has a comprehensive <a target="_blank" href="https://github.com/facebook/react/blob/main/CONTRIBUTING.md">CONTRIBUTING.md</a> file. It includes sections on:</p>
<ul>
<li><p>Code of Conduct</p>
</li>
<li><p>Development Workflow</p>
</li>
<li><p>Bugs</p>
</li>
<li><p>Proposing a Change</p>
</li>
<li><p>Sending a Pull Request</p>
</li>
</ul>
<h3 id="heading-familiarize-yourself-with-project-structure-and-coding-standards">Familiarize Yourself with Project Structure and Coding Standards</h3>
<p>Take time to understand the project's architecture and file organization. This might involve:</p>
<ol>
<li><p>Exploring the directory structure</p>
</li>
<li><p>Reading documentation on the project's architecture</p>
</li>
<li><p>Reviewing existing code to understand the coding style</p>
</li>
</ol>
<p>Many projects use automated tools to enforce coding standards. For instance, a JavaScript project might use ESLint for code linting. You might see a configuration file like .eslintrc.js in the project root:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-string">"extends"</span>: <span class="hljs-string">"airbnb"</span>,
  <span class="hljs-string">"rules"</span>: {
    <span class="hljs-string">"react/jsx-filename-extension"</span>: [<span class="hljs-number">1</span>, { <span class="hljs-string">"extensions"</span>: [<span class="hljs-string">".js"</span>, <span class="hljs-string">".jsx"</span>] }],
    <span class="hljs-string">"no-console"</span>: <span class="hljs-string">"off"</span>
  }
};
</code></pre>
<p>This configuration tells you that the project follows Airbnb's JavaScript style guide with a few custom modifications.</p>
<h2 id="heading-how-to-make-your-first-contribution">How to Make Your First Contribution</h2>
<p>Let's walk through the process of making your first contribution, using a real-life example.</p>
<h3 id="heading-choose-an-issue">Choose an Issue</h3>
<p>Suppose you've found an issue in the repository of a popular markdown editor. The issue is labeled "good first issue" and describes a bug where the preview doesn't update when the user types a backtick (`).</p>
<h3 id="heading-communicate-with-project-maintainers">Communicate with Project Maintainers</h3>
<p>Before starting work, you comment on the issue:</p>
<pre><code class="lang-plaintext">Hi there! I'm new to open source and would love to work on this issue. 
Is it still available? I'm thinking of approaching it by modifying the 
event listener for the editor component. Does that sound like a good approach?
</code></pre>
<p>A maintainer responds, welcoming you and confirming your approach.</p>
<h3 id="heading-create-a-fork-and-work-on-your-solution">Create a Fork and Work on Your Solution</h3>
<ol>
<li><p>Fork the repository to your GitHub account.</p>
</li>
<li><p>Clone your fork locally:</p>
<pre><code class="lang-plaintext"> git clone https://github.com/yourusername/markdown-editor.git
</code></pre>
</li>
<li><p>Create a new branch:</p>
<pre><code class="lang-plaintext"> git checkout -b fix-backtick-preview
</code></pre>
</li>
<li><p>Make your changes. For example, you might modify the editor component:</p>
<pre><code class="lang-javascript"> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Editor</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
   handleChange = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
     <span class="hljs-keyword">const</span> { value } = event.target;
     <span class="hljs-built_in">this</span>.props.onChange(value);

     <span class="hljs-comment">// Force update preview on backtick</span>
     <span class="hljs-keyword">if</span> (value.endsWith(<span class="hljs-string">'`'</span>)) {
       <span class="hljs-built_in">this</span>.props.forceUpdatePreview();
     }
   }

   render() {
     <span class="hljs-comment">// ... rest of the component</span>
   }
 }
</code></pre>
</li>
<li><p>Commit your changes:</p>
<pre><code class="lang-plaintext"> git add .
 git commit -m "Fix: Update preview on backtick input"
</code></pre>
</li>
<li><p>Push to your fork:</p>
<pre><code class="lang-plaintext"> git push origin fix-backtick-preview
</code></pre>
</li>
</ol>
<h3 id="heading-submit-a-pull-request">Submit a Pull Request</h3>
<ol>
<li><p>Go to the original repository on GitHub.</p>
</li>
<li><p>Click "New pull request" and select your branch.</p>
</li>
<li><p>Fill in the pull request template:</p>
<pre><code class="lang-markdown"> ## Description
 This PR fixes the issue where the preview doesn't update when a backtick is typed.

 ## Changes
<span class="hljs-bullet"> -</span> Modified the Editor component to force an update when a backtick is entered

 ## Testing
<span class="hljs-bullet"> 1.</span> Open the editor
<span class="hljs-bullet"> 2.</span> Type some text followed by a backtick
<span class="hljs-bullet"> 3.</span> Verify that the preview updates immediately

 Fixes #123
</code></pre>
</li>
<li><p>Submit the pull request and wait for feedback.</p>
</li>
</ol>
<h2 id="heading-best-practices-for-open-source-contribution">Best Practices for Open Source Contribution</h2>
<h3 id="heading-write-clear-commit-messages">Write Clear Commit Messages</h3>
<p>Good commit messages are crucial for project maintainability. Follow these guidelines:</p>
<ul>
<li><p>Use the imperative mood in the subject line</p>
</li>
<li><p>Limit the subject line to 50 characters</p>
</li>
<li><p>Capitalize the subject line</p>
</li>
<li><p>Do not end the subject line with a period</p>
</li>
<li><p>Separate subject from body with a blank line</p>
</li>
<li><p>Wrap the body at 72 characters</p>
</li>
<li><p>Use the body to explain what and why vs. how</p>
</li>
</ul>
<p>Example of a good commit message:</p>
<pre><code class="lang-plaintext">Fix race condition in connection pool

- Add mutex lock when accessing shared resource
- Implement retry mechanism for failed connections

This change prevents multiple threads from accessing the connection
pool simultaneously, which was causing occasional crashes in high
load scenarios. The retry mechanism improves resilience to temporary
network issues.
</code></pre>
<h3 id="heading-document-your-changes">Document Your Changes</h3>
<p>Clear documentation is as important as good code. Here are some best practices:</p>
<ol>
<li><p>Update relevant README files</p>
</li>
<li><p>Add inline comments for complex logic</p>
</li>
<li><p>Update or create API documentation for new features</p>
</li>
</ol>
<p>For example, if you've added a new function to a Python library:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">validate_email</span>(<span class="hljs-params">email: str</span>) -&gt; bool:</span>
    <span class="hljs-string">"""
    Validate an email address.

    Args:
        email (str): The email address to validate.

    Returns:
        bool: True if the email is valid, False otherwise.

    Example:
        &gt;&gt;&gt; validate_email("user@example.com")
        True
        &gt;&gt;&gt; validate_email("invalid-email")
        False
    """</span>
    <span class="hljs-comment"># Implementation details...</span>
</code></pre>
<h3 id="heading-respond-to-feedback">Respond to Feedback</h3>
<p>When you receive feedback on your pull request:</p>
<ol>
<li><p>Respond promptly and politely</p>
</li>
<li><p>Address all comments, even if just to acknowledge them</p>
</li>
<li><p>If you disagree with a suggestion, explain your reasoning respectfully</p>
</li>
<li><p>Make requested changes and update your pull request</p>
</li>
</ol>
<p>For example:</p>
<p>Reviewer: "Could you add a unit test for the new validate_email function?"</p>
<p>You: "Absolutely, that's a great suggestion. I'll add a comprehensive test suite for various email formats and edge cases. I'll push the changes shortly."</p>
<h2 id="heading-practical-tools-for-getting-started">Practical Tools for Getting Started</h2>
<h3 id="heading-git-begin-your-gateway-to-open-source-contributions">Git Begin: Your Gateway to Open Source Contributions</h3>
<p>To help you take your first steps in open source, I’ve developed Git Begin, a free web application designed to make finding your first contribution opportunity as easy as possible.</p>
<h4 id="heading-how-git-begin-works">How Git Begin works:</h4>
<ol>
<li><p>Visit <a target="_blank" href="https://gitbegin.theenthusiast.dev">Git Begin</a></p>
</li>
<li><p>Select your preferred programming language or framework from the options provided.</p>
</li>
<li><p>Browse through a curated list of issues tagged as "good first issue" or "beginner-friendly" across various open source projects.</p>
</li>
<li><p>Each issue is presented with key information such as the project name, issue description, and required skills.</p>
</li>
<li><p>When you find an issue that interests you, click on it to be directed to the original issue on GitHub.</p>
</li>
</ol>
<p>Git Begin eliminates the overwhelming process of searching through countless repositories. It presents you with targeted, beginner-friendly opportunities that match your skills and interests, making it easier than ever to start your open source journey.</p>
<h3 id="heading-a-real-world-project-for-first-time-contributors">A Real-World Project for First-Time Contributors</h3>
<p>In addition to Git Begin, I’m excited to introduce you to another free, open-source project designed specifically for beginners to practice their skills and make meaningful contributions:</p>
<ul>
<li><p>Project: Job Scraper</p>
</li>
<li><p>Description: A tool for scraping job listings from multiple company career pages</p>
</li>
<li><p>Repository: <a target="_blank" href="https://github.com/The-Enthusiast-404/career-craft-scrapper">https://github.com/The-Enthusiast-404/career-craft-scrapper</a></p>
</li>
</ul>
<h4 id="heading-about-the-project">About the project:</h4>
<p>This Job Scraper project is a crucial component of a larger, ambitious platform I’m helping develop that will revolutionize the job-seeking process. This free platform aims to be a comprehensive resource for job seekers, offering a range of tools to streamline their job search and application process.</p>
<p>The Job Scraper itself aggregates job listings from various company career pages, forming the foundation of our platform. But that's just the beginning. Our vision extends to creating a full-fledged ecosystem that will include:</p>
<ol>
<li><p>A centralized job application system, allowing users to apply to multiple positions across different companies seamlessly.</p>
</li>
<li><p>AI-powered resume creation tools to help job seekers craft compelling CVs tailored to their target roles.</p>
</li>
<li><p>An innovative AI mock interviewer, capable of simulating interviews for specific roles and tech stacks, helping candidates prepare more effectively.</p>
</li>
</ol>
<p>By contributing to the Job Scraper project, you're not only gaining valuable experience in web scraping and data processing but also playing a part in building a platform that will make a real difference in people's careers.</p>
<p>It's an opportunity to work on a project with immediate practical applications while also contributing to a larger vision of making job seeking more accessible and efficient for everyone.</p>
<p>As an open source contributor, you'll have the chance to work on various aspects of this system, from improving the scraping algorithms to potentially helping develop some of the AI-powered features in the future.</p>
<p>This project offers a unique blend of practical coding experience and the satisfaction of working on a tool that will directly impact job seekers worldwide.</p>
<h4 id="heading-current-contribution-opportunities">Current contribution opportunities:</h4>
<p>There are a number of "good first issues" available, all focused on web scraping tasks. These might include:</p>
<ul>
<li><p>Adding support for scraping job listings from a new company's career page</p>
</li>
<li><p>Improving the data cleaning process for a specific job site</p>
</li>
<li><p>Enhancing the scraper's resilience against changes in a website's structure</p>
</li>
</ul>
<p>Each issue is carefully documented to help newcomers understand the task and its context within the larger project.</p>
<h4 id="heading-first-steps-in-open-source">First Steps in Open Source</h4>
<p>The Job Scraper project has become a welcoming entry point for many developers making their first open source contributions. To date, we've had several contributors who chose the repository for their first pull request, most of them being students eager to gain real-world experience.</p>
<p>These newcomers to open source have successfully added new scraping functionalities, improved existing algorithms, and enhanced our data processing capabilities.</p>
<p>Their achievements demonstrate that our repository is an ideal starting point for anyone looking to begin their open source journey, especially students wanting to apply their skills to a practical project.</p>
<h4 id="heading-how-to-get-involved">How to get involved:</h4>
<ol>
<li><p>Visit the repository: <a target="_blank" href="https://github.com/The-Enthusiast-404/career-craft-scrapper">https://github.com/The-Enthusiast-404/career-craft-scrapper</a></p>
</li>
<li><p>Read through the README and <a target="_blank" href="http://CONTRIBUTING.md">CONTRIBUTING.md</a> files to understand the project and contribution guidelines</p>
</li>
<li><p>Browse the open issues labeled "good first issue"</p>
</li>
<li><p>Comment on an issue you'd like to work on, and I will guide you through the next steps</p>
</li>
</ol>
<p>Remember, both Git Begin and the Job Scraper project are completely free resources. We're committed to providing a supportive environment for developers to learn and grow in their open source journey.</p>
<h2 id="heading-continuing-your-open-source-journey">Continuing Your Open Source Journey</h2>
<h3 id="heading-building-on-your-first-contribution">Building on your first contribution:</h3>
<p>After making your first contribution, take some time to reflect on what you've learned. Consider:</p>
<ul>
<li><p>What aspects of the process did you find challenging?</p>
</li>
<li><p>What new skills or knowledge did you gain?</p>
</li>
<li><p>How can you apply this experience to future contributions?</p>
</li>
</ul>
<p>Use these insights to guide your next steps in open source.</p>
<h3 id="heading-become-a-regular-contributor">Become a regular contributor:</h3>
<p>To become a regular contributor:</p>
<ol>
<li><p>Set up project notifications to stay informed about new issues and discussions.</p>
</li>
<li><p>Participate in project discussions, offering insights or asking questions.</p>
</li>
<li><p>Take on increasingly complex issues as you become more familiar with the project.</p>
</li>
<li><p>Help other newcomers by answering questions or reviewing their pull requests.</p>
</li>
<li><p>Consider contributing to documentation or writing tests, which are often overlooked but crucial aspects of open source projects.</p>
</li>
</ol>
<h3 id="heading-explore-new-projects">Explore new projects:</h3>
<p>As you gain confidence, don't hesitate to explore new projects:</p>
<ol>
<li><p>Look for projects in different domains to broaden your skills.</p>
</li>
<li><p>Consider contributing to tools or libraries you use in your daily work.</p>
</li>
<li><p>Explore projects with different scales - from small utilities to large frameworks.</p>
</li>
</ol>
<p>Remember, each project offers unique learning opportunities and challenges.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Contributing to open source can be an incredibly rewarding experience. It allows you to improve your coding skills, collaborate with developers worldwide, and make a meaningful impact on projects used by millions of people.</p>
<p>Remember, everyone starts somewhere. Don't be afraid to make mistakes – they're part of the learning process. The open source community is generally welcoming and supportive of newcomers.</p>
<p>We hope this guide, along with tools like Git Begin and our Job Scraper project, will help you take your first steps into the world of open source contribution. Happy coding, and we look forward to seeing your contributions!</p>
<h4 id="heading-resources">Resources:</h4>
<ul>
<li><p>Git Begin: <a target="_blank" href="https://gitbegin.theenthusiast.dev">https://gitbegin.theenthusiast.dev</a></p>
</li>
<li><p>Job Scraper Project: <a target="_blank" href="https://github.com/The-Enthusiast-404/career-craft-scrapper">https://github.com/The-Enthusiast-404/career-craft-scrapper</a></p>
</li>
<li><p>Git Documentation: <a target="_blank" href="https://git-scm.com/doc">https://git-scm.com/doc</a></p>
</li>
<li><p>GitHub Guides: <a target="_blank" href="https://guides.github.com/">https://guides.github.com/</a></p>
</li>
<li><p>Open Source Guide: <a target="_blank" href="https://opensource.guide/">https://opensource.guide/</a></p>
</li>
</ul>
 ]]>
                </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>
        
            <item>
                <title>
                    <![CDATA[ How to Host Your Project on GitHub – Explained With Examples ]]>
                </title>
                <description>
                    <![CDATA[ Seven years ago, I began my journey into web development with HTML and CSS. As soon as I got the hang of JavaScript, I built my first website. The excitement was overwhelming, and I wanted to share it with my friends and the world. Like many beginner... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/host-your-first-project-on-github/</link>
                <guid isPermaLink="false">66d46156182810487e0ce1be</guid>
                
                    <category>
                        <![CDATA[ deployment ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Hosting ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Spruce Emmanuel ]]>
                </dc:creator>
                <pubDate>Thu, 08 Aug 2024 11:37:16 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/08/Screenshot-2024-08-04-at-11.47.51-PM.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Seven years ago, I began my journey into web development with HTML and CSS. As soon as I got the hang of JavaScript, I built my first website. The excitement was overwhelming, and I wanted to share it with my friends and the world.</p>
<p>Like many beginners, I started researching hosting platforms, only to find out about the cost of domains and hosting. That's when I discovered Git and GitHub, realizing I could share my projects without spending a dime.</p>
<p>If you're in the same boat, unsure about Git and GitHub and how to share your projects, this article is for you. It's the guide I wish I had seven years ago.</p>
<p>To demonstrate the power of Git and GitHub, we'll be using a real-world project as an example. Let's take the "IP Address Tracker application" project from <a target="_blank" href="https://www.freecodecamp.org/news/learn-rest-apis-javascript-project/#practical-example-how-to-build-a-web-application-with-a-public-rest-api">this freeCodeCamp tutorial</a>. You can download the source code for the project <a target="_blank" href="https://github.com/iamspruce/ip-address-tracker/">here</a>.</p>
<p>If you've followed the tutorial and built the project, or if you have a project you'd like to share, this article is for you. We'll walk you through the steps to host your project on GitHub, making it accessible to the world.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-audience">Audience</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-prerequisite-knowledge">Prerequisite Knowledge</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-getting-started-with-git-and-github">Getting Started With Git and GitHub</a></p>
<ol>
<li><p><a class="post-section-overview" href="#heading-what-is-git">What is Git?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-what-is-github">What is GitHub?</a></p>
</li>
</ol>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-git-and-github">How to Set Up Git and GitHub</a></p>
<ol>
<li><p><a class="post-section-overview" href="#heading-how-to-install-git-on-windows">How to Install Git on Windows</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-install-git-on-macos">How to Install Git on macOS</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-install-git-on-linux">How to Install Git on Linux</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-a-github-account">How to Create a GitHub Account</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-configure-git">How to Configure Git</a></p>
</li>
</ol>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-initialize-a-git-repository">How to Initialize a Git Repository</a></p>
<ol>
<li><p><a class="post-section-overview" href="#heading-step-1-download-and-open-your-project">Step 1: Download and Open Your Project</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-open-the-project-in-vs-code">Step 2: Open the Project in VS Code</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-open-the-terminal-in-vs-code">Step 3: Open the Terminal in VS Code</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-4-initialize-a-git-repository">Step 4: Initialize a Git Repository</a></p>
</li>
</ol>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-track-changes-with-git">How to Track Changes with Git</a></p>
<ol>
<li><p><a class="post-section-overview" href="#heading-preparing-changes-with-git-add">Preparing Changes with git add</a></p>
<ol>
<li><p><a class="post-section-overview" href="#heading-adding-individual-files">Adding Individual Files</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-adding-all-changes-at-once">Adding All Changes at Once</a></p>
</li>
</ol>
</li>
<li><p><a class="post-section-overview" href="#heading-saving-changes-with-git-commit">Saving Changes with git commit</a></p>
</li>
</ol>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-push-your-project-to-github">How to Push Your Project to GitHub</a></p>
<ol>
<li><p><a class="post-section-overview" href="#heading-step-1-create-a-new-repository-on-github">Step 1: Create a New Repository on GitHub</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-2-link-your-local-repository-to-github">Step 2: Link Your Local Repository to GitHub</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-3-push-your-local-changes-to-github">Step 3: Push Your Local Changes to GitHub</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-step-4-verify-your-repository-on-github">Step 4: Verify Your Repository on GitHub</a></p>
</li>
</ol>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-host-your-project-on-github-pages">How to Host Your Project on GitHub Pages</a></p>
<ol>
<li><p><a class="post-section-overview" href="#heading-what-are-github-pages">What are GitHub Pages?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-enable-github-pages">How to Enable GitHub Pages</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-get-your-github-pages-url">How to Get Your GitHub Pages URL</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-update-your-github-pages-site">How to Update Your GitHub Pages Site</a></p>
</li>
</ol>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-audience">Audience</h2>
<p>This guide is for beginner developers who have started learning HTML, CSS, and JavaScript and want to learn how to share their projects using Git and GitHub.</p>
<h2 id="heading-prerequisite-knowledge">Prerequisite Knowledge</h2>
<p>Before diving in, ensure you are familiar with:</p>
<ul>
<li><p>Basic command-line operations.</p>
</li>
<li><p>HTML, CSS, and JavaScript fundamentals.</p>
</li>
<li><p>A text editor like VS Code.</p>
</li>
</ul>
<h2 id="heading-getting-started-with-git-and-github">Getting Started With Git and GitHub</h2>
<p>I am not going to try to bore you with the differences between Git and GitHub. I am sure there are tons of resources in the world wide web already covering that but from a beginner's point of view, here is what they are:</p>
<h3 id="heading-what-is-git">What is Git?</h3>
<p>Git is a tool that helps you keep track of all the changes you make in your project's code. Imagine building a website about cats. If you change the website's title from "Cat Facts" to "All About Cats," Git will remember the change. If you later decide that you prefer "Cat Facts," Git lets you go back to that version easily.</p>
<p>It's like having a record of every edit, addition, and deletion you make to your project, so you can always revisit previous versions and make changes with confidence.</p>
<h3 id="heading-what-is-github">What is GitHub?</h3>
<p>GitHub is like a cloud-based scrapbook for your code. It's an online record where you save every edit, addition, and deletion you make to your project, so you can access it from anywhere and share it with others.</p>
<p>Imagine having a digital filing cabinet where you can store and manage different versions of your website. You can invite friends to see and even help you with your project, making it easy to collaborate. GitHub tracks changes and keeps everything organized, so if something goes wrong, you can always go back to a previous version.</p>
<h2 id="heading-how-to-set-up-git-and-github">How to Set Up Git and GitHub</h2>
<p>Now that we know what Git and GitHub are, let's get them set up on your computer. Follow these step-by-step instructions:</p>
<h3 id="heading-how-to-install-git-on-windows">How to Install Git on Windows</h3>
<p>You can download the Git installer <a target="_blank" href="https://git-scm.com/">here</a>.</p>
<p>Run the installer and follow the setup instructions, keeping the default settings.</p>
<h3 id="heading-how-to-install-git-on-macos">How to Install Git on macOS</h3>
<p>Open the Terminal on your Mac. You can find it in Applications &gt; Utilities or use Spotlight to search for it.</p>
<p>Install Git using Homebrew by copying and pasting the following commands:</p>
<pre><code class="lang-bash">/bin/bash -c <span class="hljs-string">"<span class="hljs-subst">$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)</span>"</span>
brew install git
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">==&gt; Downloading https://github.com/Homebrew/brew/tarballs/...
==&gt; Installing git
==&gt; Pouring git-2.43.0.mojave.bottle.tar.gz
🍺  /usr/<span class="hljs-built_in">local</span>/Cellar/git/2.30.1: 1,434 files, 43.8MB
</code></pre>
<h3 id="heading-how-to-install-git-on-linux">How to Install Git on Linux</h3>
<p>Open Terminal on your Linux machine. Then use your distribution's package manager to install Git.</p>
<p>For example, on Ubuntu, copy and paste the following commands:</p>
<pre><code class="lang-bash">sudo apt-get update
sudo apt-get install git
</code></pre>
<p>Output:</p>
<pre><code class="lang-plaintext">Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
git-man liberror-perl
Suggested packages:
git-daemon-run git-daemon-sysvinit git-doc git-el git-email git-gui gitk
gitweb git-mediawiki git-arch git-cvs git-svn git-hg
The following NEW packages will be installed:
git git-man liberror-perl
0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
Need to get 7,841 kB of archives.
After this operation, 43.8 MB of additional disk space will be used.
</code></pre>
<p>To verify the installation, open Terminal (if it's not already open) and type the following command to verify the installation:</p>
<pre><code class="lang-bash">git --version
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">git version 2.43.0
</code></pre>
<p>You should see the installed Git version displayed.</p>
<h3 id="heading-how-to-create-a-github-account">How to Create a GitHub Account</h3>
<ul>
<li><p>Go to <a target="_blank" href="https://github.com/">GitHub</a> and click on "Sign up."</p>
</li>
<li><p>Follow the instructions to create your account, choose a username and password, and verify your email.</p>
</li>
<li><p>Once your account is set up, customize your profile with a bio, profile picture, and links to your personal website or social media.</p>
</li>
</ul>
<h3 id="heading-how-to-configure-git">How to Configure Git</h3>
<p>Open Terminal and configure Git with the same username and email as your GitHub account:</p>
<pre><code class="lang-bash">git config --global user.name <span class="hljs-string">"Your GitHub Username"</span>
git config --global user.email <span class="hljs-string">"your.email@example.com"</span>
</code></pre>
<p>No output will be displayed, but Git will store your credentials for future use.</p>
<h2 id="heading-how-to-initialize-a-git-repository">How to Initialize a Git Repository</h2>
<p>Now that you have Git and GitHub set up, let's start by initializing Git in a project. You can use any project of your choice or follow along with our example using the "IP Address Tracker" project.</p>
<h3 id="heading-step-1-download-and-open-your-project">Step 1: Download and Open Your Project</h3>
<p>Download the source code for your chosen project or use the "IP Address Tracker" project from <a target="_blank" href="https://github.com/iamspruce/ip-address-tracker/">this link</a>. Extract the downloaded ZIP file to a location on your computer. This will provide a concrete example to demonstrate Git concepts.</p>
<h3 id="heading-step-2-open-the-project-in-vs-code">Step 2: Open the Project in VS Code</h3>
<p>Open Visual Studio Code and click on "File" &gt; "Open Folder" to select the folder where you extracted the project.</p>
<h3 id="heading-step-3-open-the-terminal-in-vs-code">Step 3: Open the Terminal in VS Code</h3>
<p>Click on "Terminal" &gt; "New Terminal" to open the terminal in VS Code, where we'll interact with Git using commands.</p>
<h3 id="heading-step-4-initialize-a-git-repository">Step 4: Initialize a Git Repository</h3>
<p>Initialize a Git repository by running the following command:</p>
<pre><code class="lang-bash">git init
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">Initialized empty Git repository <span class="hljs-keyword">in</span> /Users/spruceemmanuel/Documents/IP Address Tracker/.git/
</code></pre>
<p>This command creates a new hidden folder called <strong>.git</strong> in your project folder, which tracks changes to our project files. When you run <code>git init</code>, Git sets up the necessary files and directories to start versioning our project. This includes:</p>
<ul>
<li><p>A <strong>.git</strong> folder that stores all the metadata for your repository</p>
</li>
<li><p>A main branch, which is the default branch for your repository</p>
</li>
<li><p>A HEAD pointer, which points to the current branch (in this case, main).</p>
</li>
</ul>
<p>By initializing a Git repository, you're telling Git to start tracking changes to your project files. This allows you to version your code, collaborate with others, and maintain a record of changes.</p>
<h2 id="heading-how-to-track-changes-with-git">How to Track Changes with Git</h2>
<p>Now that we’ve set up Git, it’s ready to keep track of changes in our project.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/08/Screenshot-2024-08-04-at-11.30.49-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>VSCode source control</em></p>
<p>Git notices change in our files, but before we can save these changes, we need to tell Git to do so.</p>
<h3 id="heading-preparing-changes-with-git-add">Preparing Changes with git add</h3>
<p>To get our changes ready to save, we use the <code>git add</code> command. Here’s how it works:</p>
<h4 id="heading-adding-individual-files">Adding Individual Files</h4>
<p>If you want to add specific files, like index.html, script.js, or styles.css, you can use git add followed by the file name. For example:</p>
<pre><code class="lang-bash">git add index.html
</code></pre>
<h4 id="heading-adding-all-changes-at-once">Adding All Changes at Once</h4>
<p>If you want to add all modified files in the project to the staging area, use:</p>
<pre><code class="lang-bash">git add .
</code></pre>
<h3 id="heading-saving-changes-with-git-commit">Saving Changes with git commit</h3>
<p>Once we’ve used git add, we use git commit to save our changes. Here’s how to do it:</p>
<pre><code class="lang-bash">git commit -m <span class="hljs-string">"Describe your changes here"</span>
</code></pre>
<p>Replace "Describe your changes here" with a brief description of what you’ve changed. For example:</p>
<pre><code class="lang-bash">git commit -m <span class="hljs-string">"Update index.html with new content"</span>
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">[master (root-commit) be9b1cd] Update index.html with new content
3 files changed, 386 insertions(+)
create mode 100644 index.html
create mode 100644 script.js
create mode 100644 styles.css
</code></pre>
<p>By using <code>git add</code> and <code>git commit</code>, you’re instructing Git to track and save specific versions of your project. This helps you manage changes, collaborate with others, and maintain a record of your progress.</p>
<h2 id="heading-how-to-push-your-project-to-github">How to Push Your Project to GitHub</h2>
<p>Now that we have our changes tracked and committed locally, it’s time to upload our project to GitHub so we can share it with the world.</p>
<h3 id="heading-step-1-create-a-new-repository-on-github">Step 1: Create a New Repository on GitHub</h3>
<ul>
<li><p>Go to GitHub and log in to your account.</p>
</li>
<li><p>Click the "+" icon in the upper-right corner and select "New repository."</p>
</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/08/Screenshot-2024-08-04-at-11.36.23-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ul>
<li><p>Fill out the repository name (for example: "ip-address-tracker"), and add a description if you like.</p>
</li>
<li><p>Choose whether you want the repository to be public or private.</p>
</li>
<li><p>Do not initialize the repository with a <strong>README</strong>, <strong>gitignore</strong>, or license (since we already have a local repository set up).</p>
</li>
<li><p>Click "Create repository."</p>
</li>
</ul>
<h3 id="heading-step-2-link-your-local-repository-to-github">Step 2: Link Your Local Repository to GitHub</h3>
<p>To connect your local repository with the new GitHub repository, you need to add a remote origin. Follow these steps:</p>
<ul>
<li><p>Copy the URL of your new GitHub repository. It should look something like this: https://github.com/yourusername/ip-address-tracker.git</p>
</li>
<li><p>Open Terminal in Visual Studio Code and run the following command:</p>
</li>
</ul>
<pre><code class="lang-bash">git branch -M main
git remote add origin https://github.com/yourusername/ip-address-tracker.git
</code></pre>
<h3 id="heading-step-3-push-your-local-changes-to-github">Step 3: Push Your Local Changes to GitHub</h3>
<p>Now, push your local commits to the GitHub repository with:</p>
<pre><code class="lang-bash">git push -u origin main
</code></pre>
<p>Output:</p>
<pre><code class="lang-bash">Enumerating objects: 8, <span class="hljs-keyword">done</span>.
Counting objects: 100% (8/8), <span class="hljs-keyword">done</span>.
Compressing objects: 100% (4/4), <span class="hljs-keyword">done</span>.
Writing objects: 100% (6/6), 645 bytes | 645.00 KiB/s, <span class="hljs-keyword">done</span>.
Total 6 (delta 2), reused 0 (delta 0)
To https://github.com/yourusername/ip-address-tracker.git
* [new branch]      main -&gt; main
Branch <span class="hljs-string">'main'</span> <span class="hljs-built_in">set</span> up to track remote branch <span class="hljs-string">'main'</span> from <span class="hljs-string">'origin'</span>.
</code></pre>
<h3 id="heading-step-4-verify-your-repository-on-github">Step 4: Verify Your Repository on GitHub</h3>
<p>Go back to your GitHub repository page. You should see all your files and commit history available online.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/08/Screenshot-2024-08-04-at-8.55.48-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>A Hosted Repository on GitHub</em></p>
<h2 id="heading-how-to-host-your-project-on-github-pages">How to Host Your Project on GitHub Pages</h2>
<p>Now that your project has been initialized with Git and pushed to GitHub, let’s host it on GitHub Pages. GitHub Pages is a free service that allows you to publish web projects directly from a GitHub repository.</p>
<h3 id="heading-what-are-github-pages">What are GitHub Pages?</h3>
<p>GitHub Pages turns your GitHub repository into a website. It's an easy way to showcase your projects without needing a separate hosting service. You can create static websites directly from your repositories.</p>
<h3 id="heading-how-to-enable-github-pages">How to Enable GitHub Pages</h3>
<ul>
<li><p>Go to your GitHub repository in a web browser.</p>
</li>
<li><p>Click on the "Settings" tab.</p>
</li>
<li><p>Scroll down to the "Pages" section in the left-hand menu.</p>
</li>
<li><p>Under "Source," select the branch you want to publish from (typically main or master), and choose the root folder.</p>
</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/08/Screenshot-2024-08-04-at-11.12.19-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Selecting the branch and root folder for GitHub Pages.</em></p>
<ul>
<li>Click "Save."</li>
</ul>
<h3 id="heading-how-to-get-your-github-pages-url">How to Get Your GitHub Pages URL</h3>
<p>After enabling GitHub Pages, GitHub will provide you with a URL where your site is published. It usually follows this format:</p>
<pre><code class="lang-bash">https://&lt;username&gt;.github.io/&lt;repository-name&gt;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/08/Screenshot-2024-08-04-at-11.19.05-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The URL where your GitHub Pages site is published.</em></p>
<p>Open your browser and paste the URL to see your live website.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/08/Screenshot-2024-08-04-at-10.56.40-PM-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Viewing the live website on GitHub Pages.</em></p>
<h3 id="heading-how-to-update-your-github-pages-site">How to Update Your GitHub Pages Site</h3>
<p>Every time you push changes to the selected branch in your repository, GitHub Pages will automatically update your live site. Here’s a quick reminder on how to push changes:</p>
<ul>
<li><p>Make changes to your project files.</p>
</li>
<li><p>Add and commit your changes:</p>
</li>
</ul>
<pre><code class="lang-bash">git add .
git commit -m <span class="hljs-string">"Your commit message"</span>
</code></pre>
<ul>
<li>Push the changes to GitHub:</li>
</ul>
<pre><code class="lang-bash">git push origin main
</code></pre>
<p>With these steps, you’ve successfully hosted your project on GitHub Pages. Congratulations! Your project is now live and accessible to the world.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Just a few years ago, I was in your shoes—excited about building my first website but unsure how to share it with the world. Today, you’ve not only learned what Git and GitHub are but also how to use them to host your very own project.</p>
<p>Imagine your excitement when your project goes live, and you can share it with friends, family, and the global community. You've now set up Git, created a GitHub account, initialized a Git repository, and hosted your project on GitHub Pages. Each step has brought you closer to becoming a more confident and capable developer.</p>
<p>This is just the beginning. Git and GitHub have many more features for you to explore. As you continue building and sharing projects, you’ll discover new ways to collaborate and improve your workflow.</p>
<p>Keep experimenting, keep learning, and most importantly, keep coding. The world is waiting to see what you create next!</p>
<p>If you have any questions, feel free to find me on Twitter at <a target="_blank" href="https://twitter.com/sprucekhalifa">@sprucekhalifa</a>, and don’t forget to follow me for more tips and updates. Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Trunk Based Development? A Different Approach to the Software Development Lifecycle ]]>
                </title>
                <description>
                    <![CDATA[ The Software Development Lifecycle (SDLC) is different at every company. The version control system used, peer review process, code review process, design review process, how you do CI, automated testing, and manual testing – all vary greatly dependi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-trunk-based-development/</link>
                <guid isPermaLink="false">66bc5609da80a491ea5a5f6d</guid>
                
                    <category>
                        <![CDATA[ development process  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kealan Parr ]]>
                </dc:creator>
                <pubDate>Tue, 18 Jun 2024 12:55:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/01/Trunk-based-development.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The <strong>Software Development Lifecycle</strong> (<strong>SDLC</strong>) is different at every company.</p>
<p>The version control system used, peer review process, code review process, design review process, how you do CI, automated testing, and manual testing – all vary greatly depending on where you work.</p>
<p>How a company plans, writes, builds, reviews, deploys, and releases software is optimized for their particular use-case, all with their own strengths and drawbacks in mind.</p>
<p>I started reading about how different big tech companies run their Software Development Lifecycles (<strong>SDLC)</strong> and heard the term <strong>Trunk</strong>-<strong>Based Development</strong> a few times. This is a practice Google follows and I was curious about how it's different than the way most other companies develop software.</p>
<h2 id="heading-two-different-ways-to-do-branching">Two Different Ways to Do Branching</h2>
<h3 id="heading-release-branching">Release Branching</h3>
<p>There are two common approaches to enable multiple developers to work on one codebase.</p>
<p>The first we'll refer to as the <strong>release </strong>branching<strong>** method. I've also seen it called </strong>feature branching**. But both of these same approaches follow the same general pattern.</p>
<p>Usually via Git, developers all clone the codebase (so they all have identical copies on their machines). Then they make a new feature/release branch based on <code>main</code>, and merge as the work is completed. The emphasis here is that they only merge once, at the end, when all the work is complete – and they merge the <em>whole branch</em> into <code>main</code>.</p>
<p>Here's an overview for how developers use the <strong>Release </strong>Branch<em>**</em> method:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/ex1.png" alt="Image" width="600" height="400" loading="lazy">
<em><strong>Release </strong>Branching<strong> </strong>development workflow visualised.</em></p>
<p>The white dots represent commits, and the bottom solid black line is <code>main</code>. This is a very simple example, as <strong>release branches</strong> often end up with far more commits than I've shown in the diagram (sometimes hundreds).</p>
<p>Developers branch off <code>main</code>, make their changes, and then when it's complete/has passed code QA, it gets merged back into <code>main</code>. That's <strong>release branching</strong>.</p>
<h3 id="heading-trunk-based-development-tbd">Trunk Based Development (TBD)</h3>
<p><strong>T</strong>runk-<strong>B</strong>ased <strong>D</strong>evelopment (TBD) is the second approach. Here, each developer splits the work they will do into small batches and merge into <code>main</code> (which is often referred to as the <strong>trunk</strong>) multiple times.</p>
<p>In small teams, they normally don't create a branch and merge the branch into the trunk. They commit <em>directly</em> into the trunk without branches.</p>
<p>In a larger team (with checks and approvals necessary for MR's), they use <em>short-lived</em> branches. One <strong>release branch</strong> with 100 commits in TBD would be 10 merge requests with 10 commits each.</p>
<p>In TBD, their code changes generally don't stay around for more than a few hours. They constantly get merged and integrated with the code everyone else is writing.</p>
<p>Jez Humble is a Site Reliability Engineer at Google, and author of <a target="_blank" href="https://www.amazon.com/dp/0321601912?tag=contindelive-20">Continuous Delivery</a>, who says "branching is not the problem, merging is the problem" – which is exactly what TBD tries to solve.</p>
<p>It aims to avoid painful merges that so often occur when it is time to merge long-lived branches that have diverged histories from the trunk, or even merge multiple branches together into one from different teams/developers before merging with the trunk.</p>
<h2 id="heading-does-tbd-work-at-scale"><strong>Does TBD Work at Scale?</strong></h2>
<p>In a <a target="_blank" href="https://www.youtube.com/watch?v=W71BTkUbdqE">Google talk</a>, Rachel Potvin, who's an Engineering Manager at Google, described one codebase that has (as of Jan 2015):</p>
<ul>
<li>1 billion files</li>
<li>2 billion lines of code</li>
<li>86 terabytes of content</li>
<li>45,000 commits per workday</li>
<li>15 million lines changed in 250,000 files per week</li>
</ul>
<p>They used TBD in this codebase and it served their use cases very well. As Google is made up of many talented (most importantly, <strong>experienced</strong>) engineers, they rarely break their builds.</p>
<p>Google also has a very thorough, strict code QA process (read about it <a target="_blank" href="https://www.freecodecamp.org/news/what-google-taught-me-about-code-reviews/">here</a>) which, when using TBD, allows for fast, efficient software delivery.</p>
<p>TBD also works well for Agile methodologies where you have to ship software frequently to get feedback from your consumers/customers. You can continually integrate and get a good snapshot of your current state.</p>
<p>Let's briefly discuss some TBD strengths.</p>
<h3 id="heading-strengths-of-tbd">Strengths of TBD</h3>
<ul>
<li>Feedback (whether from code QA, or peer review) comes quickly, as you merge daily. This can stop you from doing the wrong thing for 3 weeks, and then getting feedback that your work isn't correct at the very end, causing you to miss deadlines.</li>
<li>There's a mental benefit to TBD, where developers feel like the trunk is <strong>our</strong> code, rather than everyone having their own feature branches and thinking this branch is <strong>my</strong> code. This can foster a more collaborative culture, increasing communication.</li>
<li>It results in early integration with all the other in-flight projects/tickets and helps you promote code re-use. It's much harder to "use code" that isn't merged into <code>main</code> and you don't know when will be complete. It also stops merge hell when your 9 month old release branch needs to be merged back into the trunk.</li>
<li>Large projects with lots of work involved are forced to be broken down into smaller deliverables. This is much better for estimating timelines and also for breaking up your code into modular pieces.</li>
<li>When lots of developers work in isolation on release branches, it can be harder to spot junior developers struggling in their own branch. But if they're expected to be committing their work daily, you can monitor their daily output and assist them when necessary.</li>
<li>TBD really cleanly ties in with continuous integration. With lots of small, incremental commits to an eventual finished project, you get an always tested, always integrated codebase with (minimal) horrible merges.</li>
</ul>
<h3 id="heading-weaknesses-of-tbd">Weaknesses of TBD</h3>
<ul>
<li>One of the challenges of this approach is that you have an increased chance of breaking the trunk, and stopping lots of people from working. You have to make sure your commits run unit tests along with a good code review process so you don't lose time reverting commits all day.</li>
<li>Your commit history into <code>main</code> will likely be more verbose and it can be harder to see if something is wrong. If you are called at 3 AM and asked to fix a bug on your prod site with some dodgy commits that went on during business hours, would you prefer a day with 1 commit or 200 commits?</li>
<li>If you don't have a fast build process, you will spend a long time waiting for things to build while your team constantly commits.</li>
<li>Often times with TBD you are incrementally adding new code to do something new, but you also need the "old" paths you're replacing to still work. Because of this you need to rely on feature toggles (normally from a database) to turn things on and off. This can add an extra level of complexity with debugging.</li>
<li>A final challenge can be that, when you have constant commits, you are constantly in a state of churn. You need to make sure your team regularly pulls from the trunk and doesn't end up tripping over one another while merging things.</li>
</ul>
<h2 id="heading-how-to-release-software-with-trunk-based-development">How to Release Software with Trunk-Based Development</h2>
<p>Teams using TBD will typically have a different release process than a team using feature branches.</p>
<p>Generally, if you use release branches, you release <code>main</code> whenever you have something that gets merged in (tickets, completed projects, and so on). Or some teams release <code>main</code> on a schedule, like once every week.</p>
<p>Here's an overview of how TBD teams do their releases:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/06/ex2.png" alt="Image" width="600" height="400" loading="lazy">
<em>Overview of TBD process</em></p>
<p>In TBD, branching is used for releases to allow everyone to keep committing into <code>main</code>.</p>
<p>They provide a "snapshot" of your codebase at a stable state, ready for deployment and release.</p>
<p>The only reason the TBD diagram above may need extra details is when something goes wrong with the release of prj-123. Then we commit the result into the trunk and cherry pick the commits into our release branch to get it in a workable state as soon as possible.</p>
<p>Some places, if they are releasing regularly, don't even branch and can just release the trunk whenever it's required. It depends on your company oftentimes.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>There is a whole site based on the theory and practice of TBD. Feel free to read more <a target="_blank" href="https://trunkbaseddevelopment.com/">here</a>.</p>
<p>I hope this has explained what <strong>Trunk Based Development</strong> is and why it's used. It certainly helps alleviate some of the issues around merging long-lived branches containing major rewrites.</p>
<p>I share my writing on <a target="_blank" href="https://twitter.com/kealanparr">Twitter</a> if you enjoyed this article and want to see more.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
