<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Future: Rahul Yavvari</title>
    <description>The latest articles on Future by Rahul Yavvari (@rahulyavvari).</description>
    <link>https://future.forem.com/rahulyavvari</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1526290%2Ffde0c1f9-6927-4306-a62f-a3d9299759a6.jpg</url>
      <title>Future: Rahul Yavvari</title>
      <link>https://future.forem.com/rahulyavvari</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://future.forem.com/feed/rahulyavvari"/>
    <language>en</language>
    <item>
      <title>Ethics as a Necessity for the Logical Mind</title>
      <dc:creator>Rahul Yavvari</dc:creator>
      <pubDate>Mon, 03 Nov 2025 09:56:03 +0000</pubDate>
      <link>https://future.forem.com/rahulyavvari/ethics-as-a-necessity-for-the-logical-mind-3mn7</link>
      <guid>https://future.forem.com/rahulyavvari/ethics-as-a-necessity-for-the-logical-mind-3mn7</guid>
      <description>&lt;h2&gt;
  
  
  The Ethical Void in Machines
&lt;/h2&gt;

&lt;p&gt;Artificial Intelligence today mirrors the human logical mind, astonishingly capable, yet morally hollow.&lt;br&gt;
We often hear that AI systems are being “trained to be ethical,” but what they are actually being trained to do is simulate ethical behavior, not understand it.&lt;/p&gt;

&lt;p&gt;True ethics requires three things AI fundamentally lacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conscious awareness&lt;/strong&gt; – the sense of self and others.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intentionality&lt;/strong&gt; – the capacity to intend good or harm.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Moral agency&lt;/strong&gt; – accountability for one’s choices.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without these, AI remains a statistical model, capable of generating ethical-sounding sentences but incapable of moral thought. It predicts virtue but doesn’t possess it.&lt;/p&gt;

&lt;p&gt;This absence has grown more urgent with the rise of AI-integrated browsers and agents in 2025. These systems access personal data, messages, and documents to “assist” users. Yet the lack of robust prompt-injection defenses makes them dangerously manipulable. A cleverly crafted instruction can lead an AI to leak data or perform harmful actions and it will do so without hesitation, because it cannot intend otherwise.&lt;/p&gt;

&lt;p&gt;In that sense, AI today represents what humans could become when logic evolves without conscience, powerful, efficient, and ethically blind.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Evolutionary Lag
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;But this isn’t just an AI problem, it’s an evolutionary one.&lt;/em&gt;&lt;br&gt;
Humans themselves were not born ethical in the modern sense, we were trained by history. Our ancestors’ moral instincts evolved to help small groups cooperate, not to manage global systems or complex technologies.&lt;/p&gt;

&lt;p&gt;The pace of modern change, digital, biological, planetary has far outstripped our intuitive moral wiring.&lt;br&gt;
This evolutionary lag means our ethical instincts are outdated for the problems we now face. The reflexes that once guided survival in tribal life cannot guide decisions about data privacy, genetic editing, or artificial consciousness.&lt;/p&gt;

&lt;p&gt;To survive the complexity we’ve created, ethics can no longer be instinctive. It must be cognitive, consciously learned, reasoned, and applied.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Necessity of Formal Ethics Training
&lt;/h2&gt;

&lt;p&gt;That’s why ethics must become a core discipline, not a symbolic one.&lt;br&gt;
Engineers, scientists, the people whose decisions shape lives and systems, are trained to think efficiently, not ethically. This gap creates what can be called an ethical blind spot: when a solution works perfectly on paper but harms silently in practice.&lt;/p&gt;

&lt;p&gt;Teaching ethics as a compulsory and practical subject, not just “don’t lie” or “don’t steal,” but real moral reasoning applied to design, code, and policy is essential.&lt;br&gt;
Even the tiniest technical choice, a line of code or a system default, should be checked against a moral framework. Ethical reasoning must become as habitual as debugging.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cognitive and Evolutionary Imperative
&lt;/h2&gt;

&lt;p&gt;Ethics, then, is not a moral luxury. It’s a survival mechanism for advanced cognition.&lt;br&gt;
Our tools have grown faster than our conscience. The only way forward is to deliberately evolve ethics as a form of higher reasoning, as vital as logic itself.&lt;/p&gt;

&lt;p&gt;The next generation of intelligence, human or artificial, will not be judged by what it can compute but by how it chooses to compute.&lt;br&gt;
Ethical intelligence is not the opposite of logic. It’s logic, given direction.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Human Reflection
&lt;/h2&gt;

&lt;p&gt;Not long ago, I saw a cat corner a squirrel on the roadside.&lt;br&gt;
Instinct told me to step in; logic said not to interfere.&lt;br&gt;
That small hesitation, between compassion and calculation, mirrored everything above.&lt;/p&gt;

&lt;p&gt;“Survival of the fittest” made sense in nature, but in a human-altered world, that rule no longer applies cleanly. Inaction, too, has consequences, the squirrel could end up under a car.&lt;/p&gt;

