<?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" version="2.0"><channel><title><![CDATA[Amaresh Pati]]></title><description><![CDATA[Readers can expect practical, real-world-focused technical content centred around modern web and mobile development. The blog covers React, React Native, JavaScript, backend integration, performance optimisation, architecture patterns, and developer productivity. Content is written to be clear, hands-on, and implementation-driven — helping developers understand concepts deeply and apply them effectively in real projects.]]></description><link>https://blogs.devvloper.in</link><generator>RSS for Node</generator><lastBuildDate>Fri, 24 Apr 2026 10:43:37 GMT</lastBuildDate><atom:link href="https://blogs.devvloper.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[# Git Adventures --- Part 2: When Git Starts Judging Your Decisions]]></title><description><![CDATA[In Part 1, everything was clean. Repository created. Project initialized. Branches created. Team motivated.
That illusion lasted exactly one day.
Because on Day 2, the team learned an important truth:]]></description><link>https://blogs.devvloper.in/git-adventures-part-2-when-git-starts-judging-your-decisions</link><guid isPermaLink="true">https://blogs.devvloper.in/git-adventures-part-2-when-git-starts-judging-your-decisions</guid><dc:creator><![CDATA[Amaresh Pati]]></dc:creator><pubDate>Thu, 26 Mar 2026 12:46:36 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6984b789addfcf584cb5a823/56528a61-61df-4ada-89b6-017fa3816146.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In Part 1, everything was clean. Repository created. Project initialized. Branches created. Team motivated.</p>
<p>That illusion lasted exactly one day.</p>
<p>Because on Day 2, the team learned an important truth: <strong>Writing code is easy. Understanding history is hard.</strong></p>
<p>And Git remembers everything.</p>
<hr />
<h2>Chapter 1 --- The Calm Before the Debugging Storm</h2>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wb8n8osxaefk6wsaibd8.png" alt="Image description" style="display:block;margin:0 auto" />

<p>Amaresh notices something feels wrong after pulling updates. A feature that worked yesterday is broken. When did this happen?</p>
<p>He opens the timeline:</p>
<pre><code class="language-bash">git log --oneline
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">a3f9c2b Add authentication flow
9d1a2e4 Fix validation issue
c81be77 Initial setup
</code></pre>
<p>Each commit shows a short hash (abbreviated commit ID) and message.</p>
<p><strong>When you need the full commit ID:</strong></p>
<pre><code class="language-bash">git log
</code></pre>
<p>Or to just grab HEAD's full ID:</p>
<pre><code class="language-bash">git rev-parse HEAD
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">a3f9c2b7d8e9f0a1b2c3d4e5f6g7h8i9
</code></pre>
<p><strong>Pro tip:</strong> Use <code>git log --oneline -n 20</code> to see only the last 20 commits. Saves scrolling through months of history.</p>
<p><strong>The gotcha:</strong> <code>git log</code> shows commits in reverse chronological order (newest first). If you're looking for <em>when</em> something broke, scroll down, not up.</p>
<p><strong>Commit IDs are your time machine.</strong> They allow precise navigation through Git history—and they're immutable. The same commit ID always points to the exact same code, forever.</p>
<hr />
<h2>Chapter 2 --- Understanding What Actually Changed</h2>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b83y3b6jfme6j5e2v0e2.png" alt="Image description" style="display:block;margin:0 auto" />

