<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Mastering Git on Loaay Waheed</title>
    <link>https://luvimsan.dev/series/mastering-git/</link>
    <description>Recent content in Mastering Git on Loaay Waheed</description>
    <generator>Hugo -- gohugo.io</generator><language>en-US</language><copyright>Copyright © 2026, Loaay Waheed.</copyright><lastBuildDate>Sat, 27 Sep 2025 23:21:06 +0300</lastBuildDate><atom:link href="https://luvimsan.dev/series/mastering-git/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Git Notebook - Part 2</title>
      <link>https://luvimsan.dev/blog/git-notebook-part-2/</link>
      <pubDate>Sat, 27 Sep 2025 23:21:06 +0300</pubDate>
      <guid>https://luvimsan.dev/blog/git-notebook-part-2/</guid>
      <description>&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;To keep in your pocket&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;git commit --amend&lt;/code&gt;      &amp;ndash;&amp;gt; changes the last commit msg&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git reset --soft HEAD~1&lt;/code&gt; &amp;ndash;&amp;gt; remove last commit but keep changes staged&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-1--fork&#34;&gt;Chapter 1 | fork&lt;/h2&gt;
&lt;p&gt;fork is a copy of a repo to your repos&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;on github instead of &lt;code&gt;creator/megacorp&lt;/code&gt; to &lt;code&gt;luvimsan/megacorp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;using gh cli  &lt;code&gt;gh repo fork &lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;prs-from-a-fork&#34;&gt;PRs from a fork&lt;/h3&gt;
&lt;p&gt;can be seen as a merge of branch with permission in the remote&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE] the standard way to contribute to someone else&amp;rsquo;s open-source project&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fork their repo into your account&lt;/li&gt;
&lt;li&gt;Clone your fork to your local machine&lt;/li&gt;
&lt;li&gt;Create a new branch (let&amp;rsquo;s call it your_feature)&lt;/li&gt;
&lt;li&gt;Make changes&lt;/li&gt;
&lt;li&gt;Commit and push changes to your fork&amp;rsquo;s remote your_feature branch&lt;/li&gt;
&lt;li&gt;Create a pull request to original_owner/repo main from your_username/repo your_feature&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-2--reflog&#34;&gt;Chapter 2 | reflog&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git reflog&lt;/code&gt; &amp;ndash;&amp;gt; like &lt;code&gt;git log&lt;/code&gt; but stands for &amp;ldquo;reference log&amp;rdquo;&lt;/p&gt;
&lt;h3 id=&#34;format-of-a-reflog&#34;&gt;format of a reflog&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;reflog&lt;/th&gt;
					&lt;th&gt;meaning&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;HEAD@{0}&lt;/td&gt;
					&lt;td&gt;where HEAD is now&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;HEAD@{1}&lt;/td&gt;
					&lt;td&gt;where HEAD was 1 move ago&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;HEAD@{2}&lt;/td&gt;
					&lt;td&gt;where HEAD was 2 move ago&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;HEAD@{3}&lt;/td&gt;
					&lt;td&gt;where HEAD was 2 move ago&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&amp;hellip;&lt;/td&gt;
					&lt;td&gt;&amp;hellip;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;HEAD is a reference to the branch you&amp;rsquo;re currently on.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;usage-of-reflog&#34;&gt;Usage of reflog&lt;/h3&gt;