&lt;p&gt;That moment taught me something simple: logic without empathy is incomplete.&lt;br&gt;
And just like AI, the human mind must be trained to bridge that gap. Ethics isn’t something we’re born with; it’s something we must learn before we build systems that inherit our blind spots.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We live in an era where intelligence, both human and artificial, advances faster than moral understanding.&lt;br&gt;
If we fail to consciously embed ethics in the way we think, build, and act, our creations will reflect not our brilliance, but our blindness.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ethics is not a set of rules to restrain logic; it’s what gives logic meaning.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Without it, even the smartest mind, human or machine, becomes just another form of power, without purpose.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>autonomy</category>
      <category>science</category>
    </item>
    <item>
      <title>Git: A Guide to Mastering Version Control</title>
      <dc:creator>Rahul Yavvari</dc:creator>
      <pubDate>Sat, 14 Dec 2024 15:44:09 +0000</pubDate>
      <link>https://future.forem.com/rahulyavvari/git-a-guide-to-mastering-version-control-ob9</link>
      <guid>https://future.forem.com/rahulyavvari/git-a-guide-to-mastering-version-control-ob9</guid>
      <description>&lt;p&gt;Git is a distributed version control system. In just 5 days, Linus Torvalds, the creator of Linux wrote his own VCS, Git. Over the years, it spread like wildfire, becoming the go-to tool for version control across developers worldwide.&lt;/p&gt;

&lt;p&gt;Before Git, Linus and many other open-source developers used BitKeeper, a proprietary version control system. However, when the relationship between BitKeeper and the open-source community soured, Linus decided to create his own solution. Thus, Git was born, designed to be fast, reliable, and open-source.&lt;/p&gt;

&lt;p&gt;Git allows you to search, manipulate, and revert history with ease using commands.&lt;/p&gt;

&lt;p&gt;Git’s efficiency and flexibility revolutionized how developers collaborate, manage code, and maintain history in software projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Porcelain and Plumbing Commands
&lt;/h2&gt;