<p>Amaresh needs to see <em>exactly</em> what was changed. Not just which files, but which lines.</p>
<pre><code class="language-bash">git diff
</code></pre>
<p>Output:</p>
<pre><code class="language-diff">diff --git a/auth.js b/auth.js
index 1a2b3c4..5d6e7f8 100644
--- a/auth.js
+++ b/auth.js
@@ -12,7 +12,7 @@
  function validateToken(token) {
-   if (token.length &lt; 32) {
+   if (token.length &lt; 16) {
      return false;
    }
</code></pre>
<p>Git highlights <strong>removed lines</strong> in red (with <code>-</code>) and <strong>added lines</strong> in green (with <code>+</code>).</p>
<p><strong>Compare two branches:</strong></p>
<pre><code class="language-bash">git diff main feat/authentication
</code></pre>
<p>This shows all changes in <code>feat/authentication</code> that aren't in <code>main</code>.</p>
<p><strong>Compare two commits:</strong></p>
<pre><code class="language-bash">git diff a3f9c2b 9d1a2e4
</code></pre>
<p><strong>See only filenames (not the code):</strong></p>
<pre><code class="language-bash">git diff --name-only main feat/authentication
</code></pre>
<p><strong>See file statistics:</strong></p>
<pre><code class="language-bash">git diff --stat main feat/authentication
</code></pre>
<p>Output:</p>
<pre><code class="language-diff">auth.js     | 15 ++++++++++++---
utils.js    |  8 ++------
 2 files changed, 14 insertions(+), 9 deletions(-)
</code></pre>
<p><strong>The gotcha:</strong> <code>git diff</code> with no arguments shows <strong>unstaged changes only</strong>. If you've already run <code>git add</code>, you won't see those changes. Use <code>git diff --staged</code> to see staged changes.</p>
<hr />
<h2>Chapter 3 --- Inspecting a Single Decision</h2>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4ohplfhhdml9eoxzxpqc.png" alt="Image description" style="display:block;margin:0 auto" />

<p>Johnny broke something three commits ago. Now Amaresh needs to see exactly what that commit changed.</p>
<pre><code class="language-bash">git show a3f9c2b
</code></pre>
<p>Output:</p>
<pre><code class="language-diff">commit a3f9c2b7d8e9f0a1b2c3d4e5f6g7h8i9
Author: Johnny &lt;johnny@company.com&gt;
Date:   Wed Mar 24 14:32:15 2026 +0530

    Add authentication flow

diff --git a/auth.js b/auth.js
new file mode 100644
index 0000000..a1b2c3d
--- /dev/null
+++ b/auth.js
@@ -0,0 +1,45 @@
+function authenticate(user, password) {
...
</code></pre>
<p><code>git show</code> displays:</p>
<ul>
<li><p><strong>Author</strong> — who made the change</p>
</li>
<li><p><strong>Date</strong> — when it was committed</p>
</li>
<li><p><strong>Message</strong> — the commit description</p>
</li>
<li><p><strong>Full diff</strong> — every line added/removed</p>
</li>
</ul>
<p><strong>See just the commit message:</strong></p>
<pre><code class="language-bash">git show a3f9c2b --format=fuller
</code></pre>
<p><strong>Use with current HEAD:</strong></p>
<pre><code class="language-bash">git show HEAD
</code></pre>
<p><strong>This is your bug detective tool.</strong> When you find a broken line, you can track exactly when it was added and by whom.</p>
<p><strong>The gotcha:</strong> If a commit only renamed a file without changing it, <code>git show</code> will say "similarity index 100%" but show no actual changes. The file content is identical.</p>
<hr />
<h2>Chapter 4 --- The Unexpected Urgent Task</h2>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gp0bedmbyur7t5ktwsd0.png" alt="Image description" style="display:block;margin:0 auto" />

<p>Danny has been working on a feature for hours. Code is half-written, tests are incomplete. Then a critical production bug appears, and he must switch branches immediately.</p>
<p>He can't commit incomplete work (it breaks the build). He can't lose his changes. So he uses:</p>
<pre><code class="language-bash">git stash
</code></pre>
<p>This saves all changes to a temporary location and resets the working directory to the last commit.</p>
<pre><code class="language-bash">git checkout hotfix/critical-bug
# Fix the bug, commit, merge back to main
git checkout feat/incomplete-feature
</code></pre>
<p>Now he gets his incomplete work back:</p>
<pre><code class="language-bash">git stash pop
</code></pre>
<p><strong>But there's a problem:</strong> He had created a new file (<code>utils.js</code>) that hadn't been staged. After stashing and popping, the file is gone.</p>
<p>That's because <code>git stash</code> by default only saves <strong>tracked</strong> files (files Git already knows about). New files are left behind.</p>
<p><strong>The solution:</strong></p>
<pre><code class="language-bash">git stash -u
</code></pre>
<p>The <code>-u</code> (or <code>--include-untracked</code>) flag tells Git to stash everything, including brand new files.</p>
<p><strong>Better yet, use this to be safe:</strong></p>
<pre><code class="language-bash">git stash -u -m "WIP: authentication feature with new utils"
</code></pre>
<p>The <code>-m</code> flag lets you label the stash so you remember what's in it.</p>
<p><strong>View all stashes:</strong></p>
<pre><code class="language-bash">git stash list
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">stash@{0}: WIP: authentication feature with new utils
stash@{1}: WIP: fixing typo in validator
stash@{2}: On main: saving work
</code></pre>
<p><strong>Pop a specific stash:</strong></p>
<pre><code class="language-bash">git stash pop stash@{1}
</code></pre>
<p><strong>Delete a stash without popping:</strong></p>
<pre><code class="language-bash">git stash drop stash@{0}
</code></pre>
<p><strong>Clear all stashes (⚠️ dangerous):</strong></p>
<pre><code class="language-bash">git stash clear
</code></pre>
<p><strong>The gotcha:</strong> <code>git stash pop</code> removes the stash after applying it. If the pop fails (merge conflict), the stash stays safe. But if it succeeds and you later realize you needed it, it's gone. Use <code>git stash apply</code> instead if you want to keep the stash around.</p>
<hr />
<h2>Chapter 5 --- The First Real Merge Conflict</h2>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ep1dypi6z5hr20fi094z.png" alt="Image description" style="display:block;margin:0 auto" />

<p>Johnny finishes his service-layer feature. Ronaldo finishes his database optimization feature. Both edited the same file. Johnny tries to merge Ronaldo's branch:</p>
<pre><code class="language-bash">git merge feat/service-layer
</code></pre>
<p>Git responds:</p>
<pre><code class="language-plaintext">Auto-merging api.js
CONFLICT (content): Merge conflict in api.js
Automatic merge failed; fix conflicts and then commit the result.
</code></pre>
<p>He opens <code>api.js</code> and sees:</p>
<pre><code class="language-javascript">function handleRequest(req, res) {
&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD
  // Ronaldo's code (database optimization)
  const data = db.query(req.id);
  res.send(data);
=======
  // Johnny's code (service layer)
  const service = new Service();
  const data = service.fetch(req.id);
  res.send(data);
&gt;&gt;&gt;&gt;&gt;&gt;&gt; feat/service-layer
}
</code></pre>
<p>The conflict markers show:</p>
<ul>
<li><p><code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD</code> — start of current branch (what you have now)</p>
</li>
<li><p><code>=======</code> — divider</p>
</li>
<li><p><code>&gt;&gt;&gt;&gt;&gt;&gt;&gt; feat/service-layer</code> — end of incoming branch (what you're merging in)</p>
</li>
</ul>
<p><strong>Johnny must decide:</strong> Keep Ronaldo's code? Keep his own? Use both?</p>
<p>He decides to use his service layer but call the optimized query:</p>
<pre><code class="language-javascript">function handleRequest(req, res) {
  const service = new Service();
  const data = service.fetch(req.id); // Johnny's code
  // Ronaldo's optimization is now inside service.fetch()
  res.send(data);
}
</code></pre>
<p>Now resolve the conflict:</p>
<pre><code class="language-bash">git add api.js
git commit -m "Merge feat/service-layer: resolve conflict in api.js"
</code></pre>
<p><strong>Tools to help with conflicts:</strong></p>
<pre><code class="language-bash"># See which files have conflicts
git diff --name-only --diff-filter=U

# Use a visual merge tool (if configured)
git mergetool
</code></pre>
<p><strong>Abort a merge if you're not ready:</strong></p>
<pre><code class="language-bash">git merge --abort
</code></pre>
<p><strong>The gotcha:</strong> Merge conflicts are not errors—they're Git asking you to make a decision. A merge with zero conflicts often means someone's code got silently overwritten. Conflicts are actually good; they force you to think.</p>
<hr />
<h2>Chapter 6 --- Fetch vs Pull vs Merge (The Confusion Explained)</h2>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/emiorkgktx4aaltbo9z8.png" alt="Image description" style="display:block;margin:0 auto" />

<p>Many developers use these terms interchangeably. They're not.</p>
<p><code>git fetch</code> — Downloads changes from remote, but doesn't integrate them:</p>
<pre><code class="language-bash">git fetch origin
</code></pre>
<p>This updates your local tracking branches (<code>origin/main</code>, <code>origin/feat/something</code>) but leaves your local <code>main</code> branch untouched.</p>
<p><code>git merge</code> — Combines histories:</p>
<pre><code class="language-bash">git merge origin/main
</code></pre>
<p>This integrates the remote changes into your current branch.</p>
<p><code>git pull</code> — Fetch + merge in one command:</p>
<pre><code class="language-bash">git pull origin main
</code></pre>
<p>Equivalent to:</p>
<pre><code class="language-bash">git fetch origin
git merge origin/main
</code></pre>
<p><strong>Why does this matter?</strong></p>
<p>The <strong>professional workflow</strong> is:</p>
<pre><code class="language-bash">git fetch origin          # Download changes
git log main origin/main  # Inspect what changed
git merge origin/main     # Merge when ready
</code></pre>
<p>Why? Because <code>git pull</code> can silently create merge commits you didn't expect. Fetching first lets you review changes before integrating them.</p>
<p><strong>Comparison table:</strong></p>
<table>
<thead>
<tr>
<th>Command</th>
<th>Changes local branch?</th>
<th>Creates merge commit?</th>
<th>Safe to use blindly?</th>
</tr>
</thead>
<tbody><tr>
<td><code>git fetch</code></td>
<td>❌ No</td>
<td>❌ No</td>
<td>✅ Yes</td>
</tr>
<tr>
<td><code>git merge</code></td>
<td>✅ Yes</td>
<td>✅ Maybe</td>
<td>⚠️ Only if branches are synced</td>
</tr>
<tr>
<td><code>git pull</code></td>
<td>✅ Yes</td>
<td>✅ Usually</td>
<td>⚠️ Can surprise you</td>
</tr>
</tbody></table>
<p><strong>The gotcha:</strong> <code>git pull</code> can create a merge commit automatically. If you're trying to keep a clean history, this is annoying. Use <code>git pull --rebase</code> to rebase instead of merge (we'll cover rebase in Part 3).</p>
<hr />
<h2>Chapter 7 --- Undoing Mistakes Properly</h2>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bxkglkg3f2i8c50imc7c.png" alt="Image description" style="display:block;margin:0 auto" />

<p>Mistakes happen. Git gives you three different ways to undo, and they each do something different.</p>
<h3>Mistake Type 1: "I edited a file but haven't staged it"</h3>
<p>Amaresh edited <code>config.js</code> but realizes it's wrong. He hasn't run <code>git add</code> yet.</p>
<pre><code class="language-bash">git restore config.js
</code></pre>
<p>This overwrites <code>config.js</code> with the version from the last commit. Changes are gone.</p>
<p><strong>Old syntax (still works):</strong></p>
<pre><code class="language-bash">git checkout config.js
</code></pre>
<hr />
<h3>Mistake Type 2: "I staged changes I shouldn't have"</h3>
<p>Amaresh ran <code>git add .</code> and included <code>config.js</code> accidentally. He hasn't committed yet.</p>
<pre><code class="language-bash">git restore --staged config.js
</code></pre>
<p>This unstages the file. The file still exists in your working directory with all changes intact—only the staging is removed.</p>
<p><strong>Undo all staged changes:</strong></p>
<pre><code class="language-bash">git restore --staged .
</code></pre>
<hr />
<h3>Mistake Type 3: "I committed something wrong but haven't pushed"</h3>
<p>Johnny committed buggy code. It's in his local history but not on GitHub yet.</p>
<pre><code class="language-bash">git reset HEAD~1
</code></pre>
<p>This moves the branch pointer back one commit. The buggy commit disappears from history. But the files are still in your working directory with changes intact.</p>
<pre><code class="language-bash"># Edit the files, fix the bug
git add .
git commit -m "Fixed version of that commit"
</code></pre>
<p><strong>The variants:</strong></p>
<pre><code class="language-bash">git reset --soft HEAD~1   # Undo commit, keep changes staged
git reset --mixed HEAD~1  # Undo commit, keep changes unstaged (default)
git reset --hard HEAD~1   # Undo commit, DISCARD all changes (⚠️ dangerous)
</code></pre>
<p><strong>The gotcha:</strong> <code>git reset --hard</code> is permanent. Your code is deleted. If you haven't pushed, you can use <code>git reflog</code> to recover, but it's nerve-wracking. Default to <code>--mixed</code> or <code>--soft</code>.</p>
<hr />
<h3>Mistake Type 4: "I committed bad code that's already pushed"</h3>
<p>Ronaldo pushed a commit that broke production. He can't just <code>git reset</code> because others have already pulled his changes. Rewriting history would break their local repos.</p>
<pre><code class="language-bash">git revert a3f9c2b
</code></pre>
<p>This creates a <strong>new commit</strong> that undoes the changes from commit <code>a3f9c2b</code>. Git history stays intact. Everyone can pull the revert safely.</p>
<p>Output:</p>
<pre><code class="language-plaintext">[main 7f8e9d0] Revert "Add broken authentication"
 1 file changed, 2 deletions(-)
</code></pre>
<p>Now the repo is fixed, and history shows exactly what happened.</p>
<p><strong>Compare the three approaches:</strong></p>
<table>
<thead>
<tr>
<th>Situation</th>
<th>Command</th>
<th>Creates new commit?</th>
<th>Safe to push?</th>
<th>Reversible?</th>
</tr>
</thead>
<tbody><tr>
<td>Unstaged file mess</td>
<td><code>git restore</code></td>
<td>❌ No</td>
<td>✅ N/A</td>
<td>❌ Deleted</td>
</tr>
<tr>
<td>Staged file mess</td>
<td><code>git restore --staged</code></td>
<td>❌ No</td>
<td>✅ N/A</td>
<td>✅ Still in working dir</td>
</tr>
<tr>
<td>Wrong local commit</td>
<td><code>git reset</code></td>
<td>❌ No</td>
<td>❌ Rewrites history</td>
<td>✅ Use <code>git reflog</code></td>
</tr>
<tr>
<td>Pushed bad commit</td>
<td><code>git revert</code></td>
<td>✅ Yes</td>
<td>✅ Safe</td>
<td>✅ Fully reversible</td>
</tr>
</tbody></table>
<hr />
<h2>The Safety Net: <code>git reflog</code></h2>
<p>Here's the command nobody tells you about until you need it.</p>
<p>Amaresh ran <code>git reset --hard</code> and deleted code he wanted. Is it gone forever?</p>
<pre><code class="language-bash">git reflog
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">a3f9c2b HEAD@{0}: reset: moving to HEAD~1
9d1a2e4 HEAD@{1}: commit: Add authentication flow
c81be77 HEAD@{2}: commit: Initial setup
</code></pre>
<p>The reflog shows every place HEAD has been. He can recover:</p>
<pre><code class="language-bash">git reset --hard HEAD@{1}
</code></pre>
<p><strong>The safety net catches you.</strong> Use this when you panic after a hard reset.</p>
<hr />
<h2>Quick Reference Cheat Sheet</h2>
<table>
<thead>
<tr>
<th>Problem</th>
<th>Command</th>
<th>Result</th>
</tr>
</thead>
<tbody><tr>
<td>View commit history</td>
<td><code>git log --oneline</code></td>
<td>Shows last commits</td>
</tr>
<tr>
<td>See what changed</td>
<td><code>git diff</code></td>
<td>Shows unstaged changes</td>
</tr>
<tr>
<td>See staged changes</td>
<td><code>git diff --staged</code></td>
<td>Shows changes ready to commit</td>
</tr>
<tr>
<td>Compare branches</td>
<td><code>git diff main feat/new</code></td>
<td>Shows differences</td>
</tr>
<tr>
<td>Inspect a commit</td>
<td><code>git show &lt;commit-id&gt;</code></td>
<td>Shows commit details</td>
</tr>
<tr>
<td>Save work temporarily</td>
<td><code>git stash -u -m "label"</code></td>
<td>Saves including untracked files</td>
</tr>
<tr>
<td>Restore saved work</td>
<td><code>git stash pop</code></td>
<td>Applies last stash</td>
</tr>
<tr>
<td>Download remote changes</td>
<td><code>git fetch origin</code></td>
<td>Safe, doesn't merge</td>
</tr>
<tr>
<td>Download + merge</td>
<td><code>git pull</code></td>
<td>Fetch + merge in one</td>
</tr>
<tr>
<td>Undo unstaged changes</td>
<td><code>git restore &lt;file&gt;</code></td>
<td>Discards edits to file</td>
</tr>
<tr>
<td>Unstage changes</td>
<td><code>git restore --staged &lt;file&gt;</code></td>
<td>Keeps changes, removes from staging</td>
</tr>
<tr>
<td>Undo last commit (local)</td>
<td><code>git reset HEAD~1</code></td>
<td>Moves branch back</td>
</tr>
<tr>
<td>Undo last commit (pushed)</td>
<td><code>git revert &lt;commit-id&gt;</code></td>
<td>Creates undo commit</td>
</tr>
<tr>
<td>Undo hard reset</td>
<td><code>git reflog</code></td>
<td>Shows all HEAD positions</td>
</tr>
</tbody></table>
<hr />
<p>By the end of Day 2, the team realized something important:</p>
<p>Git doesn't judge you for making mistakes. <strong>It judges you for not knowing how to recover from them.</strong></p>
<p><strong>Master these commands, and you'll never panic:</strong></p>
<ul>
<li><p><code>git log</code> + <code>git show</code> — understand what happened</p>
</li>
<li><p><code>git diff</code> — see exactly what changed</p>
</li>
<li><p><code>git stash</code> — escape from immediate problems</p>
</li>
<li><p><code>git restore</code> / <code>git reset</code> / <code>git revert</code> — fix them the right way</p>
</li>
<li><p><code>git reflog</code> — panic button</p>
</li>
</ul>
<hr />
<h2>End of Part 2</h2>
<p><strong>The team learned:</strong></p>
<ul>
<li><p><code>git log --oneline</code> — time machine for commits</p>
</li>
<li><p><code>git diff</code> — see changes precisely</p>
</li>
<li><p><code>git show</code> — inspect a single commit</p>
</li>
<li><p><code>git stash -u</code> — save incomplete work</p>
</li>
<li><p>Merge conflicts — human decisions required</p>
</li>
<li><p><code>git fetch</code> vs <code>git pull</code> — when to use which</p>
</li>
<li><p><code>git restore</code> vs <code>git reset</code> vs <code>git revert</code> — right tool for the job</p>
</li>
<li><p><code>git reflog</code> — the safety net</p>
</li>
</ul>
<hr />
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ez324ex5hvcve0s79dub.png" alt="Image description" style="display:block;margin:0 auto" />

<h2>What's Coming in Part 3</h2>
<ul>
<li><p><strong>Rebase</strong> — rewriting history (safely)</p>
</li>
<li><p><strong>Interactive rebase</strong> — rearranging commits</p>
</li>
<li><p><strong>Cherry-pick</strong> — copying specific commits</p>
</li>
<li><p><strong>Tagging</strong> — marking important versions</p>
</li>
<li><p><strong>Rebasing vs Merging</strong> — the great Git debate</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Git Adventures --- Part 1: Five Developers, One Repo, and the "It Works on My Machine" Era]]></title><description><![CDATA[Every software project begins the same way.
Someone says, "Let's build something amazing."
Ten minutes later, someone asks:

"Wait... who created the Git repo?"

This is the story of a five-person dev]]></description><link>https://blogs.devvloper.in/git-adventures-part-1-five-developers-one-repo-and-the-it-works-on-my-machine-era</link><guid isPermaLink="true">https://blogs.devvloper.in/git-adventures-part-1-five-developers-one-repo-and-the-it-works-on-my-machine-era</guid><category><![CDATA[Git]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[development]]></category><category><![CDATA[version control]]></category><category><![CDATA[Gitcommands]]></category><category><![CDATA[workflow]]></category><dc:creator><![CDATA[Amaresh Pati]]></dc:creator><pubDate>Mon, 09 Mar 2026 18:02:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6984b789addfcf584cb5a823/9c0b760a-66d4-451e-bb6c-7cc8cc1a4595.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every software project begins the same way.</p>
<p>Someone says, <strong>"Let's build something amazing."</strong></p>
<p>Ten minutes later, someone asks:</p>
<blockquote>
<p>"Wait... who created the Git repo?"</p>
</blockquote>
<p>This is the story of a five-person development team starting their first project together.</p>
<p>Meet the team.</p>
<p><strong>Virat --- The Repo Master</strong> Responsible for repositories and access control.</p>
<p><strong>Amaresh --- The Architect</strong> designs the project structure and keeps the codebase organised.</p>
<p><strong>Johnny, Danny, Ronaldo --- The Feature Crew:</strong> Three developers who will build features, write code, and occasionally break things.</p>
<p>Today is <strong>Day 1</strong>.</p>
<p>And the project begins with the most important step in any software project.</p>
<p>Creating the repository.</p>
<hr />
<h1>Chapter 1 --- The Repo Is Born</h1>
<p>Virat opens his terminal and announces that the project officially begins.</p>
<pre><code class="language-bash">mkdir project-hyperdrive
cd project-hyperdrive
</code></pre>
<p>Now he initialises Git.</p>
<pre><code class="language-bash">git init
</code></pre>
<p>Git responds:</p>
<pre><code class="language-plaintext">Initialized empty Git repository
</code></pre>
<p>Behind the scenes, something important just happened.</p>
<p>Git created a hidden folder called:</p>
<pre><code class="language-plaintext">.git
</code></pre>
<p>This folder stores everything Git needs:</p>
<ul>
<li><p>commit history</p>
</li>
<li><p>branches</p>
</li>
<li><p>logs</p>
</li>
<li><p>references</p>
</li>
<li><p>repository metadata</p>
</li>
</ul>
<p>Without <code>.git</code>the folder is just a normal directory.</p>
<p>With <code>.git</code> It becomes a <strong>version-controlled project</strong>.</p>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vjd7y1rskydsvgc134ry.png" alt="Image description" style="display:block;margin:0 auto" />

<hr />
<h1>Chapter 2 --- The Architect Builds the Foundation</h1>
<p>Virat turns to Amaresh.</p>
<p>The repository exists now, but a repository without files is like a city without buildings.</p>
<p>Amaresh prepares the <strong>initial project structure</strong> on his machine.</p>
<p>He checks what Git sees.</p>
<pre><code class="language-bash">git status
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Untracked files:
README.md
src/
config/
</code></pre>
<p>Git sees the files but does not track them automatically.</p>
<p>Developers must tell Git which files should be tracked.</p>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mfk42n367eukvf03frfs.png" alt="Image description" style="display:block;margin:0 auto" />

<hr />
<h1>Chapter 3 --- Connecting the Two Worlds</h1>
<p>Virat created the repository on <strong>his machine</strong>, and Amaresh prepared the project on <strong>his laptop</strong>.</p>
<p>Johnny asks:</p>
<blockquote>
<p>"How are we working in the same repository?"</p>
</blockquote>
<p>Virat explains.</p>
<pre><code class="language-plaintext">Local Repository → developer machines
Remote Repository → shared server
</code></pre>
<p>Virat connects his repository to the remote server.</p>
<pre><code class="language-bash">git remote add origin https://company-repo/project.git
git push -u origin main
</code></pre>
<p>Amaresh connects his machine to the same repository.</p>
<pre><code class="language-bash">git remote add origin https://company-repo/project.git
git pull origin main
</code></pre>
<p>Now both machines share the <strong>same Git history</strong>.</p>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mup6olv2fyo8j4he5nrj.png" alt="Image description" style="display:block;margin:0 auto" />

<hr />
<h1>Chapter 4 --- Teaching Git What to Remember</h1>
<p>Amaresh stages the project files.</p>
<pre><code class="language-bash">git add .
</code></pre>
<p>The dot (<code>.</code>) means <strong>add everything inside the current directory</strong>.</p>
<p>Git workflow:</p>
<pre><code class="language-plaintext">Working Directory → Staging Area → Commit History
</code></pre>
<p>Staging allows developers to choose which files should go into the next commit.</p>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p23h1dk2us0yw9rin1wt.png" alt="Image description" style="display:block;margin:0 auto" />

<hr />
<h1>Chapter 5 --- The First Commit</h1>
<p>Amaresh creates the first commit.</p>
<pre><code class="language-bash">git commit -m "Initial project setup"
</code></pre>
<p>A commit is a <strong>snapshot of the project at a specific moment</strong>.</p>
<p>Each commit records:</p>
<ul>
<li><p>changes</p>
</li>
<li><p>author</p>
</li>
<li><p>time</p>
</li>
<li><p>commit message</p>
</li>
</ul>
<hr />
<h1>Chapter 6 --- Sharing the Repo With the Team</h1>
<p>Virat grants repository access to the team.</p>
<p>Johnny clones the repository.</p>
<pre><code class="language-bash">git clone https://company-repo/project.git
</code></pre>
<p>Danny checks the status.</p>
<pre><code class="language-bash">git status
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">On branch main
Your branch is up to date with origin/main
</code></pre>
<p>Everyone is synchronised.</p>
<hr />
<h1>Chapter 7 --- The Branching Rules</h1>
<p>The <code>main</code> The branch must always remain stable.</p>
<p>Developers create branches for their work.</p>
<h3>Feature</h3>
<pre><code class="language-plaintext">feat/login-system
feat/payment-module
</code></pre>
<h3>Bugfix</h3>
<pre><code class="language-plaintext">bugfix/login-validation
bugfix/crash-on-start
</code></pre>
<h3>Hotfix</h3>
<pre><code class="language-plaintext">hotfix/security-patch
hotfix/payment-crash
</code></pre>
<h3>Chore</h3>
<pre><code class="language-plaintext">chore/update-dependencies
</code></pre>
<h3>Docs</h3>
<pre><code class="language-plaintext">docs/setup-guide
</code></pre>
<h3>Refactor</h3>
<pre><code class="language-plaintext">refactor/auth-module
</code></pre>
<h3>Style</h3>
<pre><code class="language-plaintext">style/code-formatting
</code></pre>
<h3>Test</h3>
<pre><code class="language-plaintext">test/auth-tests
</code></pre>
<h3>Performance</h3>
<pre><code class="language-plaintext">perf/query-optimization
</code></pre>
<h3>Release</h3>
<pre><code class="language-plaintext">release/v1.0
</code></pre>
<p>Workflow:</p>
<pre><code class="language-plaintext">Create branch → Commit → Push → Pull Request → Review → Merge
</code></pre>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x2nfv9xnf6uijgzl5bsj.png" alt="Image description" style="display:block;margin:0 auto" />

<hr />
<h1>Chapter 8 --- The Feature Crew Begins</h1>
<p>Amaresh assigns tasks.</p>
<p>Johnny:</p>
<pre><code class="language-plaintext">git checkout -b feat/authentication
</code></pre>
<p>Danny:</p>
<pre><code class="language-plaintext">git checkout -b feat/profile-system
</code></pre>
<p>Ronaldo:</p>
<pre><code class="language-plaintext">git checkout -b feat/service-integration
</code></pre>
<p>Three developers.</p>
<p>Three branches.</p>
<p>One repository.</p>
<p>And somewhere in the future...</p>
<p>A merge conflict is waiting.</p>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vy45khp7yiae6h7l81j6.png" alt="Image description" style="display:block;margin:0 auto" />

<hr />
<h1>End of Part 1</h1>
<p>What the team learned:</p>
<ul>
<li><p>git init</p>
</li>
<li><p>git status</p>
</li>
<li><p>git add</p>
</li>
<li><p>git commit</p>
</li>
<li><p>git remote</p>
</li>
<li><p>git push</p>
</li>
<li><p>git clone</p>
</li>
<li><p>git branch</p>
</li>
</ul>
<p>Branch naming examples:</p>
<pre><code class="language-plaintext">feat/
bugfix/
hotfix/
docs/
chore/
refactor/
style/
test/
perf/
release/
</code></pre>
<hr />
<h1>What Happens in Part 2</h1>
<p>In the next part, the team will learn:</p>
<ul>
<li><p>PR creation</p>
</li>
<li><p><code>git log</code></p>
</li>
<li><p><code>git diff</code></p>
</li>
<li><p><code>git show</code></p>
</li>
<li><p><code>git stash</code></p>
</li>
<li><p>resolving merge conflicts</p>
</li>
</ul>
<p>Follow the series for <strong>Part 2</strong>.</p>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jmt1oy87wnh4brpl9pp1.png" alt="Image description" style="display:block;margin:0 auto" />]]></content:encoded></item><item><title><![CDATA[Tools AI Can’t Replace (But Every Developer Should Use)]]></title><description><![CDATA[As developers, we keep discovering tools that quietly make our lives easier.Not flashy. Not hyped. Just… effective.
These are three tools I keep coming back to because they remove friction from my workflow.They save time, reduce mental load, and let ...]]></description><link>https://blogs.devvloper.in/tools-ai-cant-replace-but-every-developer-should-use</link><guid isPermaLink="true">https://blogs.devvloper.in/tools-ai-cant-replace-but-every-developer-should-use</guid><category><![CDATA[frontend]]></category><category><![CDATA[development]]></category><category><![CDATA[Developer]]></category><category><![CDATA[tools]]></category><category><![CDATA[full stack]]></category><dc:creator><![CDATA[Amaresh Pati]]></dc:creator><pubDate>Tue, 17 Feb 2026 04:50:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1770635137559/8f38d340-af97-455c-89c6-44f83481c4ad.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As developers, we keep discovering tools that quietly make our lives easier.<br />Not flashy. Not hyped. Just… effective.</p>
<p>These are three tools I keep coming back to because they <strong>remove friction from my workflow</strong>.<br />They save time, reduce mental load, and let me focus on building features instead of fighting setup, data, or formats.</p>
<hr />
<h2 id="heading-dummyjson-an-instant-backend-for-frontend-work">DummyJSON — An Instant Backend for Frontend Work</h2>
<p>🔗 https://dummyjson.com</p>
<p>When I start working on a new feature, backend readiness is often the bottleneck.<br />DummyJSON removes that problem entirely.</p>
<p>It gives you custom &amp; ready-to-use REST APIs with realistic data — users, products, posts, todos, comments, and more — without any setup.</p>
<h3 id="heading-why-its-genuinely-useful">Why it’s genuinely useful</h3>
<ul>
<li>Create <strong>custom APIs</strong> using your own JSON  </li>
<li>Ready endpoints like <code>/products</code>, <code>/users</code>, <code>/todos</code>, <code>/posts</code>  </li>
<li>Full HTTP support: <code>GET</code>, <code>POST</code>, <code>PUT</code>, <code>PATCH</code>, <code>DELETE</code>  </li>
<li>Pagination, search, and filtering built in  </li>
<li>Zero setup. Zero configuration.</li>
</ul>
<h3 id="heading-how-it-helps-me">How it helps me</h3>
<ul>
<li>I build UI and business logic without waiting on backend completion  </li>
<li>I can test real-world scenarios like loading states and empty responses  </li>
<li>No need to maintain mock servers or fake data generators  </li>
</ul>
<p>Instead of guessing how data <em>might</em> look, I work with something close to production from day one.</p>
<hr />
<h2 id="heading-dummyinbox-clean-email-testing-without-noise">📨 DummyInbox — Clean Email Testing Without Noise</h2>
<p>🔗 https://dummyinbox.com</p>
<p>Testing email-based flows using your real inbox gets messy fast.<br />DummyInbox fixes this with the simplest possible approach.</p>
<p>You get disposable email addresses instantly — no signup, no login, no tracking.</p>
<h3 id="heading-why-i-keep-using-it">Why I keep using it</h3>
<ul>
<li>Instant temporary email addresses  </li>
<li>Auto-expiring inboxes  </li>
<li>No spam in personal or work email  </li>
<li>Unlimited usage, completely free  </li>
</ul>
<h3 id="heading-where-it-fits-in-my-workflow">Where it fits in my workflow</h3>
<ul>
<li>Testing signup and onboarding flows  </li>
<li>Verifying OTPs and confirmation emails  </li>
<li>QA testing notification and alert emails  </li>
</ul>
<p>It does one job — and does it really well.</p>
<hr />
<h2 id="heading-json-crack-making-sense-of-messy-json">🔍 JSON Crack — Making Sense of Messy JSON</h2>
<p>🔗 https://jsoncrack.com/editor</p>
<p>If you work with APIs, you <em>will</em> deal with large, deeply nested JSON responses.<br />JSON Crack turns that chaos into clarity.</p>
<p>Paste your JSON and instantly get a visual tree or graph of the structure.</p>
<h3 id="heading-features-that-actually-matter">Features that actually matter</h3>
<ul>
<li>Interactive visualization of JSON structures  </li>
<li>Supports JSON, YAML, CSV, XML, TOML  </li>
<li>Built-in formatter and validator  </li>
<li>Easy format conversion  </li>
<li>Export visuals for documentation or sharing  </li>
</ul>
<h3 id="heading-how-i-use-it-in-real-life">How I use it in real life</h3>
<ul>
<li>Understand complex API responses copied from Postman  </li>
<li>Debug unexpected nested fields quickly  </li>
<li>Explain payload structures to teammates without long explanations  </li>
</ul>
<p>Scrolling raw JSON is painful.<br />Visualizing it saves time and mental energy.</p>
<hr />
<h2 id="heading-why-these-tools-stick-with-me">🧠 Why These Tools Stick With Me</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Tool</td><td>Problem Solved</td><td>Real Impact</td></tr>
</thead>
<tbody>
<tr>
<td>DummyJSON</td><td>Backend dependency</td><td>Faster frontend development</td></tr>
<tr>
<td>DummyInbox</td><td>Email testing clutter</td><td>Clean QA, zero inbox pollution</td></tr>
<tr>
<td>JSON Crack</td><td>JSON complexity</td><td>Faster debugging &amp; understanding</td></tr>
</tbody>
</table>
</div><p>They don’t replace thinking.<br />They <strong>remove unnecessary effort</strong> — and that’s exactly what good tools should do.</p>
<hr />
<h2 id="heading-shoutout">👏 Shoutout</h2>
<p>A big shoutout to <strong>Ovi</strong><br />👉 https://github.com/Ovi</p>
<p>For building and maintaining <strong>DummyJSON</strong> and <strong>DummyInbox</strong>.</p>
<hr />
<h2 id="heading-final-note">Final Note</h2>
<p>I’ve tried many productivity tools.<br />Most don’t survive daily usage.</p>
<p>These three did — because they solve real problems I face while building products.<br />No hype. Just utility.</p>
<p>If you’re a frontend, mobile, or full-stack developer, chances are these tools will quietly improve your workflow too.</p>
]]></content:encoded></item><item><title><![CDATA[Why I Started Wrapping Everything in React Native?]]></title><description><![CDATA[🚀I’ve been working with React Native for about 4 years now, and one thing I’ve learned the hard way is this:Nothing stays permanent.
Libraries get deprecated.Best practices change.Things that were “recommended” last year suddenly feel wrong today.
A...]]></description><link>https://blogs.devvloper.in/why-i-started-wrapping-everything-in-react-native</link><guid isPermaLink="true">https://blogs.devvloper.in/why-i-started-wrapping-everything-in-react-native</guid><category><![CDATA[React Native]]></category><category><![CDATA[JSX]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Mobile Development]]></category><category><![CDATA[Cross Platform App Development. ]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Amaresh Pati]]></dc:creator><pubDate>Sat, 07 Feb 2026 06:21:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1770444530532/5525ff96-2e26-4b72-a043-6aa04c9db246.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>🚀I’ve been working with React Native for about 4 years now, and one thing I’ve learned the hard way is this:<br />Nothing stays permanent.</p>
<p>Libraries get deprecated.<br />Best practices change.<br />Things that were “recommended” last year suddenly feel wrong today.</p>
<p>At some point, I started asking myself:</p>
<blockquote>
<p><strong>Why am I fixing the same problem again and again, just because a library changed?</strong>🤔</p>
</blockquote>
<h2 id="heading-the-pattern-i-kept-seeing"><strong>The Pattern I Kept Seeing</strong></h2>
<p>Let’s be honest — React Native apps don’t die quickly.<br />They live for years.</p>
<p>But during that time:</p>
<ul>
<li><p>FlatList starts struggling with performance</p>
</li>
<li><p>FlashList shows up and becomes the new standard</p>
</li>
<li><p>SafeAreaView from react-native is no longer enough</p>
</li>
<li><p>We move to react-native-safe-area-context</p>
</li>
</ul>
<p>And suddenly you’re touching <strong>dozens of files</strong> for what is essentially one <strong>decision change</strong>.</p>
<p>That’s when I realised —<br /><strong>The mistake was never the library choice; it was how tightly my app depended on it</strong>.</p>
<h2 id="heading-the-simple-rule-i-follow-now"><strong>The Simple Rule I Follow Now</strong></h2>
<blockquote>
<ul>
<li><p>Never use core or third-party components directly across the app.</p>
</li>
<li><p>Wrap them once. Own them.</p>
</li>
</ul>
</blockquote>
<p>I started creating a <strong>top layer of base components</strong>.</p>
<p><strong>Example 1:</strong> Lists (FlatList → FlashList)</p>
<p><strong>What I stopped doing</strong><br />Using FlatList directly everywhere:</p>
<pre><code class="lang-plaintext">import { FlatList } from 'react-native';
</code></pre>
<p>Because I already know how this story ends.</p>
<p><strong>What I do instead:</strong> AppFlatList</p>
<pre><code class="lang-plaintext">// AppFlatList.tsx
import React from 'react';
import { FlatList, FlatListProps } from 'react-native';

