update and finish lecture 2, add images.

main
borb 3 weeks ago
parent d99270507a
commit 7be3710733

@ -13,59 +13,61 @@
/* buutti.css */
/* @theme buutti */div#\:\$p>svg>foreignObject>section .columns{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:calc(var(--marpit-root-font-size, 1rem) * 1)}div#\:\$p>svg>foreignObject>section .columns12{display:grid;grid-template-columns:1fr 2fr;gap:calc(var(--marpit-root-font-size, 1rem) * 1)}div#\:\$p>svg>foreignObject>section .columns21{display:grid;grid-template-columns:2fr 1fr;gap:calc(var(--marpit-root-font-size, 1rem) * 1)}div#\:\$p>svg>foreignObject>section .columns32{display:grid;grid-template-columns:3fr 2fr;gap:calc(var(--marpit-root-font-size, 1rem) * 1)}div#\:\$p>svg>foreignObject>section .columns23{display:grid;grid-template-columns:2fr 3fr;gap:calc(var(--marpit-root-font-size, 1rem) * 1)}div#\:\$p>svg>foreignObject>section .columns111{display:grid;grid-template-columns:1fr 1fr 1fr;gap:calc(var(--marpit-root-font-size, 1rem) * 1)}div#\:\$p>svg>foreignObject>section .centered{display:flex;flex-direction:column;justify-content:center;text-align:center}div#\:\$p>svg>foreignObject>section .tableborderless td,div#\:\$p>svg>foreignObject>section th{border:none!important;border-collapse:collapse}div#\:\$p>svg>foreignObject>section.extra{background-color:#5d275d;background-image:linear-gradient(to bottom,#401a40,#1d0c1d);color:white}div#\:\$p>svg>foreignObject>section.extra a{color:rgb(145,255,209)}div#\:\$p>svg>foreignObject>section.exercise{background-color:#29366f;background-image:linear-gradient(to bottom,#20636a,#173742);color:white}div#\:\$p>svg>foreignObject>section.exercise a{color:rgb(211,173,255)}
/* @theme 79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5 */div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background]{columns:initial!important;display:block!important;padding:0!important}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background]:after,div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background]:before,div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=content]:after,div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=content]:before{display:none!important}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container]{all:initial;display:flex;flex-direction:row;height:100%;overflow:hidden;width:100%}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container][data-marpit-advanced-background-direction=vertical]{flex-direction:column}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background][data-marpit-advanced-background-split]>div[data-marpit-advanced-background-container]{width:var(--marpit-advanced-background-split,50%)}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background][data-marpit-advanced-background-split=right]>div[data-marpit-advanced-background-container]{margin-left:calc(100% - var(--marpit-advanced-background-split, 50%))}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container]>figure{all:initial;background-position:center;background-repeat:no-repeat;background-size:cover;flex:auto;margin:0}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container]>figure>figcaption{position:absolute;border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;white-space:nowrap;width:1px}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=content],div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=pseudo]{background:transparent!important}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=pseudo],div#\:\$p>svg[data-marpit-svg]>foreignObject[data-marpit-advanced-background=pseudo]{pointer-events:none!important}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background-split]{width:100%;height:100%}</style></head><body><div class="bespoke-marp-osc"><button data-bespoke-marp-osc="prev" tabindex="-1" title="Previous slide">Previous slide</button><span data-bespoke-marp-osc="page"></span><button data-bespoke-marp-osc="next" tabindex="-1" title="Next slide">Next slide</button><button data-bespoke-marp-osc="fullscreen" tabindex="-1" title="Toggle fullscreen (f)">Toggle fullscreen</button><button data-bespoke-marp-osc="presenter" tabindex="-1" title="Open presenter view (p)">Open presenter view</button></div><div id=":$p"><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="1" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="1" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
/* @theme ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd */div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background]{columns:initial!important;display:block!important;padding:0!important}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background]:after,div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background]:before,div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=content]:after,div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=content]:before{display:none!important}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container]{all:initial;display:flex;flex-direction:row;height:100%;overflow:hidden;width:100%}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container][data-marpit-advanced-background-direction=vertical]{flex-direction:column}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background][data-marpit-advanced-background-split]>div[data-marpit-advanced-background-container]{width:var(--marpit-advanced-background-split,50%)}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background][data-marpit-advanced-background-split=right]>div[data-marpit-advanced-background-container]{margin-left:calc(100% - var(--marpit-advanced-background-split, 50%))}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container]>figure{all:initial;background-position:center;background-repeat:no-repeat;background-size:cover;flex:auto;margin:0}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=background]>div[data-marpit-advanced-background-container]>figure>figcaption{position:absolute;border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;white-space:nowrap;width:1px}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=content],div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=pseudo]{background:transparent!important}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background=pseudo],div#\:\$p>svg[data-marpit-svg]>foreignObject[data-marpit-advanced-background=pseudo]{pointer-events:none!important}div#\:\$p>svg>foreignObject>section[data-marpit-advanced-background-split]{width:100%;height:100%}</style></head><body><div class="bespoke-marp-osc"><button data-bespoke-marp-osc="prev" tabindex="-1" title="Previous slide">Previous slide</button><span data-bespoke-marp-osc="page"></span><button data-bespoke-marp-osc="next" tabindex="-1" title="Next slide">Next slide</button><button data-bespoke-marp-osc="fullscreen" tabindex="-1" title="Toggle fullscreen (f)">Toggle fullscreen</button><button data-bespoke-marp-osc="presenter" tabindex="-1" title="Open presenter view (p)">Open presenter view</button></div><div id=":$p"><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="1" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="1" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h1 id="project-management-2-git-continued">Project management 2. Git continued</h1>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section data-marpit-fragments="6" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="2" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;--marpit-advanced-background-split:30%;" data-marpit-pagination-total="27" data-marpit-advanced-background="background" data-marpit-advanced-background-split="right"><div data-marpit-advanced-background-container="true" data-marpit-advanced-background-direction="horizontal"><figure style="background-image:url(&quot;imgs/git-branches.png&quot;);background-size:60%;"><figcaption>width:</figcaption></figure></div></section></foreignObject><foreignObject width="70%" height="720"><section id="2" data-marpit-fragments="6" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="2" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;--marpit-advanced-background-split:30%;" data-marpit-pagination-total="27" data-marpit-advanced-background="content" data-marpit-advanced-background-split="right">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section data-marpit-fragments="6" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="2" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;--marpit-advanced-background-split:30%;" data-marpit-pagination-total="27" data-marpit-advanced-background="background" data-marpit-advanced-background-split="right"><div data-marpit-advanced-background-container="true" data-marpit-advanced-background-direction="horizontal"><figure style="background-image:url(&quot;imgs/git-branches.png&quot;);background-size:60%;"><figcaption>width:</figcaption></figure></div></section></foreignObject><foreignObject width="70%" height="720"><section id="2" data-marpit-fragments="6" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="2" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;--marpit-advanced-background-split:30%;" data-marpit-pagination-total="27" data-marpit-advanced-background="content" data-marpit-advanced-background-split="right">
<h2 id="branches">Branches</h2>
<ul>
<li data-marpit-fragment="1">A Git repository can have multiple <em><strong>branches</strong></em></li>
<li data-marpit-fragment="2">By default, a Git repository has only one branch
<ul>
<li data-marpit-fragment="3">named either <code>master</code> or <code>main</code></li>
<li data-marpit-fragment="3">named usually <code>main</code> or <code>master</code></li>
</ul>
</li>
<li data-marpit-fragment="4">Using multiple branches makes it possible to work on new features step by step in their own <em><strong>feature branches</strong></em>
<ul>
<li data-marpit-fragment="5">Meanwhile, the <code>master</code> branch is kept clean and in a working state</li>
<li data-marpit-fragment="6">Only when the feature is completed, the branch is merged into the <code>master</code> branch!</li>
<li data-marpit-fragment="5">Meanwhile, the <code>main</code> branch is kept clean and in a working state</li>
<li data-marpit-fragment="6">Only when the feature is completed, the branch is merged into the <code>main</code> branch!</li>
</ul>
</li>
</ul>
</section>
</foreignObject><foreignObject width="1280" height="720" data-marpit-advanced-background="pseudo"><section data-marpit-fragments="6" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="2" style="" data-marpit-pagination-total="27" data-marpit-advanced-background="pseudo" data-marpit-advanced-background-split="right"></section></foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="3" data-marpit-fragments="2" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="3" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
</foreignObject><foreignObject width="1280" height="720" data-marpit-advanced-background="pseudo"><section data-marpit-fragments="6" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="2" style="" data-marpit-pagination-total="27" data-marpit-advanced-background="pseudo" data-marpit-advanced-background-split="right"></section></foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="3" data-marpit-fragments="2" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="3" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h3 id="active-branch">Active branch</h3>
<ul>
<li data-marpit-fragment="1">Even though your local repository can have multiple branches, only one of them is <em>active</em> at a given time</li>
<li data-marpit-fragment="2"><code>git status</code> tells you firsthand which branch you are on: <code>On branch master</code></li>
<li data-marpit-fragment="2"><code>git status</code> tells you firsthand which branch you are on:<pre is="marp-pre" data-auto-scaling="downscale-only"><code>On branch main
</code></pre>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="4" data-marpit-fragments="6" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="4" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="4" data-marpit-fragments="6" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="4" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h2 id="git-branch--git-checkout"><code>git branch</code> &amp; <code>git checkout</code></h2>
<ul>
<li data-marpit-fragment="1">You can create a new branch with <code>git branch &lt;branchName&gt;</code>
<li data-marpit-fragment="1">You can create a new branch with <code>git branch &lt;branchname&gt;</code>
<ul>
<li data-marpit-fragment="2">The new branch is not empty: it contains a copy of the code of the branch you executed this command in</li>
</ul>
</li>
<li data-marpit-fragment="3"><em><strong>Note:</strong></em> <code>git branch &lt;branchName&gt;</code> does not make the branch active!</li>
<li data-marpit-fragment="3"><em><strong>Note:</strong></em> <code>git branch &lt;branchname&gt;</code> does not make the branch active!</li>
<li data-marpit-fragment="4">To make the branch active, a.k.a &quot;move&quot; to the branch:
<ul>
<li data-marpit-fragment="5"><code>git checkout &lt;branchName&gt;</code>.</li>
<li data-marpit-fragment="6">For example, to move back to master use <code>git checkout master</code></li>
<li data-marpit-fragment="5"><code>git checkout &lt;branchname&gt;</code>.</li>
<li data-marpit-fragment="6">For example, to move back to the main branch, use <code>git checkout main</code></li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="5" data-marpit-fragments="5" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="5" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="5" data-marpit-fragments="5" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="5" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h3 id="local-vs-remote-branches">Local vs. remote branches</h3>
<ul>
<li data-marpit-fragment="1"><code>git branch &lt;branchName&gt;</code> only creates a local branch</li>
<li data-marpit-fragment="2">When you try to push changes from a new local branch, Git nags you that a matching remote branch doesn't yet exist
<li data-marpit-fragment="1"><code>git branch &lt;branchname&gt;</code> only creates a <em><strong>local</strong></em> branch</li>
<li data-marpit-fragment="2">When you try to push changes from a new local branch for the first time, Git nags you that a matching remote branch doesn't yet exist
<ul>
<li data-marpit-fragment="3">Git tells you how to create the remote branch:
<ul>
<li data-marpit-fragment="4"><code>git push --set-upstream origin &lt;newBranch&gt;</code></li>
<li data-marpit-fragment="4"><code>git push --set-upstream origin &lt;branchname&gt;</code></li>
<li data-marpit-fragment="5">Afterwards, <code>git push</code> pushes the changes to the matching remote branch</li>
</ul>
</li>
@ -73,12 +75,13 @@
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="6" data-marpit-fragments="8" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="6" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="6" data-marpit-fragments="8" data-paginate="true" data-class="extra invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="extra invert" data-marpit-pagination="6" style="--paginate:true;--class:extra invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h3 id="extra-branch-commands">Extra branch commands</h3>
<ul>
<li data-marpit-fragment="1">Handy command: <code>git checkout -b &lt;branchName&gt;</code>
<li data-marpit-fragment="1">Handy command: <code>git checkout -b &lt;branchname&gt;</code>
<ul>
<li data-marpit-fragment="2">It's a shorthand for <code>git branch &lt;branchName&gt;</code> + <code>git checkout &lt;branchName&gt;</code></li>
<li data-marpit-fragment="2">It's a shorthand for <code>git branch &lt;branchname&gt;</code> + <code>git checkout &lt;branchname&gt;</code></li>
</ul>
</li>
<li data-marpit-fragment="3">Get a list of local branches with <code>git branch</code>
@ -86,102 +89,116 @@
<li data-marpit-fragment="4">...and all branches (incl. the remote ones) with <code>git branch -a</code></li>
</ul>
</li>
<li data-marpit-fragment="5">Delete a local branch with <code>git branch -d &lt;branchName&gt;</code>
<li data-marpit-fragment="5">Delete a local branch with <code>git branch -d &lt;branchname&gt;</code>
<ul>
<li data-marpit-fragment="6">Remote branch can be deleted in the GitHub/etc website</li>
<li data-marpit-fragment="7">...or with <code>git push origin -d &lt;branchName&gt;</code></li>
<li data-marpit-fragment="6">Remote branch can be deleted in the GitLab/etc website
<ul>
<li data-marpit-fragment="7">...or with <code>git push origin -d &lt;branchname&gt;</code></li>
</ul>
</li>
<li data-marpit-fragment="8"><em><strong>Note:</strong></em> If deleted remote branches still show up in <code>git branch -a</code>, you can use the command <code>git remote prune origin</code> to remove them from the list.</li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="7" data-marpit-fragments="6" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="7" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="7" data-marpit-fragments="8" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="7" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h2 id="git-merge"><code>git merge</code></h2>
<ul>
<li data-marpit-fragment="1">So you've been working on a feature branch. What next?</li>
<li data-marpit-fragment="2">When the feature is done (and all the broken things fixed), you want to apply your changes back to <code>master</code></li>
<li data-marpit-fragment="3">For this, we use <code>git merge &lt;branchToMerge&gt;</code>
<ul>
<li data-marpit-fragment="4">It applies changes from <code>&lt;branchToMerge&gt;</code> to the <em><strong>current active branch</strong></em></li>
</ul>
</li>
<li data-marpit-fragment="5"><code>master</code> branch is usually (and should be) protected, so we can't merge our new code to <code>master</code> directly</li>
<li data-marpit-fragment="6">Instead, we do the <em>inverse</em>.</li>
<li data-marpit-fragment="1">When a feature is done (and all the broken things fixed), you want to apply, i.e., <em><strong>merge</strong></em> your changes from the feature branch to the <code>main</code> branch</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="8" data-marpit-fragments="8" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="8" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
<h2 id="merging-with-a-pull-request">Merging with a pull request</h2>
<ol>
<li data-marpit-fragment="1">Make sure you have the newest version of the <code>master</code> branch:</li>
</ol>
<li data-marpit-fragment="2">First, checkout the <code>main</code> branch with <code>git checkout main</code></li>
<li data-marpit-fragment="3">Then, do a <code>git pull</code> so you have the newest version of the <code>main</code> branch
<ul>
<li data-marpit-fragment="2">Checkout <code>master</code> branch</li>
<li data-marpit-fragment="3">Pull changes from GitHub/etc</li>
<li data-marpit-fragment="4">Checkout the feature branch</li>
<li data-marpit-fragment="5">Merge the contents of <code>master</code> to <code>featureBranch</code> with <code>git merge master</code></li>
<li data-marpit-fragment="4">(Someone else might have done changes to it while you were working on your feature!)</li>
</ul>
<ol start="2">
<li data-marpit-fragment="6">Then, create a <em><strong>pull request</strong></em> on GitHub/etc (In GitLab, it's called <em><strong>merge request</strong></em>!)</li>
</ol>
</li>
<li data-marpit-fragment="5">Then, merge your local feature branch to your local main branch with<br />
<code>git merge &lt;featurebranch&gt;</code>
<ul>
<li data-marpit-fragment="7">This creates a formal process for merging your <em>remote</em> feature branch to remote <code>master</code></li>
<li data-marpit-fragment="8">This adds a layer of protection to the <code>master</code> branch: no direct merging!</li>
<li data-marpit-fragment="6">It applies changes from <code>&lt;featurebranch&gt;</code> to the <em><strong>current active branch</strong></em></li>
<li data-marpit-fragment="7">This is where <em><strong>conflicts</strong></em> might happen (more about them <a href="#conflicts">later</a>)</li>
</ul>
</li>
<li data-marpit-fragment="8">Then, push your changes to remote with <code>git push</code></li>
</ol>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="9" data-marpit-fragments="2" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="9" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
<p><img src="imgs/github-pullreq.png" alt="" /></p>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="8" data-marpit-fragments="8" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="8" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h3 id="merging-with-a-pullmerge-request">Merging with a pull/merge request</h3>
<ul>
<li data-marpit-fragment="1">UI of a new pull request (<em>Pull requests &gt; New pull request</em>) can be confusing...
<li data-marpit-fragment="1">The aforementioned procedure isn't what we usually do, though!</li>
<li data-marpit-fragment="2"><code>main</code> branch should be <em><strong>protected</strong></em> so we can't merge our new code there directly
<ul>
<li data-marpit-fragment="2"><em>base</em> is the branch you're merging, <em>compare</em> is the branch you're merging into!</li>
<li data-marpit-fragment="3">Instead, we do the <em>inverse</em>.</li>
</ul>
</li>
</ul>
<ol>
<li data-marpit-fragment="4">First, checkout the <code>main</code> branch with <code>git checkout main</code></li>
<li data-marpit-fragment="5">Then, do a <code>git pull</code> so you have the newest version of the <code>main</code> branch</li>
<li data-marpit-fragment="6">Then, <em><strong>checkout back to the feature branch</strong></em>.</li>
<li data-marpit-fragment="7">Merge your local <code>main</code> branch to your local <code>featurebranch</code> with<br />
<code>git merge main</code></li>
<li data-marpit-fragment="8">Then, create a <em><strong>merge request</strong></em> on GitLab (it's <em><strong>pull request</strong></em> on GitHub—they're the same thing, just named from different points of view.)</li>
</ol>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="10" data-marpit-fragments="5" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="10" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
<h3 id="if-automatic-merge-fails">If automatic merge fails...</h3>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="9" data-marpit-fragments="6" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="9" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h3 id="simplifying-merging-further">Simplifying merging further</h3>
<ul>
<li data-marpit-fragment="1"><em><strong>Pro tip:</strong></em> If you're working on your feature branch, you can merge changes from the <code>main</code> branch without changing branches altogether.</li>
</ul>
<ol>
<li data-marpit-fragment="1">Pull remote changes to your local <code>master</code>.
<li data-marpit-fragment="2">Update your local main branch with <code>git fetch origin main:main</code></li>
<li data-marpit-fragment="3">Merge your local <code>main</code> branch to your local <code>featurebranch</code> with<br />
<code>git merge main</code></li>
<li data-marpit-fragment="4">Then, create a merge request/pull request</li>
</ol>
<ul>
<li data-marpit-fragment="5">Much easier this way!
<ul>
<li data-marpit-fragment="2"><em><strong>Pro tip:</strong></em> If you're on your feature branch, you can do this quickly without changing branches with<br />
<code>git fetch origin master:master</code></li>
<li data-marpit-fragment="6">But what is the merge request, anyway?</li>
</ul>
</li>
<li data-marpit-fragment="3">Merge changes from <code>master</code> to your local feature branch.</li>
<li data-marpit-fragment="4">Fix the ensuing <em><strong>conflicts</strong></em> (see <a href="#3-conflicts">next section</a>)</li>
<li data-marpit-fragment="5">Push your new local branch to GitHub/etc</li>
</ol>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="11" data-marpit-fragments="5" data-paginate="true" data-class="extra invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="extra invert" data-marpit-pagination="11" style="--paginate:true;--class:extra invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
<h2 id="extra-merging-without-a-pull-request">Extra: Merging without a pull request</h2>
<ol>
<li data-marpit-fragment="1">First, checkout the <code>master</code> branch with <code>git checkout master</code></li>
<li data-marpit-fragment="2">Then, do a <code>git pull</code> so you have the newest version of the <code>master</code> branch
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="10" data-marpit-fragments="6" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="10" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h3 id="merge-requestpull-request">Merge request/pull request</h3>
<ul>
<li data-marpit-fragment="3">Someone else might have done changes to it while you were working on your feature!</li>
<li data-marpit-fragment="1">Merge/pull request is a formal process for merging your <em>remote</em> feature branch straight to the remote <code>main</code> branch</li>
<li data-marpit-fragment="2">This adds a layer of protection to the <code>main</code> branch: no direct merging to the <code>main</code> branch!</li>
<li data-marpit-fragment="3">Additionally, a <em><strong>code review</strong></em> can happen at this stage:
<ul>
<li data-marpit-fragment="4">If a code maintainer thinks your merge request needs some modifications, you can make changes to the feature branch accordingly</li>
<li data-marpit-fragment="5">A merge request is branch-specific, so when you push your changes to your feature branch, the merge request is automatically updated as well.</li>
<li data-marpit-fragment="6">If this procedure is followed strictly, no bad code should get into the main branch!</li>
</ul>
</li>
<li data-marpit-fragment="4">Then, merge <code>&lt;featureBranch&gt;</code> to <code>master</code> with <code>git merge &lt;featureBranch&gt;</code>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="11" data-marpit-fragments="2" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="11" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h3 id="github-pull-request-ui">GitHub pull request UI</h3>
<p><img src="imgs/github-pullreq.png" alt="" style="width:900px;" /></p>
<ul>
<li data-marpit-fragment="1">UI of a new pull request (<em>Pull requests &gt; New pull request</em>) can be confusing...
<ul>
<li data-marpit-fragment="5">Fix conflicts</li>
<li data-marpit-fragment="2"><em>base</em> is the branch you're merging, <em>compare</em> is the branch you're merging into.</li>
</ul>
</li>
</ol>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="12" data-marpit-fragments="3" data-paginate="true" data-class="exercise invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="exercise invert" data-marpit-pagination="12" style="--paginate:true;--class:exercise invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="12" data-marpit-fragments="3" data-paginate="true" data-class="exercise invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="exercise invert" data-marpit-pagination="12" style="--paginate:true;--class:exercise invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h2 id="exercise-1-pushing-onwards">Exercise 1. Pushing onwards</h2>
<p>Continue the exercise from <a href="1-git-basics">Git Basics</a> or create a new repository for these exercises.</p>
<ul>
<ol>
<li data-marpit-fragment="1">Create a new branch (with a name <code>new-feature</code>, for instance) in your local repository.</li>
<li data-marpit-fragment="2">Checkout the branch, make some changes to <code>GitTest.md</code> there, and push the changes to GitHub.</li>
<li data-marpit-fragment="3">Then, merge the changes from your <code>new-feature</code> branch to <code>master</code> branch by using<br />
a) pull request in GitHub<br />
b) <code>git merge</code> from command line</li>
</ul>
<li data-marpit-fragment="2">Checkout the branch, make some changes to <code>GitTest.md</code> there, and push the changes to GitLab.</li>
<li data-marpit-fragment="3">Then, merge the changes from your <code>new-feature</code> branch to the <code>main</code> branch by using<br />
a) <code>git merge</code> from command line<br />
b) a merge request in GitLab</li>
</ol>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="13" data-marpit-fragments="11" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="13" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="13" data-marpit-fragments="11" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="13" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h2 id="gitlens">GitLens</h2>
<ul>
<li data-marpit-fragment="1">To make the Git workflow easier, install the GitLens extension to VS code
@ -190,38 +207,46 @@ b) <code>git merge</code> from command line</li>
</ul>
</li>
<li data-marpit-fragment="3">Install it from the Extensions panel (access with <em><strong>CTRL+SHIFT+X</strong></em>)</li>
<li data-marpit-fragment="4">Adds many new views to the source control tab:
<li data-marpit-fragment="4">Adds many new views to the source control tab</li>
</ul>
<div class='columns12' markdown='1'>
<div markdown='1'>
<ul>
<li data-marpit-fragment="5">For example:
<ul>
<li data-marpit-fragment="5">Commits</li>
<li data-marpit-fragment="6">Repositories</li>
<li data-marpit-fragment="7">File History</li>
<li data-marpit-fragment="8">Line History</li>
<li data-marpit-fragment="9">Branches</li>
<li data-marpit-fragment="10">Remotes</li>
<li data-marpit-fragment="11">etc...</li>
<li data-marpit-fragment="6">Commits</li>
<li data-marpit-fragment="7">Repositories</li>
<li data-marpit-fragment="8">File History</li>
<li data-marpit-fragment="9">Line History</li>
<li data-marpit-fragment="10">Branches</li>
<li data-marpit-fragment="11">Remotes</li>
</ul>
</li>
</ul>
</div>
<div markdown='1'>
<p><img src="imgs/gitlens.png" alt="" /></p>
</div>
</div>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="14" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="14" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
<h1 id="3-conflicts">3. Conflicts</h1>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="15" data-marpit-fragments="6" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="15" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="14" data-marpit-fragments="7" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="14" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h2 id="conflicts">Conflicts</h2>
<ul>
<li data-marpit-fragment="1">Sometimes two people have made changes in the same lines of code!
<ul>
<li data-marpit-fragment="2">This leads to a conflict.</li>
<li data-marpit-fragment="2">This leads to a <em><strong>conflict</strong></em>.</li>
</ul>
</li>
<li data-marpit-fragment="3">Let's assume we're trying to merge changes from featureBranch to master.</li>
<li data-marpit-fragment="4">If a conflict happens, the merge does not conclude automatically. Instead, we need to <em><strong>fix all the conflicts</strong></em> by hand and then <em><strong>conclude the merge</strong></em> with some commands.</li>
<li data-marpit-fragment="5">Conflicting lines of code are framed by some <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; garbage ======= symbols &gt;&gt;&gt;&gt;&gt;&gt;&gt;</code> we don't yet understand</li>
<li data-marpit-fragment="6">Before we can conclude the merge, we need to get rid of the garbage.</li>
<li data-marpit-fragment="3">Let's assume we're trying to merge changes from <code>featurebranch</code> to <code>main</code>.</li>
<li data-marpit-fragment="4">If a conflict happens, the merge does not conclude automatically.</li>
<li data-marpit-fragment="5">Instead, we need to <em><strong>fix all the conflicts</strong></em> by hand and then <em><strong>conclude the merge</strong></em> with some commands.</li>
<li data-marpit-fragment="6">Conflicting lines of code are framed by some <code>&lt;&lt;&lt;&lt; garbage ==== symbols &gt;&gt;&gt;&gt;</code><br />
we don't yet understand</li>
<li data-marpit-fragment="7">Before we can conclude the merge, we need to get rid of the garbage.</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="16" data-marpit-fragments="3" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="16" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
<h3 id="said-garbage">Said garbage</h3>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="15" data-marpit-fragments="5" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="15" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h3 id="garbage-explained">Garbage explained</h3>
<pre is="marp-pre" data-auto-scaling="downscale-only"><code class="language-c#">&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD:Player.<span class="hljs-function">cs
<span class="hljs-title">if</span> (<span class="hljs-params">Input.anyKey</span>)</span> {
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
@ -232,52 +257,69 @@ b) <code>git merge</code> from command line</li>
&gt;&gt;&gt;&gt;&gt;&gt;&gt; featureBranch:Player.cs
</code></pre>
<ul>
<li data-marpit-fragment="1"><em><strong>Current change</strong></em> is between <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt;</code> and <code>=======</code>: old code in <code>master</code></li>
<li data-marpit-fragment="2"><em><strong>Incoming change</strong></em> is between <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt;</code> and <code>=======</code>: new code from <code>featureBranch</code></li>
<li data-marpit-fragment="3">Use your text editor to choose which (or some combination of both) you want to preserve</li>
<li data-marpit-fragment="1"><em><strong>Current change</strong></em> is between <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt;</code> and <code>=======</code>
<ul>
<li data-marpit-fragment="2">old code that was already in <code>main</code></li>
</ul>
</li>
<li data-marpit-fragment="3"><em><strong>Incoming change</strong></em> is between <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt;</code> and <code>=======</code>
<ul>
<li data-marpit-fragment="4">new code coming from <code>featurebranch</code></li>
</ul>
</li>
<li data-marpit-fragment="5">Use your text editor to choose which (or some combination of both) you want to preserve</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section data-marpit-fragments="5" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="17" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;--marpit-advanced-background-split:50%;" data-marpit-pagination-total="27" data-marpit-advanced-background="background" data-marpit-advanced-background-split="right"><div data-marpit-advanced-background-container="true" data-marpit-advanced-background-direction="horizontal"><figure style="background-image:url(&quot;imgs/vscode-conflicts.png&quot;);background-size:95% auto;"></figure></div></section></foreignObject><foreignObject width="50%" height="720"><section id="17" data-marpit-fragments="5" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="17" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;--marpit-advanced-background-split:50%;" data-marpit-pagination-total="27" data-marpit-advanced-background="content" data-marpit-advanced-background-split="right">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section data-marpit-fragments="5" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="16" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;--marpit-advanced-background-split:50%;" data-marpit-pagination-total="27" data-marpit-advanced-background="background" data-marpit-advanced-background-split="right"><div data-marpit-advanced-background-container="true" data-marpit-advanced-background-direction="horizontal"><figure style="background-image:url(&quot;imgs/vscode-conflicts.png&quot;);background-size:95% auto;"></figure></div></section></foreignObject><foreignObject width="50%" height="720"><section id="16" data-marpit-fragments="5" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="16" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;--marpit-advanced-background-split:50%;" data-marpit-pagination-total="27" data-marpit-advanced-background="content" data-marpit-advanced-background-split="right">
<h3 id="vs-code-tools">VS Code tools</h3>
<ul>
<li data-marpit-fragment="1">VS Code gives us tools to make conflict resolution a quick process</li>
<li data-marpit-fragment="2">Click which lines of code you want to preserve:
<li data-marpit-fragment="1">VS Code gives us tools to make conflict resolution a relatively quick process</li>
<li data-marpit-fragment="2">Choose your preference:
<ul>
<li data-marpit-fragment="3"><em><strong>Accept Current Change</strong></em> (old code is preserved, new code removed)</li>
<li data-marpit-fragment="4"><em><strong>Accept Incoming Change</strong></em> (new code is preserved, old code removed)</li>
<li data-marpit-fragment="5"><em><strong>Accept Both Changes</strong></em> (both are preserved)</li>
<li data-marpit-fragment="3"><em><strong>Accept Current Change</strong></em><br />
(old code is preserved,<br />
new code is removed)</li>
<li data-marpit-fragment="4"><em><strong>Accept Incoming Change</strong></em> (new code is preserved,<br />
old code is removed)</li>
<li data-marpit-fragment="5"><em><strong>Accept Both Changes</strong></em><br />
(both are preserved)</li>
</ul>
</li>
</ul>
</section>
</foreignObject><foreignObject width="1280" height="720" data-marpit-advanced-background="pseudo"><section data-marpit-fragments="5" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="17" style="" data-marpit-pagination-total="27" data-marpit-advanced-background="pseudo" data-marpit-advanced-background-split="right"></section></foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="18" data-marpit-fragments="4" data-paginate="true" data-class="invert" data-footer="If VS code is not configured properly as Git's text editor, and you encounter an error, run `git config core.editor code --wait`" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="18" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
<h2 id="after-resolving-the-conflict">After resolving the conflict</h2>
</foreignObject><foreignObject width="1280" height="720" data-marpit-advanced-background="pseudo"><section data-marpit-fragments="5" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="16" style="" data-marpit-pagination-total="27" data-marpit-advanced-background="pseudo" data-marpit-advanced-background-split="right"></section></foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="17" data-marpit-fragments="6" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="17" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h3 id="after-resolving-the-conflict">After resolving the conflict</h3>
<ul>
<li data-marpit-fragment="1">After resolving conflicting files, use <code>git add &lt;filename&gt;</code> to add them to the commit</li>
<li data-marpit-fragment="1">After resolving all conflicting files, use <code>git add &lt;filename&gt;</code> to add them to the commit</li>
<li data-marpit-fragment="2">Then use <code>git commit</code> to apply changes (without a message! no <code>-m</code>)
<ul>
<li data-marpit-fragment="3">Close the automatically opened <code>COMMITMSG</code> file. This should finish the merge.</li>
<li data-marpit-fragment="3">Close the automatically opened <code>COMMITMSG</code> file.</li>
<li data-marpit-fragment="4">This finishes the merge.</li>
</ul>
</li>
<li data-marpit-fragment="4">Then just <code>git push</code> to apply changes in the remote repository</li>
<li data-marpit-fragment="5">Then just <code>git push</code> to apply changes in the remote repository</li>
<li data-marpit-fragment="6"><em><strong>Note:</strong></em> If VS code is not configured properly as the Git's text editor, and you encounter an error, run <code>git config core.editor code --wait</code></li>
</ul>
<footer>If VS code is not configured properly as Git's text editor, and you encounter an error, run <code>git config core.editor code --wait</code></footer>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="19" data-marpit-fragments="7" data-paginate="true" data-class="exercise invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="exercise invert" data-marpit-pagination="19" style="--paginate:true;--class:exercise invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="18" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="18" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h3 id="example-git-workflow-with-branches">Example Git workflow with branches</h3>
<p><img src="imgs/merge-workflow.png" alt="" style="width:1200px;" /></p>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="19" data-marpit-fragments="6" data-paginate="true" data-class="exercise invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="exercise invert" data-marpit-pagination="19" style="--paginate:true;--class:exercise invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h2 id="exercise-2-fixing-conflicts">Exercise 2. Fixing conflicts</h2>
<ul>
<p>Continue in the Exercise 1 repository.</p>
<ol>
<li data-marpit-fragment="1">Create a new branch in your local repository, but do not checkout it just yet.</li>
<li data-marpit-fragment="2">First, we simulate your teammate's changes by making changes to the <code>master</code> branch directly: On the <code>master</code> branch, make some changes to <code>GitTest.md</code>, and <strong>add &amp; commit</strong>.</li>
<li data-marpit-fragment="2">On the <code>main</code> branch, make some changes to <code>GitTest.md</code>, and <strong>add &amp; commit</strong>.</li>
<li data-marpit-fragment="3">Then, checkout the new feature branch.</li>
<li data-marpit-fragment="4">Then, make some other changes to GitTest.md to the same line as before, <strong>add &amp; commit</strong>.</li>
<li data-marpit-fragment="5">Then, merge the changes from the <code>master</code> branch to your feature branch by using <code>git merge</code></li>
<li data-marpit-fragment="4">Make some <em><strong>other</strong></em> changes to GitTest.md to the same line as before, <strong>add &amp; commit</strong>.</li>
<li data-marpit-fragment="5">Then, merge the changes from the <code>main</code> branch to your feature branch by using <code>git merge</code></li>
<li data-marpit-fragment="6">Fix the ensuing conflicts, add &amp; commit &amp; push.</li>
<li data-marpit-fragment="7">Now you can create a pull request to merge your changes to the master branch.</li>
</ul>
</ol>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="20" data-marpit-fragments="4" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="20" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
<h2 id="git-workflow-3-undoing">Git workflow 3: Undoing</h2>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="20" data-marpit-fragments="4" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="20" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h2 id="undoing">Undoing</h2>
<ul>
<li data-marpit-fragment="1">Git doesn't have a general &quot;undo&quot; command</li>
<li data-marpit-fragment="2">If you make a mistake, it is very case-specific what you need to do to fix it
@ -288,7 +330,7 @@ b) <code>git merge</code> from command line</li>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="21" data-marpit-fragments="7" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="21" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="21" data-marpit-fragments="8" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="21" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h2 id="git-log--git-checkout-hashcode"><code>git log</code> &amp; <code>git checkout &lt;hashcode&gt;</code></h2>
<ul>
<li data-marpit-fragment="1">
@ -304,55 +346,40 @@ b) <code>git merge</code> from command line</li>
<li data-marpit-fragment="7">
<p><em><strong>Note:</strong></em> If you have GitLens, check the Commits view in the Source control tab to see the commit history.</p>
</li>
<li data-marpit-fragment="8"></li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="22" data-marpit-fragments="8" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="22" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
<h2 id="revert-one-file-to-a-previous-state">Revert one file to a previous state</h2>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="22" data-marpit-fragments="7" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="22" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h3 id="reverting-one-file-to-a-previous-state">Reverting one file to a previous state</h3>
<ul>
<li data-marpit-fragment="1">Sometimes you want to revert just one file to its previous state</li>
<li data-marpit-fragment="2">For that, you need to figure out the commit hash of the state you want to return to</li>
<li data-marpit-fragment="3">Find that out in one of the following methods:
<li data-marpit-fragment="2">You can use <code>git checkout &lt;commit-hash&gt; -- &lt;filename&gt;</code> to time travel just that file to how it was in that commit</li>
<li data-marpit-fragment="3">For this, you of course need to figure out the commit hash you want to return to</li>
<li data-marpit-fragment="4">Find that out in one of the following methods:
<ul>
<li data-marpit-fragment="4"><code>git log --oneline</code></li>
<li data-marpit-fragment="5">VS Code: <em>Source control &gt; File history</em></li>
<li data-marpit-fragment="6">GitHub: check commits</li>
</ul>
</li>
<li data-marpit-fragment="7">Then, run
<ul>
<li data-marpit-fragment="8"><code>git checkout &lt;commit-hash&gt; -- &lt;filename&gt;</code></li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="23" data-marpit-fragments="7" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="23" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
<h2 id="collaboration-in-unity">Collaboration in Unity</h2>
<ul>
<li data-marpit-fragment="1"><em><strong>The zeroth rule:</strong></em> Make sure that everyone on team uses the same Unity and package versions.</li>
<li data-marpit-fragment="2"><em><strong>The first rule:</strong></em> Don't ever work on the same thing simultaneously.</li>
<li data-marpit-fragment="3"><em><strong>The second rule:</strong></em> When you do break rule #1, make necessary changes in communication so you won't break it again.</li>
<li data-marpit-fragment="4">Be sure to communicate about <em><strong>scene ownership</strong></em>
<ul>
<li data-marpit-fragment="5">Scenes are not code files, so you can't easily merge changes if two people have worked on them</li>
<li data-marpit-fragment="6">Thus, the <em><strong>Scene Owner</strong></em> will be the only person on the team who should be working on a certain scene</li>
<li data-marpit-fragment="7">If a scene needs GameObject contributions from others, they can create prefabs that the Scene Owners then add to their scene</li>
<li data-marpit-fragment="5"><code>git log --oneline</code></li>
<li data-marpit-fragment="6">VS Code: <em>Source control &gt; File history</em></li>
<li data-marpit-fragment="7">Check commits from GitHub/GitLab</li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="24" data-marpit-fragments="6" data-paginate="true" data-class="exercise invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="exercise invert" data-marpit-pagination="24" style="--paginate:true;--class:exercise invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="23" data-marpit-fragments="5" data-paginate="true" data-class="exercise invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="exercise invert" data-marpit-pagination="23" style="--paginate:true;--class:exercise invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h2 id="exercise-3-branching-team-effort">Exercise 3. Branching team effort</h2>
<p>Work as a group for this assignment. Continue Exercise 2 from <a href="1-git-basics">Git basics</a>.</p>
<ol>
<li data-marpit-fragment="1">Every group member: create your own individual branch from the <code>main</code> branch</li>
<li data-marpit-fragment="2">Then, make some changes to the <code>GitTest.md</code> file.
<ul>
<li data-marpit-fragment="1">Work as a group for this assignment.</li>
<li data-marpit-fragment="2">Continue Exercise 2 from <a href="1-git-basics">Git basics</a>.</li>
<li data-marpit-fragment="3">Every group member creates an individual branch from the master, and makes some changes to the <code>GitTest.md</code> file.</li>
<li data-marpit-fragment="4">Add new files as well, at least one per group member.</li>
<li data-marpit-fragment="5">Do not tell other group members what you're going to change! :D</li>
<li data-marpit-fragment="6">Then, merge the changes back to the master branch. Fix ensuing conflicts, if any appear.</li>
<li data-marpit-fragment="3">Do not tell other group members what you're going to change! :D</li>
</ul>
</li>
<li data-marpit-fragment="4">Add new files as well, at least one file per group member.</li>
<li data-marpit-fragment="5">Then, merge the changes back to the <code>main</code> branch. Fix ensuing conflicts, if any appear.</li>
</ol>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="25" data-marpit-fragments="3" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="invert" data-marpit-pagination="25" style="--paginate:true;--class:invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="24" data-marpit-fragments="3" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="invert" data-marpit-pagination="24" style="--paginate:true;--class:invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h2 id="reading">Reading</h2>
<ul>
<li data-marpit-fragment="1"><a href="https://git-scm.com/book/en/v2">Pro Git book</a></li>
@ -360,13 +387,14 @@ b) <code>git merge</code> from command line</li>
<li data-marpit-fragment="3"><a href="https://docs.gitlab.com/ee/topics/git/numerous_undo_possibilities_in_git/">Undo possibilities</a></li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="26" data-marpit-fragments="9" data-paginate="true" data-class="extra invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="extra invert" data-marpit-pagination="26" style="--paginate:true;--class:extra invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="25" data-marpit-fragments="8" data-paginate="true" data-class="extra invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="extra invert" data-marpit-pagination="25" style="--paginate:true;--class:extra invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h2 id="very-extra-git-rebase">Very extra: <code>git rebase</code></h2>
<ul>
<li data-marpit-fragment="1"><code>git merge</code> creates a new commit for the merge process</li>
<li data-marpit-fragment="2">Sometimes that's undesirable, so an alternative is to use <code>git rebase</code></li>
<li data-marpit-fragment="3">Unlike merge, rebase applies changes from the rebased branch <em><strong>one commit at a time</strong></em></li>
<li data-marpit-fragment="3">Unlike merge, rebase applies changes from the rebased branch<br />
<em><strong>one commit at a time</strong></em></li>
<li data-marpit-fragment="4">Whenever there's a conflict:</li>
</ul>
<ol>
@ -375,11 +403,25 @@ b) <code>git merge</code> from command line</li>
<li data-marpit-fragment="7">If you want to disregard a conflicting commit, use <code>git rebase --skip</code></li>
<li data-marpit-fragment="8">If you get cold feet, you can cancel the rebase with <code>git rebase --abort</code></li>
</ol>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="26" data-marpit-fragments="8" data-paginate="true" data-class="extra invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="extra invert" data-marpit-pagination="26" style="--paginate:true;--class:extra invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h2 id="very-extra-interactive-git-rebase--i">Very extra: Interactive <code>git rebase -i</code></h2>
<ul>
<li data-marpit-fragment="1"><code>git rebase</code> also has a hidden <em><strong>interactive</strong></em> mode used with <code>git rebase -i</code></li>
<li data-marpit-fragment="2">This is a true swiss army knife of a Git tool for rewriting Git history</li>
<li data-marpit-fragment="3">It can:
<ul>
<li data-marpit-fragment="9"><em><strong>Note:</strong></em> A good link for <a href="https://borbware.github.io/unity-basics-course/project-management/2-git-continued-slides.html">understanding rebase</a></li>
<li data-marpit-fragment="4">Squash commits into one</li>
<li data-marpit-fragment="5">Cherry-pick only certain commits</li>
<li data-marpit-fragment="6">Reword commit messages</li>
<li data-marpit-fragment="7">And more!</li>
</ul>
</li>
<li data-marpit-fragment="8">See <a href="https://hackernoon.com/beginners-guide-to-interactive-rebasing-346a3f9c3a6d">Hackernoon: Beginners Guide to Interactive Rebasing</a></li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="27" data-marpit-fragments="5" data-paginate="true" data-class="extra invert" data-heading-divider="3" data-theme="79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5" lang="en-US" class="extra invert" data-marpit-pagination="27" style="--paginate:true;--class:extra invert;--heading-divider:3;--theme:79cyd3oru1j29cg66ofi9uvfluhymakxwh6huu59m5;" data-marpit-pagination-total="27">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="27" data-marpit-fragments="5" data-paginate="true" data-class="extra invert" data-heading-divider="3" data-theme="ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd" lang="en-US" class="extra invert" data-marpit-pagination="27" style="--paginate:true;--class:extra invert;--heading-divider:3;--theme:ybejrdgvlcl0z8let7y30k9ggispck2i7go0p3siwhvd;" data-marpit-pagination-total="27">
<h2 id="very-very-extra-git-submodules">Very very extra: Git submodules</h2>
<ul>