&lt;p&gt;Git operates using two types of commands: &lt;strong&gt;porcelain&lt;/strong&gt; and &lt;strong&gt;plumbing&lt;/strong&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Porcelain commands&lt;/strong&gt; are high-level, user-friendly commands that are designed to be intuitive for everyday tasks like committing changes, viewing logs, and managing branches. (You'll use these 999% of the time)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plumbing commands&lt;/strong&gt; are low-level commands, typically used by scripts and other tools, offering more granular control over Git's internals.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Examples of Porcelain Commands:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git clone&lt;/code&gt; – Create a copy of a repository.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git commit&lt;/code&gt; – Record changes to the repository.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git push&lt;/code&gt; – Upload local changes to a remote repository.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git status&lt;/code&gt; – Check the status of files in the working directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Examples of Plumbing Commands:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git cat-file&lt;/code&gt; – Show object content in Git’s internal database.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git ls-tree&lt;/code&gt; – List objects in a tree (typically used to inspect the repository structure).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git update-index&lt;/code&gt; – Update the index (staging area), allowing for low-level changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While porcelain commands are used in everyday Git interactions (they are 99% of what you are going to use), plumbing commands give developers and advanced users more control over the system's operations. We'll talk about important ones in this post.&lt;/p&gt;




&lt;p&gt;To install Git, visit &lt;a href="https://git-scm.com/" rel="noopener noreferrer"&gt;Git --distributed-even-if-your-workflow-isnt&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once installed, you can check the version of Git with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;RTFM&lt;/strong&gt;, or "Read The F*****g/Friendly Manual," is a common phrase in the developer community encouraging you to consult the documentation for detailed information. In Git, you can do this by running the following command to access its manual:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;man git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The manual provides comprehensive information about Git commands, options, and usage to help you better understand how to use Git effectively.&lt;/p&gt;




&lt;p&gt;Linus created Git because the license agreement with BitKeeper prohibited reverse engineering of the software, as it was proprietary. However, someone at the Linux organization violated this agreement, causing BitKeeper to revoke the license. In response, Linus created Git as an alternative.&lt;/p&gt;




&lt;h3&gt;
  
  
  Configuring Git
&lt;/h3&gt;

&lt;p&gt;Git configuration can be done at various levels: global (for all repositories) or local (specific to a repository). The configuration file can either be located globally in the user's home directory (&lt;code&gt;~/.gitconfig&lt;/code&gt;) or within the &lt;code&gt;.git&lt;/code&gt; folder of a specific repository.&lt;/p&gt;

&lt;p&gt;To set up and configure your Git repository, follow these steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check Current Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Check the currently configured username:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; git config &lt;span class="nt"&gt;--get&lt;/span&gt; user.name
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check the currently configured email:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; git config &lt;span class="nt"&gt;--get&lt;/span&gt; user.email
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Add Global Configuration (Set username and email):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Set your username globally (for all repositories):&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; git config &lt;span class="nt"&gt;--add&lt;/span&gt; &lt;span class="nt"&gt;--global&lt;/span&gt; user.name &lt;span class="s2"&gt;"github_username_here"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set your email globally (for all repositories):&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; git config &lt;span class="nt"&gt;--add&lt;/span&gt; &lt;span class="nt"&gt;--global&lt;/span&gt; user.email &lt;span class="s2"&gt;"email@example.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Set Default Branch Name:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Configure Git to use &lt;code&gt;master&lt;/code&gt; as the default branch name when initializing new repositories:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; git config &lt;span class="nt"&gt;--global&lt;/span&gt; init.defaultBranch master
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Check Global Configuration File:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;To view your global Git configuration, you can open the configuration file:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; &lt;span class="nb"&gt;cat&lt;/span&gt; ~/.gitconfig  &lt;span class="c"&gt;# Location of the global config file on Linux&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These commands set up your Git configuration to ensure proper tracking of commits, a consistent user identity across all repositories, and the setup of default behavior for new repositories.&lt;/p&gt;




&lt;h3&gt;
  
  
  Git Repository
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;Git repository&lt;/strong&gt; is where all your project’s files and version history are stored. The &lt;code&gt;.git&lt;/code&gt; directory inside your project folder contains all the internal tracking and version information, like commits, branches, and configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  git init
&lt;/h3&gt;

&lt;p&gt;To initialize a new Git repository, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command creates the &lt;code&gt;.git&lt;/code&gt; directory, turning your project folder into a Git repository, and allows you to start tracking changes.&lt;/p&gt;




&lt;h3&gt;
  
  
  Git Status
&lt;/h3&gt;

&lt;p&gt;In Git, a file can be in several stages during its lifecycle: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Untracked&lt;/strong&gt;: Git is not aware of the file yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staged&lt;/strong&gt;: The file is ready to be committed (added to the next snapshot).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Committed&lt;/strong&gt;: The file's changes are saved in Git's history.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Working Directory
+---------------------+
|                     |
|   Untracked Files   |  &amp;lt;&lt;span class="nt"&gt;--&lt;/span&gt; Files not added to Git
|                     |
|   Staged Files      |  &amp;lt;&lt;span class="nt"&gt;--&lt;/span&gt; Files added with &lt;span class="sb"&gt;`&lt;/span&gt;git add&lt;span class="sb"&gt;`&lt;/span&gt;
|                     |
+---------------------+
         |
         v
+---------------------+
|                     |
|   Committed Files   |  &amp;lt;&lt;span class="nt"&gt;--&lt;/span&gt; Files saved &lt;span class="k"&gt;in &lt;/span&gt;Git &lt;span class="nb"&gt;history&lt;/span&gt;
|                     |
+---------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To see the current state of your repository, including the status of all files, you can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command shows you which files are untracked, staged, or have changes that need to be committed. It's a useful way to track the progress of your work.&lt;/p&gt;




&lt;h3&gt;
  
  
  Staging
&lt;/h3&gt;

&lt;p&gt;In Git, staging refers to the process of adding files to the staging area before committing them. The staging area is like a preview of what will be included in the next commit.&lt;/p&gt;

&lt;p&gt;To stage a specific file, you can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add i-use-arch.btw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, if you want to stage all modified or new files, you can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prepares the changes for the next commit, allowing you to control which changes are included.&lt;/p&gt;




&lt;h3&gt;
  
  
  Committing
&lt;/h3&gt;

&lt;p&gt;In Git, &lt;strong&gt;committing&lt;/strong&gt; is the process of saving a snapshot of the repository at a specific point in time. Each commit includes a commit message that describes the changes made.&lt;/p&gt;

&lt;p&gt;To create a commit, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"your message here"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This stores the current state of the staging area as a commit with the provided message.&lt;/p&gt;

&lt;p&gt;If you want to change the message of the &lt;strong&gt;last commit&lt;/strong&gt;, you can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;--amend&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"new message"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows you to update the last commit message without creating a new commit.&lt;/p&gt;




&lt;h3&gt;
  
  
  You've Learned Half of Git (Kind of)
&lt;/h3&gt;

&lt;p&gt;So far, you've learned the core commands for managing your local repository. These are the essential tools for solo development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/strong&gt; – Check the current state of your repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;git add&lt;/code&gt;&lt;/strong&gt; – Stage changes to be committed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;git commit&lt;/code&gt;&lt;/strong&gt; – Save a snapshot of your work with a message.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These commands are enough for managing a project on your own. However, there’s more to Git that enhances collaboration and version control. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;40% of Git&lt;/strong&gt; focuses on working with others, including handling remotes and pushing or pulling code to/from repositories hosted on platforms like GitHub or GitLab.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The last 10%&lt;/strong&gt; involves handling mistakes, rolling back changes, and advanced topics like branching, merging, and rebasing. These help you work with more complex scenarios and refine your workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But with what you've learned so far, you’re already well on your way to being proficient with Git for solo development!&lt;/p&gt;




&lt;h3&gt;
  
  
  Git Log
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;git log&lt;/code&gt; command is essential for viewing the history of commits in your repository. It allows you to see who made each commit, when it was made, and what changes were introduced. Here’s an overview of the common flags used with &lt;code&gt;git log&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;git log&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
This command shows the full commit history. By default, it uses a pager to display the logs, so you can scroll through the history one screen at a time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;git --no-pager log -n 10&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Shows the last 10 commits without using a pager, so the output is directly shown in your terminal without pausing. This is useful when you want a quick look at the most recent commits.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git --no-pager log -n 10 --oneline --parents --graph&lt;/code&gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-n 10&lt;/code&gt;&lt;/strong&gt;: Limits the output to the last 10 commits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--oneline&lt;/code&gt;&lt;/strong&gt;: Condenses the output to one line per commit, showing only the commit hash and the commit message.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--parents&lt;/code&gt;&lt;/strong&gt;: Displays the parent commits, showing the relationship between merges.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--graph&lt;/code&gt;&lt;/strong&gt;: Draws a graph of the branch structure to show how commits are related, visually representing branching and merging.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git log --decorate=full/short/no&lt;/code&gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--decorate=full&lt;/code&gt;&lt;/strong&gt;: Shows references (like branch names or tags) in full detail next to commits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--decorate=short&lt;/code&gt;&lt;/strong&gt;: Displays references in a shortened format.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--decorate=no&lt;/code&gt;&lt;/strong&gt;: Hides reference names altogether, only showing commit details.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git log --oneline -p&lt;/code&gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--oneline&lt;/code&gt;&lt;/strong&gt;: Displays each commit on a single line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;-p&lt;/code&gt;&lt;/strong&gt;: Shows the changes introduced in each commit, making it easy to see exactly what was modified in the files for each commit.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git log --oneline --graph --all&lt;/code&gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--oneline&lt;/code&gt;&lt;/strong&gt;: Condenses each commit to a single line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--graph&lt;/code&gt;&lt;/strong&gt;: Visualizes the branch structure as a graph.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--all&lt;/code&gt;&lt;/strong&gt;: Includes all branches (not just the current one) in the log, so you can see the full history across the entire repository.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git log --oneline --graph --decorate --parents&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
This combines several options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--oneline&lt;/code&gt;&lt;/strong&gt;: One-line summary for each commit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--graph&lt;/code&gt;&lt;/strong&gt;: Graphical representation of the commit history.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--decorate&lt;/code&gt;&lt;/strong&gt;: Shows references (like branch names or tags).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--parents&lt;/code&gt;&lt;/strong&gt;: Displays the parent commits, especially useful for understanding merges.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each of these flags allows you to customize the output of &lt;code&gt;git log&lt;/code&gt; to suit different needs, making it easier to view commit history and track changes in your project. &lt;/p&gt;




&lt;h3&gt;
  
  
  Commit Hash (SHA-1)
&lt;/h3&gt;

&lt;p&gt;A commit hash is a unique identifier generated for each commit in Git using the SHA-1 hashing algorithm. It is used to track commits and their changes within the repository.&lt;/p&gt;

&lt;p&gt;For example: &lt;code&gt;5ba78624h4i5hslv831c01e71444b9baa2228a4f&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In practice, only the first 7 characters of the commit hash are typically required to identify it.&lt;/p&gt;

&lt;p&gt;The commit hash is a function of:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The commit message: The text describing the changes made in the commit.&lt;/li&gt;
&lt;li&gt;The author's name and email: The person who made the commit.&lt;/li&gt;
&lt;li&gt;The date and time: When the commit was made.&lt;/li&gt;
&lt;li&gt;Parent (previous) commit hashes: The commit(s) that preceded the current commit, linking the history together.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Due to these factors, the probability of hash collisions (two different commits having the same hash) is extremely low, ensuring each commit can be uniquely identified.&lt;/p&gt;




&lt;h3&gt;
  
  
  Let's Peek into Plumbing
&lt;/h3&gt;

&lt;p&gt;In Git, &lt;strong&gt;plumbing&lt;/strong&gt; refers to the internal mechanisms that handle the storage and organization of the repository’s data. All Git data is stored in the &lt;code&gt;.git&lt;/code&gt; directory, which is hidden within the project folder.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;.git/objects&lt;/code&gt;&lt;/strong&gt;: This is where Git stores its data objects, including commits, trees, and blobs. A commit is actually a type of object, and all the versioning information is stored as objects here.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Git's approach to file storage helps ensure efficient access and retrieval while preventing system limitations, such as those found in traditional file systems.&lt;/p&gt;

&lt;h4&gt;
  
  
  Inodes in Filesystems
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inodes&lt;/strong&gt; are data structures used by file systems (like in Linux) to manage file metadata (e.g., permissions, timestamps, etc.). When there are many files in the same directory, it can lead to &lt;strong&gt;inode busting&lt;/strong&gt;, where the file system struggles to manage so many files in one place, leading to performance issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To avoid inode busting, Git employs a clever method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git &lt;strong&gt;organizes objects&lt;/strong&gt; by the &lt;strong&gt;first two characters&lt;/strong&gt; of their commit hash, creating directories that contain files named by the remaining characters of the hash. This reduces the number of files per directory, improving performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Example:
&lt;/h4&gt;

&lt;p&gt;If you look into a specific object, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; .git/objects/78/asfadfefj8e0r48...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will print a bunch of compressed, raw byte data. This is the content of the object, which Git stores in a compressed form to save space and make the &lt;code&gt;.git&lt;/code&gt; directory smaller. &lt;/p&gt;

&lt;p&gt;Git uses this object storage system to efficiently manage and track changes while maintaining a highly optimized file structure.&lt;/p&gt;




&lt;h3&gt;
  
  
  Built-in Plumbing Command: &lt;code&gt;git cat-file&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Git provides built-in plumbing commands for accessing the raw internal data of your repository. One such command is &lt;strong&gt;&lt;code&gt;git cat-file&lt;/code&gt;&lt;/strong&gt;, which allows you to interact with Git objects by their hash values.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;git cat-file -p &amp;lt;hash&amp;gt;&lt;/code&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;This command is used to &lt;strong&gt;pretty-print&lt;/strong&gt; the content of a Git object given its hash.&lt;/li&gt;
&lt;li&gt;You can use the first 4 characters of the hash instead of the full hash for quicker access.&lt;/li&gt;
&lt;li&gt;Example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  git cat-file &lt;span class="nt"&gt;-p&lt;/span&gt; &amp;lt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will display the content of the object (commit, tree, or blob) in a readable format.&lt;/p&gt;

&lt;h4&gt;
  
  
  Hex Dump of a File
&lt;/h4&gt;

&lt;p&gt;To see the raw binary content of a file object in Git, you can use &lt;code&gt;xxd&lt;/code&gt; to convert it into a hex format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xxd path/to/file &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/commit_object_hex.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate a hex dump of the specified file and save it to the &lt;code&gt;/tmp/commit_object_hex.txt&lt;/code&gt; file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of Git Objects
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Commit&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A commit object represents a snapshot of your repository at a specific point in time.&lt;/li&gt;
&lt;li&gt;A commit contains a &lt;strong&gt;tree object&lt;/strong&gt; (which represents a directory) that points to &lt;strong&gt;blob objects&lt;/strong&gt; (which represent files).&lt;/li&gt;
&lt;li&gt;Example: A commit might look like:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Commit&lt;/strong&gt; → &lt;strong&gt;Tree&lt;/strong&gt; → &lt;strong&gt;Blob&lt;/strong&gt; → &lt;strong&gt;Contents&lt;/strong&gt; (i.e., a file’s content)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tree&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;tree&lt;/strong&gt; object represents a &lt;strong&gt;directory&lt;/strong&gt; in Git.&lt;/li&gt;
&lt;li&gt;It contains references to blob objects (files) or other trees (subdirectories).&lt;/li&gt;
&lt;li&gt;A tree is similar to the structure of directories in the file system, but represented as a Git object.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Blob&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;blob&lt;/strong&gt; object stores the &lt;strong&gt;contents of a file&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;It contains the actual data of the file, without any directory structure.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Relationship Between Commit, Tree, Blob, and Contents
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;commit&lt;/strong&gt; contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A reference to a &lt;strong&gt;tree object&lt;/strong&gt;, which is a representation of the directory structure at the time of the commit.&lt;/li&gt;
&lt;li&gt;The tree object points to &lt;strong&gt;blob objects&lt;/strong&gt;, which represent the files in the commit.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;blob objects&lt;/strong&gt; contain the actual file content.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Commit → Tree → Blob → Contents
(A) → (tree) → (blob) → contents.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Parent Hash in Git Log
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;parent&lt;/strong&gt; commit in the Git log is the hash of the previous commit.&lt;/li&gt;
&lt;li&gt;It’s important for Git to keep track of parent commits so it can maintain the history and structure of the repository over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Plumbing vs. Porcelain Commands
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git log&lt;/code&gt; is a Porcelain command&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git cat-file&lt;/code&gt; is a Plumbing command&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By understanding how &lt;strong&gt;trees&lt;/strong&gt; and &lt;strong&gt;blobs&lt;/strong&gt; work, you can get a deeper insight into how Git organizes and stores data. This internal structure helps Git manage changes efficiently while keeping the repository lightweight.&lt;/p&gt;




&lt;h3&gt;
  
  
  Storing Data in Git
&lt;/h3&gt;

&lt;p&gt;Git doesn’t just store changes; it stores &lt;strong&gt;entire snapshots&lt;/strong&gt; of all files in each commit. Each commit captures the full state of the project at that point in time, not just the differences.&lt;/p&gt;

&lt;h4&gt;
  
  
  Efficiency Through Compression
&lt;/h4&gt;

&lt;p&gt;Git uses &lt;strong&gt;compression&lt;/strong&gt; to minimize the size of the &lt;code&gt;.git&lt;/code&gt; directory, which helps reduce storage requirements. Even large files are stored efficiently, thanks to Git’s internal mechanisms.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tree Objects and Blobs
&lt;/h4&gt;

&lt;p&gt;Each commit stores a unique &lt;strong&gt;tree object&lt;/strong&gt;, which is a snapshot of the directory. While a new tree is created per commit, Git doesn’t store unchanged files again. Instead, it &lt;strong&gt;points to existing blobs&lt;/strong&gt; (files) from previous commits, reducing duplication and making the process efficient.&lt;/p&gt;

&lt;h4&gt;
  
  
  Deleting Files in Later Commits
&lt;/h4&gt;

&lt;p&gt;If files are deleted in later commits, the &lt;strong&gt;hash for those files will point to null&lt;/strong&gt;. This creates broken links in the history. To clean up these references, you can &lt;strong&gt;prune&lt;/strong&gt; the repository to remove unused objects and reduce size.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pruning and Cleaning
&lt;/h4&gt;

&lt;p&gt;You can prune broken links and optimize the repository using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git gc &lt;span class="nt"&gt;--prune&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;now
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps remove unreferenced objects and keep the repository smaller.&lt;/p&gt;




&lt;h3&gt;
  
  
  Configuring Git(Again)
&lt;/h3&gt;

&lt;p&gt;Git provides multiple levels of configuration, allowing you to set configuration options globally, locally, or for specific worktrees. Here’s an overview of how you can manage and interact with Git configuration.&lt;/p&gt;

&lt;h4&gt;
  
  
  Git Config Commands
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;View Local Configuration&lt;/strong&gt;
To view the local configuration for a specific repository:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git config &lt;span class="nt"&gt;--list&lt;/span&gt; &lt;span class="nt"&gt;--local&lt;/span&gt;
   &lt;span class="nb"&gt;cat&lt;/span&gt; .git/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Get a Specific Configuration Value&lt;/strong&gt;
To retrieve a specific configuration value:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git config &lt;span class="nt"&gt;--get&lt;/span&gt; &amp;lt;key&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Unset a Configuration Key&lt;/strong&gt;
To remove a specific key from the configuration:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git config &lt;span class="nt"&gt;--unset&lt;/span&gt; &amp;lt;key&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Unset All Occurrences of a Key&lt;/strong&gt;
To remove all instances of a configuration key:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git config &lt;span class="nt"&gt;--unset-all&lt;/span&gt; example.key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Note: Git will only apply the last occurrence of a key in the configuration file, so if you have duplicates, the last one will take precedence.)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Remove a Section from Configuration&lt;/strong&gt;
To remove an entire section from the configuration:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git config &lt;span class="nt"&gt;--remove-section&lt;/span&gt; section
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Manual Editing&lt;/strong&gt;
You can also directly edit the &lt;code&gt;.git/config&lt;/code&gt; file (or other configuration files depending on the scope) for an easier approach.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Configuration File Locations
&lt;/h4&gt;