export function AppFlatList&lt;T&gt;(props: FlatListProps&lt;T&gt;) {
  return (
    &lt;FlatList
      {...props}
      removeClippedSubviews
      windowSize={5}
      initialNumToRender={10}
    /&gt;
  );
}
</code></pre>
<p>Usage stays simple:</p>
<pre><code class="lang-plaintext">&lt;AppFlatList
  data={data}
  renderItem={renderItem}
  keyExtractor={(item) =&gt; item.id}
/&gt;
</code></pre>
<p>Now, when performance becomes an issue (and it will), I don’t panic.</p>
<p><strong>Later… switching to FlashList</strong></p>
<pre><code class="lang-plaintext">// AppFlatList.tsx
import { FlashList, FlashListProps } from '@shopify/flash-list';

export function AppFlatList&lt;T&gt;(props: FlashListProps&lt;T&gt;) {
  return &lt;FlashList {...props} estimatedItemSize={60} /&gt;;
}
</code></pre>
<p>That’s it.</p>
<p>No screen changes.<br />No refactor weekends.<br />No stress.</p>
<p><strong>Example 2:</strong> Base Component Deprecation (SafeAreaView)<br />This one hit me multiple times.</p>
<p>Earlier we all used:</p>
<pre><code class="lang-plaintext">import { SafeAreaView } from 'react-native';
</code></pre>
<p>Later, we were told:</p>
<blockquote>
<p>“Use react-native-safe-area-context instead.”</p>
</blockquote>
<p>Now imagine SafeAreaView used everywhere.</p>
<p>Painful, right?</p>
<pre><code class="lang-plaintext">// AppSafeAreaView.tsx
import React from 'react';
import { SafeAreaView } from 'react-native-safe-area-context';

