<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Git Essentials on fffelipe's world wide web</title><link>https://fffelipe.com/misc/learning/git/</link><description>Recent content in Git Essentials on fffelipe's world wide web</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://fffelipe.com/misc/learning/git/index.xml" rel="self" type="application/rss+xml"/><item><title>Repository</title><link>https://fffelipe.com/misc/learning/git/repository/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/repository/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git init &lt;span style="color:#75715e"&gt;# new project here&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git clone &amp;lt;url&amp;gt; &lt;span style="color:#75715e"&gt;# copy a remote repo from GitHub&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Run &lt;code&gt;init&lt;/code&gt; for a fresh project, &lt;code&gt;clone&lt;/code&gt; to start working on something that already lives on GitHub.&lt;/p&gt;</description></item><item><title>The Three States</title><link>https://fffelipe.com/misc/learning/git/three-states/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/three-states/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;edit → git add → git commit
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is the mental model for everything else. Staging lets you commit a curated subset of your changes.&lt;/p&gt;</description></item><item><title>Working tree</title><link>https://fffelipe.com/misc/learning/git/working-tree/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/working-tree/</guid><description>&lt;p&gt;It is your visible project folder: source files, notes, images, configs, and anything else not hidden inside Git internals.&lt;/p&gt;
&lt;p&gt;Example: after editing &lt;code&gt;index.html&lt;/code&gt;, that file is changed in the working tree, but Git has not stored that change in history yet.&lt;/p&gt;</description></item><item><title>Staging area</title><link>https://fffelipe.com/misc/learning/git/staging-area/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/staging-area/</guid><description>&lt;p&gt;Use &lt;code&gt;git add &amp;lt;file&amp;gt;&lt;/code&gt; to stage changes. Only staged changes are included when you run &lt;code&gt;git commit&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Real-world example: you fixed a typo and also started a big refactor. Stage only the typo fix so you can commit it separately and keep history clean.&lt;/p&gt;</description></item><item><title>Commit</title><link>https://fffelipe.com/misc/learning/git/commit/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/commit/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git add src/auth.js
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git commit -m &lt;span style="color:#e6db74"&gt;&amp;#34;Validate email on signup&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Keep commits small and focused on one logical change. Good messages explain &lt;em&gt;why&lt;/em&gt;, not &lt;em&gt;what&lt;/em&gt;.&lt;/p&gt;</description></item><item><title>git status</title><link>https://fffelipe.com/misc/learning/git/status/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/status/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git status
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Your most-used command. Run it constantly to stay oriented.&lt;/p&gt;</description></item><item><title>git log</title><link>https://fffelipe.com/misc/learning/git/log/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/log/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git log --oneline --graph --decorate
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Find when a bug was introduced or understand how a file evolved. The flags above give a compact, readable view.&lt;/p&gt;</description></item><item><title>git diff</title><link>https://fffelipe.com/misc/learning/git/diff/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/diff/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git diff &lt;span style="color:#75715e"&gt;# unstaged changes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git diff --staged &lt;span style="color:#75715e"&gt;# what would commit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git diff main..feature &lt;span style="color:#75715e"&gt;# between branches&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Always review the diff before committing: it catches stray console.logs and accidental edits.&lt;/p&gt;</description></item><item><title>Branch</title><link>https://fffelipe.com/misc/learning/git/branch/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/branch/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch -c feature-auth &lt;span style="color:#75715e"&gt;# create + switch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch main &lt;span style="color:#75715e"&gt;# back to main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git branch -d feature-auth &lt;span style="color:#75715e"&gt;# delete&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;One branch per feature or fix. Keep &lt;code&gt;main&lt;/code&gt; always deployable: it should reflect what is in production.&lt;/p&gt;</description></item><item><title>Merge</title><link>https://fffelipe.com/misc/learning/git/merge/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/merge/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch main
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git merge feature-auth
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On GitHub, merging usually happens through the PR &amp;ldquo;Merge&amp;rdquo; button rather than locally: that way CI and review approval are enforced.&lt;/p&gt;</description></item><item><title>Merge Conflict</title><link>https://fffelipe.com/misc/learning/git/merge-conflict/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/merge-conflict/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# open files with &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; markers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# edit to keep what you want&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git add &amp;lt;file&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git commit
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Most editors highlight conflicts and offer &amp;ldquo;accept current/incoming/both&amp;rdquo; buttons. Test before committing the resolution.&lt;/p&gt;</description></item><item><title>git switch</title><link>https://fffelipe.com/misc/learning/git/switch/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/switch/</guid><description>&lt;p&gt;Examples:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch main
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch -c feature/login
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Real-world example: switch from &lt;code&gt;main&lt;/code&gt; to a feature branch before starting work so your changes are isolated from production-ready code.&lt;/p&gt;</description></item><item><title>Rebase</title><link>https://fffelipe.com/misc/learning/git/rebase/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/rebase/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch feature-x
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git rebase main
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Used to keep your feature branch up-to-date with main. Don&amp;rsquo;t rebase branches others are working on; it rewrites history.&lt;/p&gt;</description></item><item><title>HEAD</title><link>https://fffelipe.com/misc/learning/git/head/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/head/</guid><description>&lt;p&gt;Most of the time, &lt;code&gt;HEAD&lt;/code&gt; points to the current branch, and the branch points to the latest commit on that branch.&lt;/p&gt;
&lt;p&gt;Real-world example: if you are on &lt;code&gt;main&lt;/code&gt;, new commits move &lt;code&gt;main&lt;/code&gt; forward, and &lt;code&gt;HEAD&lt;/code&gt; follows along because it points at &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Remote</title><link>https://fffelipe.com/misc/learning/git/remote/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/remote/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git remote -v &lt;span style="color:#75715e"&gt;# list remotes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git remote add origin &amp;lt;url&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;origin&lt;/code&gt; is the conventional name for your primary remote. Most projects only need one; forks add a second called &lt;code&gt;upstream&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Push</title><link>https://fffelipe.com/misc/learning/git/push/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/push/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git push &lt;span style="color:#75715e"&gt;# if upstream is set&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git push -u origin feature-x &lt;span style="color:#75715e"&gt;# first push of a new branch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;-u&lt;/code&gt; sets the upstream so future &lt;code&gt;push&lt;/code&gt;/&lt;code&gt;pull&lt;/code&gt; work without arguments. After this, your branch shows up on GitHub.&lt;/p&gt;</description></item><item><title>Pull</title><link>https://fffelipe.com/misc/learning/git/pull/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/pull/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git pull
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git pull --rebase &lt;span style="color:#75715e"&gt;# avoids extra merge commits&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Run before starting work each day. &lt;code&gt;--rebase&lt;/code&gt; keeps history cleaner on shared branches.&lt;/p&gt;</description></item><item><title>Fetch</title><link>https://fffelipe.com/misc/learning/git/fetch/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/fetch/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git fetch origin
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git log origin/main &lt;span style="color:#75715e"&gt;# see what you&amp;#39;d be merging&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Use when you want to inspect remote changes before deciding to merge or rebase.&lt;/p&gt;</description></item><item><title>Pull Request</title><link>https://fffelipe.com/misc/learning/git/pull-request/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/pull-request/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# After pushing your branch:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh pr create --fill &lt;span style="color:#75715e"&gt;# uses last commit as title/body&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh pr view --web &lt;span style="color:#75715e"&gt;# open in browser&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh pr list
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh pr checkout &lt;span style="color:#ae81ff"&gt;142&lt;/span&gt; &lt;span style="color:#75715e"&gt;# review someone else&amp;#39;s PR locally&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;PRs are where code review and CI run. Most teams use squash-merge to keep &lt;code&gt;main&lt;/code&gt;&amp;rsquo;s history one commit per PR.&lt;/p&gt;</description></item><item><title>.gitignore</title><link>https://fffelipe.com/misc/learning/git/gitignore/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/gitignore/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# .gitignore&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;node_modules/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.env
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;*.log
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.DS_Store
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dist/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Add on day one. Never commit secrets, dependencies, or build output. GitHub provides language-specific templates when you create a repo.&lt;/p&gt;</description></item><item><title>git stash</title><link>https://fffelipe.com/misc/learning/git/stash/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/stash/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git stash -u &lt;span style="color:#75715e"&gt;# save WIP, including new files&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch hotfix
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ...do urgent work...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch feature-x
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git stash pop &lt;span style="color:#75715e"&gt;# restore WIP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Perfect for the &amp;ldquo;I need to fix prod &lt;em&gt;right now&lt;/em&gt;&amp;rdquo; moment. The &lt;code&gt;-u&lt;/code&gt; flag matters: without it, untracked files won&amp;rsquo;t be saved.&lt;/p&gt;</description></item><item><title>Undo Changes</title><link>https://fffelipe.com/misc/learning/git/undo-changes/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/undo-changes/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git restore file.js &lt;span style="color:#75715e"&gt;# discard local edits&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git restore --staged file.js &lt;span style="color:#75715e"&gt;# unstage&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git reset --soft HEAD~1 &lt;span style="color:#75715e"&gt;# undo last commit, keep changes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git reset --hard HEAD~1 &lt;span style="color:#75715e"&gt;# ⚠️ delete last commit + changes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;--soft&lt;/code&gt; is safe and useful for amending. &lt;code&gt;--hard&lt;/code&gt; is destructive: only use it locally, never on pushed commits.&lt;/p&gt;</description></item><item><title>Tags</title><link>https://fffelipe.com/misc/learning/git/tag/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/tag/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git tag v1.0.0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git tag -a v1.0.0 -m &lt;span style="color:#e6db74"&gt;&amp;#34;First public release&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git push origin v1.0.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Mark release versions or deployment milestones. GitHub Actions and other CI systems often trigger off tag pushes.&lt;/p&gt;</description></item><item><title>gh CLI</title><link>https://fffelipe.com/misc/learning/git/gh-cli/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/gh-cli/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh auth login &lt;span style="color:#75715e"&gt;# one-time setup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh repo clone owner/name
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh pr create --fill
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh pr checkout &lt;span style="color:#ae81ff"&gt;42&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh issue list --assignee @me
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh run watch &lt;span style="color:#75715e"&gt;# follow CI for current commit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Saves the trip to the browser for most PR and CI tasks. Once authenticated, it also handles SSH/HTTPS credentials transparently.&lt;/p&gt;</description></item><item><title>origin</title><link>https://fffelipe.com/misc/learning/git/origin/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/origin/</guid><description>&lt;p&gt;&lt;code&gt;origin&lt;/code&gt; is just a nickname, not a special server. You can rename it or add more remotes.&lt;/p&gt;
&lt;p&gt;Real-world example: &lt;code&gt;origin/main&lt;/code&gt; means &amp;ldquo;the last fetched state of the &lt;code&gt;main&lt;/code&gt; branch on the remote named &lt;code&gt;origin&lt;/code&gt;.&amp;rdquo;&lt;/p&gt;</description></item><item><title>Daily Push Flow</title><link>https://fffelipe.com/misc/learning/git/daily-push-flow/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/daily-push-flow/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 1. Start from a fresh main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch main
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git pull
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 2. Create a branch for your work&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch -c feat/email-validation
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 3. Make changes, then commit in logical chunks&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git add src/auth.js
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git diff --staged &lt;span style="color:#75715e"&gt;# review before committing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git commit -m &lt;span style="color:#e6db74"&gt;&amp;#34;Validate email format on signup&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 4. Push and open a PR&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git push -u origin feat/email-validation
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh pr create --fill
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Always branch from an up-to-date main. Push early (even on rough work) so teammates can see progress and CI runs sooner. The PR is where review and merging happen, not your local machine.&lt;/p&gt;</description></item><item><title>Sync Branch with Main</title><link>https://fffelipe.com/misc/learning/git/sync-branch-with-main/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/sync-branch-with-main/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 1. Update your local main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch main
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git pull
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 2. Replay your feature work on top of latest main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch feat/email-validation
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git rebase main
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 3. If there are conflicts, edit the files, then:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git add &amp;lt;resolved-files&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git rebase --continue
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 4. Push the rewritten branch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git push --force-with-lease
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;--force-with-lease&lt;/code&gt; is the safe variant of &lt;code&gt;--force&lt;/code&gt;: it refuses to overwrite commits you haven&amp;rsquo;t seen. If you prefer to avoid history rewrites, &lt;code&gt;git merge main&lt;/code&gt; into your branch works too, but creates an extra merge commit.&lt;/p&gt;</description></item><item><title>Code Review Iteration</title><link>https://fffelipe.com/misc/learning/git/code-review-iteration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/code-review-iteration/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Option A: separate commits (easier to follow review thread)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git add src/auth.js
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git commit -m &lt;span style="color:#e6db74"&gt;&amp;#34;Address review: trim whitespace&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git push
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Option B: amend previous commit (cleaner final history)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git add src/auth.js
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git commit --amend --no-edit
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git push --force-with-lease
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Option A is friendlier for reviewers: they can see exactly what changed since their last review. Option B is fine if your team squash-merges anyway, since intermediate commits get collapsed at merge time.&lt;/p&gt;</description></item><item><title>Hotfix While Mid-Feature</title><link>https://fffelipe.com/misc/learning/git/hotfix-while-mid-feature/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/hotfix-while-mid-feature/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 1. Stash WIP, including any new untracked files&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git stash -u
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 2. Branch off latest main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch main
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git pull
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch -c hotfix/payment-timeout
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 3. Fix, commit, push, open PR&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git commit -am &lt;span style="color:#e6db74"&gt;&amp;#34;Increase payment gateway timeout&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git push -u origin hotfix/payment-timeout
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh pr create --fill
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 4. Once merged, resume your feature work&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch feat/email-validation
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git stash pop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Hotfixes branch from &lt;code&gt;main&lt;/code&gt;, not from your feature branch, because you don&amp;rsquo;t want to ship half-done feature code with the fix. The &lt;code&gt;-u&lt;/code&gt; on stash is critical: without it, brand-new files vanish when you switch branches.&lt;/p&gt;</description></item><item><title>Fork &amp; Stay in Sync</title><link>https://fffelipe.com/misc/learning/git/fork-and-stay-in-sync/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/fork-and-stay-in-sync/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 1. Click &amp;#34;Fork&amp;#34; on GitHub, then clone your fork&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git clone git@github.com:you/their-project.git
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd their-project
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 2. Add the original repo as &amp;#39;upstream&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git remote add upstream git@github.com:them/their-project.git
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git remote -v
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 3. Periodically pull updates from upstream&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git fetch upstream
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch main
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git merge upstream/main
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git push &lt;span style="color:#75715e"&gt;# update your fork&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 4. Make changes on a branch, push to your fork, open PR upstream&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git switch -c fix/typo-in-readme
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ...edit, commit, push...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gh pr create --fill
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Two remotes: &lt;code&gt;origin&lt;/code&gt; is your fork, &lt;code&gt;upstream&lt;/code&gt; is the original repo. PRs go from a branch on your fork to upstream&amp;rsquo;s main. Keep your fork&amp;rsquo;s main in sync with upstream so new branches start from the latest code.&lt;/p&gt;</description></item><item><title>Undo a Pushed Commit</title><link>https://fffelipe.com/misc/learning/git/undo-a-pushed-commit/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/undo-a-pushed-commit/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 1. Find the bad commit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git log --oneline
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 2. Create a new commit that undoes it&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git revert &amp;lt;commit-hash&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 3. Push the revert&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git push
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;revert&lt;/code&gt; is safe on shared branches: it adds a new commit instead of erasing the old one. Avoid &lt;code&gt;git reset --hard&lt;/code&gt; + &lt;code&gt;--force&lt;/code&gt; on any branch others may have pulled; you&amp;rsquo;ll cause confusion and lost work.&lt;/p&gt;</description></item><item><title>Revert</title><link>https://fffelipe.com/misc/learning/git/revert/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fffelipe.com/misc/learning/git/revert/</guid><description>&lt;p&gt;Revert is safe for shared branches because it does not rewrite history. It adds another commit saying &amp;ldquo;undo that change.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Real-world example: if a commit on &lt;code&gt;main&lt;/code&gt; broke production, revert it so everyone sees the fix as a normal new commit.&lt;/p&gt;</description></item></channel></rss>