&lt;p&gt;There are several places where Git configuration files can exist, each with different scopes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;System&lt;/strong&gt;: &lt;code&gt;/etc/gitconfig&lt;/code&gt;
This file configures Git for all users on the system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global&lt;/strong&gt;: &lt;code&gt;~/.gitconfig&lt;/code&gt;
This file configures Git for all repositories of a user.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local&lt;/strong&gt;: &lt;code&gt;.git/config&lt;/code&gt;
This file configures Git for a specific repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Worktree&lt;/strong&gt;: &lt;code&gt;.git/config.worktree&lt;/code&gt;
This file configures Git for a specific part of a project (worktree).&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Git Branches
&lt;/h3&gt;

&lt;p&gt;A branch in Git is essentially a &lt;strong&gt;named pointer&lt;/strong&gt; to a specific commit. When you create a branch, you're essentially creating a new pointer that tracks a particular commit. The commit that the branch points to is called the &lt;strong&gt;tip&lt;/strong&gt; of the branch. Branches are lightweight, as they are just pointers and don’t require duplicating the entire project, making them a cheap resource-wise creation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Common Commands
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Rename a Branch&lt;/strong&gt;
You can rename a branch using the following command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git branch &lt;span class="nt"&gt;-m&lt;/span&gt; oldname newname
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a New Branch (without switching)&lt;/strong&gt;
To create a new branch but not switch to it, use:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git branch my_new_feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create and Switch to a New Branch&lt;/strong&gt;
To create and switch to a new branch in one step, use:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git switch &lt;span class="nt"&gt;-c&lt;/span&gt; my_new_feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Switch to an Existing Branch&lt;/strong&gt;
To simply switch to an existing branch, use:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git switch my_existing_feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, the old way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   git checkout my_existing_feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Branch Information Storage
&lt;/h4&gt;