export function AppSafeAreaView({ children, style }) {
  return (
    &lt;SafeAreaView style={[{ flex: 1 }, style]}&gt;
      {children}
    &lt;/SafeAreaView&gt;
  );
}
</code></pre>
<p>Usage:</p>
<pre><code class="lang-plaintext">&lt;AppSafeAreaView&gt;
  &lt;HomeScreen /&gt;
&lt;/AppSafeAreaView&gt;
</code></pre>
<p>Now I don’t care:</p>
<ul>
<li><p>if API changes</p>
</li>
<li><p>if padding logic changes</p>
</li>
<li><p>if Android/iOS behavior differs later</p>
</li>
<li><p>I’ve isolated it.</p>
</li>
</ul>
<h2 id="heading-this-slowly-became-my-default-style"><strong>This Slowly Became My Default Style</strong></h2>
<p>Now I do this for almost everything:</p>
<ul>
<li><p>AppText → font scaling, typography updates</p>
</li>
<li><p>AppButton → design system changes</p>
</li>
<li><p>AppInput → validation, focus handling</p>
</li>
<li><p>AppImage → caching, placeholders</p>
</li>
<li><p>AppPressable → analytics hooks later</p>
</li>
<li><p>Every time I hesitate and think</p>
</li>
</ul>
<blockquote>
<p>“Should I just use this directly?”</p>
</blockquote>
<p>I remember how many times I’ve regretted that decision.</p>
<p><strong>Why This Matters (Real Talk)</strong><br />React Native evolves fast.<br />Your app doesn’t.</p>
<p>So either:</p>
<ul>
<li><p>You chase changes every year<br />  or</p>
</li>
<li><p>You design your app to absorb them calmly</p>
</li>
</ul>
<p>Wrapping components doesn’t slow you down.<br />Refactoring later does.</p>
<p><strong>Final Thought</strong><br />This isn’t about over-engineering.<br />It’s about respecting the fact that change is guaranteed.</p>
<blockquote>
<p>I don’t wrap components because I expect problems today.<br />I wrap them because I know future-me will be tired.</p>
</blockquote>
<p>And honestly?<br />Future-me deserves better.</p>
]]></content:encoded></item></channel></rss>