&lt;p&gt;reflog can be used to rescue a commit has been removed&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;git reflog to get commit hash&lt;/li&gt;
&lt;li&gt;git cat-file -p commit&lt;/li&gt;
&lt;li&gt;traverse till get the content of the commit&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a better way of rescuing a commit will be like this&lt;br&gt;&lt;/li&gt;
&lt;li&gt;git merge commitish &lt;br&gt;&lt;/li&gt;
&lt;li&gt;or git merge HEAD@{1}&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-3--merge-conflicts&#34;&gt;Chapter 3 | Merge conflicts&lt;/h2&gt;
&lt;p&gt;when two branches modify the same part since their common merge base&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;merging and rebasing is the common way of making conflicts&lt;/li&gt;
&lt;li&gt;git modify the conflicted file with both changes separating them with &amp;raquo; &amp;laquo; ==&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!EXAMPLE]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-csv&#34; data-lang=&#34;csv&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt;first_name&lt;/span&gt;,&lt;span style=&#34;color:#f1fa8c&#34;&gt;last_name&lt;/span&gt;,&lt;span style=&#34;color:#f1fa8c&#34;&gt;company&lt;/span&gt;,&lt;span style=&#34;color:#f1fa8c&#34;&gt;title&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt; &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; HEAD (branch im in) (ours)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt; karson&lt;/span&gt;,&lt;span style=&#34;color:#f1fa8c&#34;&gt;yummy&lt;/span&gt;,&lt;span style=&#34;color:#f1fa8c&#34;&gt;intercooler&lt;/span&gt;,&lt;span style=&#34;color:#f1fa8c&#34;&gt;ceo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt; ======= (end)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt; jayson&lt;/span&gt;,&lt;span style=&#34;color:#f1fa8c&#34;&gt;gross&lt;/span&gt;,&lt;span style=&#34;color:#f1fa8c&#34;&gt;htmz&lt;/span&gt;,&lt;span style=&#34;color:#f1fa8c&#34;&gt;contributor&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f1fa8c&#34;&gt; &amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; main (the other branch) (theirs)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&amp;ldquo;ours&amp;rdquo; &amp;ndash;&amp;gt; refers to the branch we are on (merging into)&lt;/li&gt;
&lt;li&gt;&amp;ldquo;theirs&amp;rdquo; &amp;ndash;&amp;gt; refers to the branch being merged&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git merge their_branch&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;checkout-conflict&#34;&gt;Checkout conflict&lt;/h3&gt;
&lt;p&gt;This will resolve a conflict without the need to edit the conflicted file&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git checkout --theirs path/to/file&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--ours&lt;/code&gt; will overwrite the file with the changes from the branch you are currently on and merging into&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--theirs&lt;/code&gt; will overwrite the file with the changes from the branch you are merging into the current branch&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-4--rebase-conflicts&#34;&gt;Chapter 4 | Rebase conflicts&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE] rebase rewrites history which sometimes may be dangerous But it provies linear history, easier for reverting&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;git rebase main&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it switch to the source branch &lt;code&gt;main&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;replays the commits from target branch im in &lt;code&gt;feat&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;it has a diff state called rebasing state&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;in conflict&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ours means the source branch &lt;code&gt;main&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;theirs means the target branch &lt;code&gt;feat&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git add . &amp;amp;&amp;amp; git rebase --continue&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;rerere-to-the-rescue&#34;&gt;RERERE to the rescue&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The git rerere functionality is a bit of a hidden feature.
The name stands for “reuse recorded resolution” and,
as the name implies, it allows you to ask Git to remember
how you’ve resolved a hunk conflict so that the next time it sees the same conflict,
Git can resolve it for you automatically.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Recorded preimage for &#39;customers/favs.md&#39;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Recorded resolution for &#39;customers/favs.md&#39;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Resolved &#39;customers/favs.md&#39; using previous resolution&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;accidental-commit-after-rebase&#34;&gt;Accidental commit after rebase&lt;/h3&gt;
&lt;p&gt;If you accidentally commit the resolution of a rebase conflict, just:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git reset --soft HEAD~1&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &amp;ndash;soft flag will keep your changes, and just undo the commit.&lt;/li&gt;
&lt;li&gt;Then you can simply &lt;code&gt;--continue&lt;/code&gt; the rebase as normal.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-5--squash&#34;&gt;Chapter 5 | Squash&lt;/h2&gt;
&lt;p&gt;To squash some commits in one commit&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git rebase -i HEAD~n&lt;/code&gt;
i : interactive
n : number of commits to squash
change pick &amp;ndash;&amp;gt; s, squash&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE] Why Does Rebase Squash?
Remember, rebase is all about replaying changes. When we rebase onto a
specific commit (HEAD~n), we&amp;rsquo;re telling Git to replay all the changes from
the current branch on top of that commit. Then we use the interactive flag
to &amp;ldquo;squash&amp;rdquo; those changes so that Rebase will apply them all in a single commit&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;notes&#34;&gt;NOTES:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;never squash on main branch
&lt;ul&gt;
&lt;li&gt;squash on a feat branch&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;the purpose of squash is to allow you to make lots of commits and then leave
the important ones and squash the other in a signle commit&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-6--stash&#34;&gt;Chapter 6 | Stash&lt;/h2&gt;
&lt;p&gt;Definition: Temporarily saves uncommitted changes and reverts the working directory to match the latest commit (HEAD).
Command: &lt;code&gt;git stash&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;stash&lt;/strong&gt; stores the changes in a stack (LIFO) &amp;ndash;&amp;gt; get the most recent changes first&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git stash list&lt;/code&gt; example
stash@{0}: On main: bad marketing
stash@{1}: On main: good marketing&lt;/p&gt;
&lt;h3 id=&#34;useful-flags&#34;&gt;useful flags&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git stash list&lt;/code&gt;           &amp;ndash;&amp;gt; (list all the stashes)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git stash pop&lt;/code&gt;            &amp;ndash;&amp;gt; (applay the most recent stash entry to the working directory)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git stash apply&lt;/code&gt;          &amp;ndash;&amp;gt; Apply a specific stash without deleting it&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git stash drop&lt;/code&gt;           &amp;ndash;&amp;gt; Delete a stash without applaying&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git stash -m &#39;message&#39;&lt;/code&gt;   &amp;ndash;&amp;gt; multiple staashes with message&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-7--revert&#34;&gt;Chapter 7 | Revert&lt;/h2&gt;
&lt;p&gt;Definition: it&amp;rsquo;s a commit that remove another commit by replaying it in reverse
and keep the full history of the change and the undoing
Command: &lt;code&gt;git revert commit-ish&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;git-reset-vs-git-revert&#34;&gt;git reset vs git revert&lt;/h3&gt;
&lt;p&gt;Mostly personal branches:
git reset &amp;ndash;soft: Undo commits but keep changes staged
git reset &amp;ndash;hard: Undo commits and discard changes&lt;/p&gt;
&lt;p&gt;Mostly public branches:
git revert: Create a new commit that undoes a previous commit&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-8--cherry-pick&#34;&gt;Chapter 8 | Cherry Pick&lt;/h2&gt;
&lt;p&gt;Definition: a way to pick a commit or a range of commits from a branch to add to
another branch without getting all the commits (if merging and rebasing is not needed)
Command: &lt;code&gt;git cherry-pick commit-ish&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;workflow&#34;&gt;workflow&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;release has a b c commits&lt;/li&gt;
&lt;li&gt;main has a b c d g h n
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;instead of getting all the commits from main to release&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;we can just cherry-pick g commit and added to release&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-9--bisect&#34;&gt;Chapter 9 | Bisect&lt;/h2&gt;
&lt;p&gt;a way to find where a change or a bug was introduced using binary search in O(log n)&lt;/p&gt;
&lt;h3 id=&#34;how-to-bisect&#34;&gt;how to bisect&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;start with &lt;code&gt;git bisect start&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;select bad commit &lt;code&gt;git bisect bad {commit-ish}&lt;/code&gt;
or just &lt;code&gt;git bisect bad&lt;/code&gt; for the current commit&lt;/li&gt;
&lt;li&gt;select good commit with git by &lt;code&gt;git bisect good {commit-ish}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Git will checkout a commit between the good and bad commits for you to test to see if the bug is present&lt;/li&gt;
&lt;li&gt;Execute git bisect good or git bisect bad to say the current commit is good or bad&lt;/li&gt;
&lt;li&gt;Loop back to step 4 (until git bisect completes)&lt;/li&gt;
&lt;li&gt;Exit the bisect mode with &lt;code&gt;git bisect reset&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;automated-bisect-script&#34;&gt;Automated bisect script&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;instead of selecting bad and good we can make a script to automate that such that&lt;br&gt;
&amp;ndash;&amp;gt; return 0 when it&amp;rsquo;s a good commit&lt;br&gt;
&amp;ndash;&amp;gt; return 1-127 except 125 when it&amp;rsquo;s a bad commit&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;if&lt;/span&gt; grep -q &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;SCANNING&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#f1fa8c&#34;&gt;&amp;#34;scripts/scan.sh&amp;#34;&lt;/span&gt;; &lt;span style=&#34;color:#ff79c6&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;exit&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8be9fd;font-style:italic&#34;&gt;exit&lt;/span&gt; &lt;span style=&#34;color:#bd93f9&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ff79c6&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;using this command &lt;code&gt;git bisect run ./script.sh&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-10--worktrees&#34;&gt;Chapter 10 | Worktrees&lt;/h2&gt;
&lt;p&gt;A worktree in git is an additional working directory linked to the same Git repository.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE] main worktree
all that time we was working with the main working tree that was created by
git-init or git-clone&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;all stored at .git/worktrees directory&lt;/p&gt;
&lt;h3 id=&#34;pros&#34;&gt;pros&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;checkout multiple branches at the same time&lt;/li&gt;
&lt;li&gt;no need for git commands just two directories each has it&amp;rsquo;s own branch&lt;/li&gt;
&lt;li&gt;replace the continous stashing&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;cons&#34;&gt;cons&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;no duplicate branches&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;syntax&#34;&gt;syntax&lt;/h3&gt;
&lt;p&gt;add  &amp;ndash;&amp;gt; &lt;code&gt;git worktree add {path} {branch_name}&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;example --&amp;gt;   `git worktree add ../ultracorp` // using same worktree name for branch
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;list &amp;ndash;&amp;gt;  &lt;code&gt;git worktree list&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;remove &amp;ndash;&amp;gt; &lt;code&gt;git worktree remove {path}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;p&gt;prune (remove the directory) &amp;ndash;&amp;gt; &lt;code&gt;git worktree prune&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-11--tags&#34;&gt;Chapter 11 | Tags&lt;/h2&gt;
&lt;p&gt;an immutable pointer to a specific commit&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!INFO] unlike branches
tags can be created and deleted, but not modified&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;syntax-1&#34;&gt;Syntax&lt;/h3&gt;
&lt;p&gt;list        &amp;ndash;&amp;gt; &lt;code&gt;git tag&lt;/code&gt;
create      &amp;ndash;&amp;gt; &lt;code&gt;git tag {name}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;flags
name (-a)   &amp;ndash;&amp;gt; &lt;code&gt;git tag -a {name}&lt;/code&gt; //default first parameter
msg  (-m)   &amp;ndash;&amp;gt; &lt;code&gt;git tag -a {name} -m {msg}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;push        &amp;ndash;&amp;gt; &lt;code&gt;git push --tags&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;semver&#34;&gt;Semver&lt;/h3&gt;
&lt;p&gt;semver stands for &amp;ldquo;Semantic Versioning&amp;rdquo; for versioning software&lt;/p&gt;
&lt;p&gt;two primary purposes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To give us a standard convention for versioning software&lt;/li&gt;
&lt;li&gt;To help us understand the impact of a version change and if it&amp;rsquo;s safe (how hard it will be) to upgrade to&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;v3.12.5&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;3  &amp;ndash;&amp;gt; MAJOR (breaking changes)&lt;/li&gt;
&lt;li&gt;12 &amp;ndash;&amp;gt; MINOR (safe features)&lt;/li&gt;
&lt;li&gt;5  &amp;ndash;&amp;gt; PATCH (fafe bug fixes)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MAJOR increments when we make &amp;ldquo;breaking&amp;rdquo; changes (this is typically a big release, for example, Python 2 -&amp;gt; Python 3)&lt;/li&gt;
&lt;li&gt;MINOR increments when we add new features in a backward-compatible manner&lt;/li&gt;
&lt;li&gt;PATCH increments when we make backward-compatible bug fixes&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;references&#34;&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/rH3zE7VlIMs&#34;
  
   target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;