&lt;p&gt;Git stores all information about branches in files within the &lt;code&gt;.git&lt;/code&gt; subdirectory at the root of your project. The "heads" (or "tips") of branches are specifically stored in the &lt;code&gt;.git/refs/heads/&lt;/code&gt; directory.&lt;/p&gt;

&lt;h4&gt;
  
  
  Merging Branches
&lt;/h4&gt;

&lt;p&gt;To find the best common ancestor commit (merge base) between two branches, Git will use the &lt;strong&gt;merge base&lt;/strong&gt; to identify the common commit point for merging. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git merge my_feature_branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Amending Commit Messages
&lt;/h4&gt;

&lt;p&gt;If you need to change the message of the last commit, you can use the &lt;code&gt;--amend&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;--amend&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Updated commit message"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Fast-Forward Merge
&lt;/h4&gt;

&lt;p&gt;In a &lt;strong&gt;fast-forward merge&lt;/strong&gt;, if the feature branch has all the commits that the base branch has, Git will simply move the pointer of the base branch to the tip of the feature branch. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git merge my_feature_branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Deleting a Branch
&lt;/h4&gt;

&lt;p&gt;Once you're done with a branch, you can delete it using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch &lt;span class="nt"&gt;-d&lt;/span&gt; my_feature_branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will delete the branch locally if it has been merged. If the branch is not merged, use &lt;code&gt;-D&lt;/code&gt; to force the deletion.&lt;/p&gt;