@ -13,127 +13,148 @@ theme: buutti
* A Git repository can have multiple ***branches***
* By default, a Git repository has only one branch
* named either `master` or `main`
* named usually `main` or `master`
* Using multiple branches makes it possible to work on new features step by step in their own ***feature branches***
* Meanwhile, the `master` branch is kept clean and in a working state
* Only when the feature is completed, the branch is merged into the `master` branch!
* Meanwhile, the `main` branch is kept clean and in a working state
* Only when the feature is completed, the branch is merged into the `main` branch!
![bg right:30% width: 60%](imgs/git-branches.png)
### Active branch
* Even though your local repository can have multiple branches, only one of them is *active* at a given time
* `git status` tells you firsthand which branch you are on: `On branch master`
* `git status` tells you firsthand which branch you are on:
```
On branch main
```
## `git branch` & `git checkout`
* You can create a new branch with `git branch <branchName>`
* You can create a new branch with `git branch <branchname>`
* The new branch is not empty: it contains a copy of the code of the branch you executed this command in
* ***Note:*** `git branch <branchName>` does not make the branch active!
* ***Note:*** `git branch <branchname>` does not make the branch active!
* To make the branch active, a.k.a "move" to the branch:
* `git checkout <branchName>`.
* For example, to move back to master use `git checkout master`
* `git checkout <branchname>`.
* For example, to move back to the main branch, use `git checkout main`
### Local vs. remote branches
* `git branch <branchName>` only creates a local branch
* When you try to push changes from a new local branch, Git nags you that a matching remote branch doesn't yet exist
* `git branch <branchname>` only creates a ***local*** branch
* When you try to push changes from a new local branch for the first time, Git nags you that a matching remote branch doesn't yet exist
* Git tells you how to create the remote branch:
* `git push --set-upstream origin <newBranch>`
* `git push --set-upstream origin <branchname>`
* Afterwards, `git push` pushes the changes to the matching remote branch
### Extra branch commands
<!-- _class: "extra invert" -->
* Handy command: `git checkout -b <branchName>`
* It's a shorthand for `git branch <branchName>` + `git checkout <branchName>`
* Handy command: `git checkout -b <branchname>`
* It's a shorthand for `git branch <branchname>` + `git checkout <branchname>`
* Get a list of local branches with `git branch`
* ...and all branches (incl. the remote ones) with `git branch -a`
* Delete a local branch with `git branch -d <branchName>`
* Remote branch can be deleted in the GitHub/etc website
* ...or with `git push origin -d <branchName>`
* Delete a local branch with `git branch -d <branchname>`
* Remote branch can be deleted in the GitLab/etc website
* ...or with `git push origin -d <branchname>`
* ***Note:*** If deleted remote branches still show up in `git branch -a`, you can use the command `git remote prune origin` to remove them from the list.
## `git merge`
* So you've been working on a feature branch. What next?
* When the feature is done (and all the broken things fixed), you want to apply your changes back to `master`
* For this, we use `git merge <branchToMerge>`
* It applies changes from `<branchToMerge>` to the ***current active branch***
* `master` branch is usually (and should be) protected, so we can't merge our new code to `master` directly
* Instead, we do the *inverse*.
* When a feature is done (and all the broken things fixed), you want to apply, i.e., ***merge*** your changes from the feature branch to the `main` branch
1) First, checkout the `main` branch with `git checkout main`
2) Then, do a `git pull` so you have the newest version of the `main` branch
* (Someone else might have done changes to it while you were working on your feature!)
3) Then, merge your local feature branch to your local main branch with
`git merge <featurebranch>`
* It applies changes from `<featurebranch>` to the ***current active branch***
* This is where ***conflicts*** might happen (more about them [later](#conflicts))
4) Then, push your changes to remote with `git push`
## Merging with a pull request
### Merging with a pull/merge request
1) Make sure you have the newest version of the `master` branch:
* Checkout `master` branch
* Pull changes from GitHub/etc
* Checkout the feature branch
* Merge the contents of `master` to `featureBranch` with `git merge master`
2) Then, create a ***pull request*** on GitHub/etc (In GitLab, it's called ***merge request***!)
* This creates a formal process for merging your *remote* feature branch to remote `master`
* This adds a layer of protection to the `master` branch: no direct merging!
* The aforementioned procedure isn't what we usually do, though!
* `main` branch should be ***protected*** so we can't merge our new code there directly
* Instead, we do the *inverse*.
1) First, checkout the `main` branch with `git checkout main`
2) Then, do a `git pull` so you have the newest version of the `main` branch
3) Then, ***checkout back to the feature branch***.
4) Merge your local `main` branch to your local `featurebranch` with
`git merge main`
5) Then, create a ***merge request*** on GitLab (it's ***pull request*** on GitHub—they're the same thing, just named from different points of view.)
---
### Simplifying merging further
![](imgs/github-pullreq.png)
* ***Pro tip:*** If you're working on your feature branch, you can merge changes from the `main` branch without changing branches altogether.
1) Update your local main branch with ```git fetch origin main:main```
2) Merge your local `main` branch to your local `featurebranch` with
`git merge main`
3) Then, create a merge request/pull request
* UI of a new pull request (*Pull requests > New pull request*) can be confusing...
* *base* is the branch you're merging, *compare* is the branch you're merging into!
* Much easier this way!
* But what is the merge request, anyway?
### If automatic merge fails...
### Merge request/pull request
1) Pull remote changes to your local `master`.
* ***Pro tip:*** If you're on your feature branch, you can do this quickly without changing branches with
```git fetch origin master:master```
2) Merge changes from `master` to your local feature branch.
3) Fix the ensuing ***conflicts*** (see [next section](#3-conflicts))
4) Push your new local branch to GitHub/etc
* Merge/pull request is a formal process for merging your *remote* feature branch straight to the remote `main` branch
* This adds a layer of protection to the `main` branch: no direct merging to the `main` branch!
* Additionally, a ***code review*** can happen at this stage:
* If a code maintainer thinks your merge request needs some modifications, you can make changes to the feature branch accordingly
* A merge request is branch-specific, so when you push your changes to your feature branch, the merge request is automatically updated as well.
* If this procedure is followed strictly, no bad code should get into the main branch!
## Extra: Merging without a pull request
<!-- _class: "extra invert" -->
### GitHub pull request UI
![w:900px](imgs/github-pullreq.png)
1) First, checkout the `master` branch with `git checkout master`
2) Then, do a `git pull` so you have the newest version of the `master` branch
* Someone else might have done changes to it while you were working on your feature!
3) Then, merge `<featureBranch>` to `master` with `git merge <featureBranch>`
* Fix conflicts
* UI of a new pull request (*Pull requests > New pull request*) can be confusing...
* *base* is the branch you're merging, *compare* is the branch you're merging into.
## Exercise 1. Pushing onwards
<!--_class: "exercise invert" -->
Continue the exercise from [Git Basics](1-git-basics) or create a new repository for these exercises.
* Create a new branch (with a name `new-feature`, for instance) in your local repository.
* Checkout the branch, make some changes to `GitTest.md` there, and push the changes to GitHub.
* Then, merge the changes from your `new-feature` branch to `master` branch by using
a) pull request in GitHub
b) `git merge` from command line
1) Create a new branch (with a name `new-feature`, for instance) in your local repository.
2) Checkout the branch, make some changes to `GitTest.md` there, and push the changes to GitLab.
3) Then, merge the changes from your `new-feature` branch to the `main` branch by using
a) `git merge` from command line
b) a merge request in GitLab
## GitLens
* To make the Git workflow easier, install the GitLens extension to VS code
* It helps in managing conflicts, comparing branches or commits
* Install it from the Extensions panel (access with ***CTRL+SHIFT+X***)
* Adds many new views to the source control tab:
* Adds many new views to the source control tab
<div class='columns12' markdown='1'>
<div markdown='1'>
* For example:
* Commits
* Repositories
* File History
* Line History
* Branches
* Remotes
* etc...
# 3. Conflicts
</div>
<div markdown='1'>
![](imgs/gitlens.png)
</div>
</div>
## Conflicts
* Sometimes two people have made changes in the same lines of code!
* This leads to a conflict.
* Let's assume we're trying to merge changes from featureBranch to master.
* If a conflict happens, the merge does not conclude automatically. Instead, we need to ***fix all the conflicts*** by hand and then ***conclude the merge*** with some commands.
* Conflicting lines of code are framed by some `<<<<<<< garbage ======= symbols >>>>>>>` we don't yet understand
* This leads to a ***conflict***.
* Let's assume we're trying to merge changes from `featurebranch` to `main`.
* If a conflict happens, the merge does not conclude automatically.
* Instead, we need to ***fix all the conflicts*** by hand and then ***conclude the merge*** with some commands.
* Conflicting lines of code are framed by some `<<<< garbage ==== symbols >>>>`
we don't yet understand
* Before we can conclude the merge, we need to get rid of the garbage.
### Said garbage
### Garbage explained
```c#
<<<<<<< HEAD:Player.cs
@ -145,40 +166,51 @@ Continue the exercise from [Git Basics](1-git-basics) or create a new repository
return true;
>>>>>>> featureBranch:Player.cs
```
* ***Current change*** is between `<<<<<<<` and `=======`: old code in `master`
* ***Incoming change*** is between `>>>>>>>` and `=======`: new code from `featureBranch`
* ***Current change*** is between `<<<<<<<` and `=======`
* old code that was already in `main`
* ***Incoming change*** is between `>>>>>>>` and `=======`
* new code coming from `featurebranch`
* Use your text editor to choose which (or some combination of both) you want to preserve
### VS Code tools
* VS Code gives us tools to make conflict resolution a quick process
* Click which lines of code you want to preserve:
* ***Accept Current Change*** (old code is preserved, new code removed)
* ***Accept Incoming Change*** (new code is preserved, old code removed)
* ***Accept Both Changes*** (both are preserved)
* VS Code gives us tools to make conflict resolution a relatively quick process
* Choose your preference:
* ***Accept Current Change***
(old code is preserved,
new code is removed)
* ***Accept Incoming Change*** (new code is preserved,
old code is removed)
* ***Accept Both Changes***
(both are preserved)
![bg right width:95%](imgs/vscode-conflicts.png)
## After resolving the conflict
* After resolving conflicting files, use `git add <filename>` to add them to the commit
### After resolving the conflict
* After resolving all conflicting files, use `git add <filename>` to add them to the commit
* Then use `git commit` to apply changes (without a message! no `-m`)
* Close the automatically opened `COMMITMSG` file. This should finish the merge.
* Close the automatically opened `COMMITMSG` file.
* This finishes the merge.
* Then just `git push` to apply changes in the remote repository
* ***Note:*** If VS code is not configured properly as the Git's text editor, and you encounter an error, run `git config core.editor code --wait`
### Example Git workflow with branches
<!-- _footer: "If VS code is not configured properly as Git's text editor, and you encounter an error, run `git config core.editor code --wait`" -->
![w:1200px](imgs/merge-workflow.png)
## Exercise 2. Fixing conflicts
<!--_class: "exercise invert" -->
* Create a new branch in your local repository, but do not checkout it just yet.
* First, we simulate your teammate's changes by making changes to the `master` branch directly: On the `master` branch, make some changes to `GitTest.md`, and **add & commit**.
* Then, checkout the new feature branch.
* Then, make some other changes to GitTest.md to the same line as before, **add & commit**.
* Then, merge the changes from the `master` branch to your feature branch by using `git merge`
* Fix the ensuing conflicts, add & commit & push.
* Now you can create a pull request to merge your changes to the master branch.
Continue in the Exercise 1 repository.
## Git workflow 3: Undoing
1) Create a new branch in your local repository, but do not checkout it just yet.
2) On the `main` branch, make some changes to `GitTest.md`, and **add & commit**.
3) Then, checkout the new feature branch.
4) Make some ***other*** changes to GitTest.md to the same line as before, **add & commit**.
5) Then, merge the changes from the `main` branch to your feature branch by using `git merge`
6) Fix the ensuing conflicts, add & commit & push.
## Undoing
* Git doesn't have a general "undo" command
* If you make a mistake, it is very case-specific what you need to do to fix it
@ -195,37 +227,26 @@ Continue the exercise from [Git Basics](1-git-basics) or create a new repository
* Use `git checkout <hashcode>` to "time travel" into the commit
* ***Note:*** If you have GitLens, check the Commits view in the Source control tab to see the commit history.
## Revert one file to a previous state
*
### Reverting one file to a previous state
* Sometimes you want to revert just one file to its previous state
* For that, you need to figure out the commit hash of the state you want to return to
* You can use `git checkout <commit-hash> -- <filename>` to time travel just that file to how it was in that commit
* For this, you of course need to figure out the commit hash you want to return to
* Find that out in one of the following methods:
* `git log --oneline`
* VS Code: *Source control > File history*
* GitHub: check commits
* Then, run
* `git checkout <commit-hash> -- <filename>`
## Collaboration in Unity
* ***The zeroth rule:*** Make sure that everyone on team uses the same Unity and package versions.
* ***The first rule:*** Don't ever work on the same thing simultaneously.
* ***The second rule:*** When you do break rule #1, make necessary changes in communication so you won't break it again.
* Be sure to communicate about ***scene ownership***
* Scenes are not code files, so you can't easily merge changes if two people have worked on them
* Thus, the ***Scene Owner*** will be the only person on the team who should be working on a certain scene
* If a scene needs GameObject contributions from others, they can create prefabs that the Scene Owners then add to their scene
* Check commits from GitHub/GitLab
## Exercise 3. Branching team effort
<!--_class: "exercise invert" -->
* Work as a group for this assignment.
* Continue Exercise 2 from [Git basics](1-git-basics).
* Every group member creates an individual branch from the master, and makes some changes to the `GitTest.md` file.
* Add new files as well, at least one per group member.
* Do not tell other group members what you're going to change! :D
* Then, merge the changes back to the master branch. Fix ensuing conflicts, if any appear.
Work as a group for this assignment. Continue Exercise 2 from [Git basics](1-git-basics).
1) Every group member: create your own individual branch from the `main` branch
2) Then, make some changes to the `GitTest.md` file.
* Do not tell other group members what you're going to change! :D
3) Add new files as well, at least one file per group member.
4) Then, merge the changes back to the `main` branch. Fix ensuing conflicts, if any appear.
## Reading
@ -238,14 +259,25 @@ Continue the exercise from [Git Basics](1-git-basics) or create a new repository
* `git merge` creates a new commit for the merge process
* Sometimes that's undesirable, so an alternative is to use `git rebase`
* Unlike merge, rebase applies changes from the rebased branch ***one commit at a time***
* Unlike merge, rebase applies changes from the rebased branch
***one commit at a time***
* Whenever there's a conflict:
1) After fixing the conflict, add the conflicting file with `git add <filename>`
2) Then continue the rebase process with `git rebase --continue`
3) If you want to disregard a conflicting commit, use `git rebase --skip`
4) If you get cold feet, you can cancel the rebase with `git rebase --abort`
* ***Note:*** A good link for [understanding rebase](https://borbware.github.io/unity-basics-course/project-management/2-git-continued-slides.html)
## Very extra: Interactive `git rebase -i`
<!-- _class: "extra invert" -->
* `git rebase` also has a hidden ***interactive*** mode used with `git rebase -i`
* This is a true swiss army knife of a Git tool for rewriting Git history
* It can:
* Squash commits into one
* Cherry-pick only certain commits
* Reword commit messages
* And more!
* See [Hackernoon: Beginners Guide to Interactive Rebasing](https://hackernoon.com/beginners-guide-to-interactive-rebasing-346a3f9c3a6d)
## Very very extra: Git submodules
<!-- _class: "extra invert" -->

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Loading…
Cancel
Save