&gt;Git course on boot.dev by The Primeagen&lt;/a&gt;
&lt;/p&gt;
</description>
    </item>
    <item>
      <title>Git Notebook - Part 1</title>
      <link>https://luvimsan.dev/blog/git-notebook-part-1/</link>
      <pubDate>Sat, 13 Sep 2025 21:25:01 +0300</pubDate>
      <guid>https://luvimsan.dev/blog/git-notebook-part-1/</guid>
      <description>&lt;h2 id=&#34;chapter-1--introduction&#34;&gt;Chapter 1 | Introduction&lt;/h2&gt;
&lt;p&gt;Git is &lt;em&gt;the&lt;/em&gt; distributed &lt;a href=&#34;https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control&#34;
  
   target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;
&gt;version control system&lt;/a&gt;
 (VCS). Nearly every developer in the world uses it to manage their code. It has quite a monopoly on VCS. Developers use Git to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Keep a history of their code changes&lt;/li&gt;
&lt;li&gt;Revert mistakes made in their code&lt;/li&gt;
&lt;li&gt;Collaborate with other developers&lt;/li&gt;
&lt;li&gt;Make backups of their code&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;overview-about-the-contents&#34;&gt;Overview about the contents:&lt;/h3&gt;
&lt;h4 id=&#34;porcelain-most-used&#34;&gt;Porcelain: (most used)&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git add&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git commit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git pull&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git log&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;plumbing&#34;&gt;Plumbing&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git apply&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git commit-tree&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git hash-object&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-2--git-repository-core-concepts&#34;&gt;Chapter 2 | git repository (core concepts)&lt;/h2&gt;
&lt;p&gt;4 states:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Working Directory or &amp;ldquo;working tree&amp;rdquo;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The actual filesystem&lt;/li&gt;
&lt;li&gt;Stored in desk&lt;/li&gt;
&lt;li&gt;by editing the file&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Index (Staging Area)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A snapshot of what you plan to commit&lt;/li&gt;
&lt;li&gt;Stored in .git/index&lt;/li&gt;
&lt;li&gt;by git add file (from tree to index)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Repository (Commits, HEAD)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The database of snapshots&lt;/li&gt;
&lt;li&gt;Stored in .git/objects&lt;/li&gt;
&lt;li&gt;by git commit (from index to local repo)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Remote Repository&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a remote repo&lt;/li&gt;
&lt;li&gt;Stored mostly on the cloudin (github, gitlab &amp;hellip;)&lt;/li&gt;
&lt;li&gt;by git remote add (from local to remote)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;states-of-changes&#34;&gt;States of Changes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Untracked: file exists in working tree but not in index.&lt;/li&gt;
&lt;li&gt;Modified (unstaged): file changed in working tree, not yet staged.&lt;/li&gt;
&lt;li&gt;Staged: change recorded in index, waiting to be committed.&lt;/li&gt;
&lt;li&gt;Committed: change saved permanently into the repo as a commit object.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-3---git-internals-gits-four-object-types&#34;&gt;Chapter 3 |  git internals (Git’s Four Object Types)&lt;/h2&gt;
&lt;p&gt;Inside .git/objects/, Git stores content-addressed objects. The key is
the SHA-1 hash of the content (with a header). There are four object types:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Blob&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;What it is: File contents (binary or text).&lt;/li&gt;
&lt;li&gt;Internals: Stored as &amp;ldquo;blob and hashed with SHA-1.&lt;/li&gt;
&lt;li&gt;Mental model: &amp;ldquo;Just the contents of one file, nothing else (no metadata).&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Tree&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;What it is: Directory (list of entries).&lt;/li&gt;
&lt;li&gt;Mental model: &amp;ldquo;A folder structure mapping names → blobs/trees.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;Commit&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;What it is: Snapshot pointer.&lt;/li&gt;
&lt;li&gt;Internals: Stores the SHA0 of a tree (root directory snapshot), parent commits, author, message.&lt;/li&gt;
&lt;li&gt;Mental model: &amp;ldquo;A node in the history graph pointing to a tree.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&#34;4&#34;&gt;
&lt;li&gt;Tag&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;What it is: Named pointer to a commit (sometimes with extra metadata).&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-4--git-config&#34;&gt;Chapter 4 | git config&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git config &amp;lt;action&amp;gt; &amp;lt;scope&amp;gt; &amp;lt;section.key&amp;gt; &amp;quot;value&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;action&lt;/strong&gt;:    &amp;ndash;add, &amp;ndash;list, &amp;ndash;get, &amp;ndash;unset, &amp;ndash;unset-all, &amp;ndash;remove-section&lt;br&gt;
&lt;strong&gt;scope&lt;/strong&gt;:     &amp;ndash;global, &amp;ndash;local&lt;br&gt;
&lt;strong&gt;section&lt;/strong&gt;:   user.name, user.email, init.defaultBranch&lt;br&gt;
&lt;strong&gt;value&lt;/strong&gt;:     main, master&lt;br&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-5--git-branches&#34;&gt;Chapter 5 | git branches&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;A branch is just a named pointer to a specific commit&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Git Branch&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git branch&lt;/code&gt; → list branches&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git branch &amp;lt;name&amp;gt;&lt;/code&gt; → create branch&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git branch -m &amp;lt;oldname&amp;gt; &amp;lt;newname&amp;gt;&lt;/code&gt; → change branch&amp;rsquo;s name&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Git switch&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git switch &amp;lt;name&amp;gt;&lt;/code&gt; → switch to branch&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git switch -c &amp;lt;name&amp;gt;&lt;/code&gt; → create + switch&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git branch -d &amp;lt;name&amp;gt;&lt;/code&gt; → delete branch&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-6--git-merge&#34;&gt;Chapter 6 | git merge&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;A process to merge the two branches with a merge commit&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;A - B - C - F    main
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     \     /
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      D - E      other_branch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;git merge other_branch&lt;/code&gt; → in main branch&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-7--git-rebase&#34;&gt;Chapter 7 | git rebase&lt;/h2&gt;
&lt;p&gt;git rebase stands for changing the base commit of two branch hence the name re-base&lt;/p&gt;
&lt;p&gt;from this&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;A - B - C    main
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    D - E    feature_branch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;to&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;A - B - C         main
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          D - E   feature_branch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;[!HINT]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;always rebase&lt;/li&gt;
&lt;li&gt;squash to a single commit&lt;/li&gt;
&lt;li&gt;revert when needed&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
Rebase your work onto others’ work → OK.&lt;br&gt;
Your feature branch rebased onto main.}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;git rebase main&lt;/code&gt; &amp;ndash;&amp;gt; Rebase others’ work onto your work → Bad.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git rebase feature&lt;/code&gt; &amp;ndash;&amp;gt; {Public branch rebased onto your feature.}&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-8--git-reset&#34;&gt;Chapter 8 | git reset&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git reset &amp;lt;action&amp;gt; commit-ish&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;action: &amp;ndash;soft, &amp;ndash;mixed, &amp;ndash;hard&lt;br&gt;
commit-ish : commit-hash, HEAD~n&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;HEAD~ or HEAD~1 &amp;ndash;&amp;gt; commit before this one&lt;/p&gt;
&lt;p&gt;HEAD~2 -&amp;gt; two commits before&lt;/p&gt;
&lt;h3 id=&#34;git-reset-internals&#34;&gt;Git reset internals&lt;/h3&gt;
&lt;p&gt;1- all three modes do the exact same first step
2- move HEAD to the target commit&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;flags tell git what to do with (index, working directory)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;git reset --soft&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;staging area: preserved, All differences between your old commit and the target commit are placed here&lt;/li&gt;
&lt;li&gt;working directory: untouched&lt;/li&gt;
&lt;li&gt;All the changes from the deleted commits are instantly placed right back into your Staging Area.&lt;/li&gt;
&lt;li&gt;Use case: Squashing or editing recent commits without losing your work.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;git reset --hard&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;staging area: wiped to match target commit&lt;/li&gt;
&lt;li&gt;working directory: overwritten to match target commit
-&amp;gt; wipes the staging area, overwrites your working directory to match target commit
-&amp;gt; it only overwrites only unstaged but (untracked will not be touched)&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Use case:&lt;/em&gt; Nuclear option to discard bad experiments and return to a known state.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;git reset --mixed&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;wipes the staging area to match target comit&lt;/li&gt;
&lt;li&gt;working directory: untouched, diff will be in unstaged state&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;example&#34;&gt;Example:&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#282a36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;main: A -&amp;gt; B -&amp;gt; C -&amp;gt; D
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HEAD:                ^
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;if &amp;hellip; is used:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git reset --hard HEAD~2&lt;/code&gt;  &amp;ndash; goes to b (b commit-hash can be used)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;-&amp;gt; C, D commit is gone (not forever &amp;ldquo;reflog&amp;rdquo;)&lt;br&gt;
-&amp;gt; like you have just commit B&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;if you have staged and unstaged changes. you can&amp;rsquo;t recove it  at all&lt;br&gt;
but if they are commited git reflog may help you&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;git reset --soft HEAD~2&lt;/code&gt;  &amp;ndash; goes to b (b commit-hash can be used)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;-&amp;gt; C, D changes are  staged in the index&lt;br&gt;
-&amp;gt; like you have made all thea changes in c, d and only add them to index&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;git reset --mixed HEAD~2&lt;/code&gt;  &amp;ndash; goes to b (b commit-hash can be used)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;-&amp;gt; C, D changes are  unstaged in the index&lt;br&gt;
-&amp;gt; like you have made all thea changes in c, d and never added them to index&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-9--git-remote&#34;&gt;Chapter 9 | git remote&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;git remote &amp;lt;action&amp;gt; &amp;lt;name&amp;gt; &amp;lt;uri&amp;gt;&lt;/code&gt;
action: add, rename, remove
uri(uniform resource identifier): urls, relative path&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Remote is just another repo that has branches&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;git fetch&lt;/code&gt;: downloads commits and updates remote-tracking branches
does not change the current branch or working files.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git merge&lt;/code&gt;: merging branches between local ******&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-10--github&#34;&gt;Chapter 10 | Github&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;[!EXAMPLE]
git remote add origin &lt;a href=&#34;mailto:git@github.com&#34;
  
  
&gt;git@github.com&lt;/a&gt;
:userName/repoName      // ssh&lt;br&gt;
git remote add origin &lt;a href=&#34;https://github.com/userName/repoName&#34;
  
   target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;