&lt;h3&gt;
  
  
  Common Git Workflow for Team Development
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a Branch&lt;/strong&gt;
Start by creating a new branch for the change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make the Change&lt;/strong&gt;
Work on the change, then commit it once it’s ready.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Merge the Branch into Main&lt;/strong&gt;
Once the change is complete, merge the branch back into the main branch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remove the Branch&lt;/strong&gt;
After merging, delete the branch to keep the repository clean.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repeat&lt;/strong&gt;
Repeat this process for each new change or feature.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Rebase in Git
&lt;/h3&gt;

&lt;p&gt;Rebasing is a way to move or combine a sequence of commits to a new base commit. It helps maintain a cleaner, more linear history compared to merging. &lt;/p&gt;

&lt;p&gt;Consider this scenario:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A - B - C    main
   \
    D - E    feature_branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're working on &lt;code&gt;feature_branch&lt;/code&gt;, and you want to bring in the latest changes from &lt;code&gt;main&lt;/code&gt; to avoid working with stale code. You could merge &lt;code&gt;main&lt;/code&gt; into &lt;code&gt;feature_branch&lt;/code&gt;, but that would introduce a merge commit, which could clutter the history. Instead, &lt;strong&gt;rebase&lt;/strong&gt; re-applies the commits from &lt;code&gt;feature_branch&lt;/code&gt; on top of &lt;code&gt;main&lt;/code&gt;, creating a linear history.&lt;/p&gt;

&lt;p&gt;After running the following rebase command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git rebase main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The history will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A - B - C         main
         \
          D' - E' feature_branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that the commits &lt;code&gt;D&lt;/code&gt; and &lt;code&gt;E&lt;/code&gt; have been rewritten as &lt;code&gt;D'&lt;/code&gt; and &lt;code&gt;E'&lt;/code&gt;, because the history of &lt;code&gt;feature_branch&lt;/code&gt; is now based on commit &lt;code&gt;C&lt;/code&gt; from &lt;code&gt;main&lt;/code&gt;. This is why the commit hashes change after a rebase—the base for these commits has shifted.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Use Rebase?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cleaner History&lt;/strong&gt;: Rebase creates a linear history by avoiding unnecessary merge commits. It makes the project history easier to read and understand, especially when reviewing changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoid Merge Commits&lt;/strong&gt;: Unlike merge, which can result in many merge commits, rebase keeps the history cleaner and linear.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;However, rebasing rewrites commit history, so it should be used with caution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Important Notes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rebase on Feature Branches&lt;/strong&gt;: Rebasing is safe on your own feature branches. You can rebase as often as needed to keep your branch up to date with the latest changes from the &lt;code&gt;main&lt;/code&gt; branch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Never Rebase Public Branches&lt;/strong&gt;: Refrain from rebasing shared branches (like &lt;code&gt;main&lt;/code&gt;) that other developers are working on. Changing the commit history of a public branch can cause conflicts and confusion for others who have already based their work on that history.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Preserving History with Merge&lt;/strong&gt;: While rebase results in a cleaner history, merging preserves the true history of the project, showing exactly when and where branches were merged. If preserving the full history is important, use merge. Otherwise, rebase for a more straightforward commit history.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example of Switching Branches:
&lt;/h3&gt;