&gt;https://github.com/userName/repoName&lt;/a&gt;
  // https&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;git ls-remote&lt;/code&gt;: to list the rmeotes&lt;/p&gt;
&lt;h3 id=&#34;git-push&#34;&gt;git push&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;git push &amp;lt;remote-repository&amp;gt; &amp;lt;local-branch&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git push&lt;/code&gt; sends local changes to any &amp;ldquo;remote&amp;rdquo;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!EXAMPLE]
&lt;code&gt;git push -u origin main &lt;/code&gt; &lt;br&gt;
to push from current branch from local  &amp;ndash;&amp;gt;  origin/main {remote}/{branch}&lt;br&gt;
-u set the upstream between remote and local repos&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&#34;alternative-options&#34;&gt;Alternative Options&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;git push origin &amp;lt;localbranch&amp;gt;:&amp;lt;remotebranch&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;git push origin main:main&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;push my main local to origin main&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;push with diff name: git push origin main:feature-grid&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;delete remote branch:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;git push origin :old-feature&lt;/li&gt;
&lt;li&gt;git push origin &amp;ndash;delete old-feature&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;git-pull&#34;&gt;git pull&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;git pull [&amp;lt;remote&amp;gt;/&amp;lt;branch&amp;gt;]&lt;/code&gt;
git-pull - Fetch from and integrate with another repository or a local&lt;/p&gt;
&lt;h4 id=&#34;pull-request&#34;&gt;pull request&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;pull request is a way to propose changes, typically to the rest of your team,&lt;br&gt;
or to the maintainer of a project you&amp;rsquo;re contributing to.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;merge branches in remote&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;merges branches in remote: (by pull request)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Base: main &amp;lt;&amp;ndash;  compare: branch&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;git-restore&#34;&gt;git restore&lt;/h3&gt;
&lt;p&gt;discarding unstaged changes:    &lt;code&gt;git restore file&lt;/code&gt;
unstaging a file:               &lt;code&gt;git restore --staged file&lt;/code&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;chapter-11--gitignore&#34;&gt;Chapter 11 | gitignore&lt;/h2&gt;
&lt;p&gt;a file named .gitignore that gives instruction to git internals on which to track&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;can be at root or in a specific folders&lt;/li&gt;
&lt;li&gt;nested gitignore only applies to the directory it&amp;rsquo;s in and its subdirectories.&lt;/li&gt;
&lt;li&gt;.git/info/exclude is local gitignore that doesn&amp;rsquo;t need to be commited&lt;/li&gt;
&lt;li&gt;order matters in a &lt;code&gt;.gitignore&lt;/code&gt; so be careful&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;pattern&#34;&gt;pattern&lt;/h3&gt;
&lt;p&gt;a test rule with wild cards, let&amp;rsquo;s go over them&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;* &amp;ndash;&amp;gt; anynumber of characters &lt;code&gt;*.log&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;\ &amp;ndash;&amp;gt; anchorying to the root directory not any sub &lt;code&gt;\main.py&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;! &amp;ndash;&amp;gt; negating an existing ignore &lt;code&gt;*.txt&lt;/code&gt; &lt;code&gt;!important.txt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;# &amp;ndash;&amp;gt; commenting any text &lt;code&gt;# idk&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[!IMPORTANT]
some rules of thumb for coding projects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ignore things that can be generated (e.g. compiled code, minified files, etc.)&lt;/li&gt;
&lt;li&gt;Ignore dependencies (e.g. node_modules, venv, packages, etc.)&lt;/li&gt;
&lt;li&gt;Ignore things that are personal or specific to how you like to work (e.g. editor settings)&lt;/li&gt;
&lt;li&gt;Ignore things that are sensitive or dangerous (e.g. .env files, passwords, API keys, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;references&#34;&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/rH3zE7VlIMs&#34;
  
   target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;
&gt;Git course on boot.dev by The Primeagen&lt;/a&gt;
&lt;/p&gt;
</description>
    </item>
  </channel>
</rss>