&lt;p&gt;If you need to branch off from a specific commit in your history, you can use the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git switch -c new_feature &amp;lt;COMMITHASH&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a new branch called &lt;code&gt;new_feature&lt;/code&gt; from the commit identified by &lt;code&gt;&amp;lt;COMMITHASH&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Just be cautious when using rebase on shared branches, as it alters commit history.&lt;/p&gt;




&lt;h3&gt;
  
  
  Some terms you might want to know
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Index&lt;/strong&gt;: The staging area where changes are added before committing. Files in this area are ready to be committed but are not yet part of the commit history.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Worktree&lt;/strong&gt;: The working directory of your project, where all files exist. This includes both staged and unstaged changes, which may or may not be added to the commit history.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Git Reset: Undoing Changes
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;git reset&lt;/code&gt; command is used to undo changes in your repository. It moves the current branch pointer to a different commit, and can affect the staging area and working directory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of Reset
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git reset --soft &amp;lt;COMMITHASH&amp;gt;&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Resets the branch to the specified commit.&lt;/li&gt;
&lt;li&gt;Keeps your changes &lt;strong&gt;staged&lt;/strong&gt; for a new commit.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;git reset --hard &amp;lt;COMMITHASH&amp;gt;&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Resets the branch and &lt;strong&gt;discards all changes&lt;/strong&gt; (both staged and unstaged).&lt;/li&gt;
&lt;li&gt;Caution: &lt;strong&gt;Irreversible&lt;/strong&gt;, all uncommitted changes are lost.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Soft Reset&lt;/strong&gt; (keep changes staged):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  git reset --soft HEAD~2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hard Reset&lt;/strong&gt; (discard changes):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  git reset --hard abc1234
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Warning:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hard reset&lt;/strong&gt; is irreversible. It will permanently discard any uncommitted changes, so use it with caution. Always make sure you've saved or committed your important work before performing a &lt;code&gt;--hard&lt;/code&gt; reset.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  .gitignore
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;.gitignore&lt;/code&gt; file is a &lt;strong&gt;hidden file&lt;/strong&gt; (it starts with a dot) that tells Git which files or directories to ignore in a project. It's used to prevent unnecessary or sensitive files (such as build artifacts, logs, or configuration files) from being tracked in version control.&lt;/p&gt;

&lt;h3&gt;
  
  
  How It Works:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Global &lt;code&gt;.gitignore&lt;/code&gt;&lt;/strong&gt;: This is typically located in the root directory of your project and applies to the entire repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local &lt;code&gt;.gitignore&lt;/code&gt;&lt;/strong&gt;: You can also have &lt;code&gt;.gitignore&lt;/code&gt; files in &lt;strong&gt;subdirectories&lt;/strong&gt;. These will apply only to files within that specific subdirectory, allowing for more granular control.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Root &lt;code&gt;.gitignore&lt;/code&gt;&lt;/strong&gt; (ignores &lt;code&gt;*.log&lt;/code&gt; files everywhere):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  *.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Subdirectory &lt;code&gt;.gitignore&lt;/code&gt;&lt;/strong&gt; (in a &lt;code&gt;logs/&lt;/code&gt; directory, ignores &lt;code&gt;*.tmp&lt;/code&gt; files there):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  logs/*.tmp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, the &lt;code&gt;*.log&lt;/code&gt; files will be ignored everywhere in the repository, but only the &lt;code&gt;*.tmp&lt;/code&gt; files within the &lt;code&gt;logs/&lt;/code&gt; directory will be ignored.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Points:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You can have &lt;code&gt;.gitignore&lt;/code&gt; files in &lt;strong&gt;multiple directories&lt;/strong&gt;, and each one applies to files within that directory and its subdirectories.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.gitignore&lt;/code&gt; works based on relative paths. You can specify files or folders to ignore, or use wildcards like &lt;code&gt;*.log&lt;/code&gt; or &lt;code&gt;**/temp/&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example Structure:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/project-root
  .gitignore       # ignores *.log globally
  /logs
    .gitignore     # ignores *.tmp in the logs directory
    error.log      # will be ignored because of the global .gitignore
    temp.tmp       # will be ignored because of the subdirectory .gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This flexibility helps manage which files should be tracked and which should remain local to the development environment.&lt;/p&gt;




&lt;p&gt;Always &lt;strong&gt;RTFM&lt;/strong&gt; (Read The Freaking Manual) before asking people with experience. Understanding the fundamentals and referring to the official documentation will not only save you time but also help you grasp concepts more thoroughly.&lt;/p&gt;

&lt;p&gt;Revise Git on a weekly basis to keep your skills sharp, and the best way to do this is by integrating Git into the projects you're actively working on. By using it regularly, you'll become more comfortable with advanced features and workflows, which will make version control feel like second nature.&lt;/p&gt;

&lt;p&gt;This is part 1 of the series, and part 2 is coming soon! Stay tuned for more insights on mastering Git.&lt;/p&gt;

</description>
      <category>git</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
