Merge branch 'main' of gitea.buutti.com:education/programming-basics

main
borb 1 week ago
commit c54b632621

@ -13,10 +13,10 @@
/* 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 6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d */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="6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d" lang="en-US" class="invert" data-marpit-pagination="1" style="--paginate:true;--class:invert;--heading-divider:3;--theme:6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d;" data-marpit-pagination-total="14">
/* @theme galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg */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="galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg" lang="en-US" class="invert" data-marpit-pagination="1" style="--paginate:true;--class:invert;--heading-divider:3;--theme:galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg;" data-marpit-pagination-total="15">
<h1 id="project-management-0-git-setup">Project management 0. Git setup</h1>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="2" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d" lang="en-US" class="invert" data-marpit-pagination="2" style="--paginate:true;--class:invert;--heading-divider:3;--theme:6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d;" data-marpit-pagination-total="14">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="2" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg" lang="en-US" class="invert" data-marpit-pagination="2" style="--paginate:true;--class:invert;--heading-divider:3;--theme:galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg;" data-marpit-pagination-total="15">
<h2 id="contents">Contents</h2>
<ul>
<li><a href="#contents">Contents</a></li>
@ -29,50 +29,82 @@
<li><a href="#btw-config">Btw: Config</a></li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="3" data-marpit-fragments="5" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d" lang="en-US" class="invert" data-marpit-pagination="3" style="--paginate:true;--class:invert;--heading-divider:3;--theme:6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d;" data-marpit-pagination-total="14">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="3" data-marpit-fragments="5" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg" lang="en-US" class="invert" data-marpit-pagination="3" style="--paginate:true;--class:invert;--heading-divider:3;--theme:galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg;" data-marpit-pagination-total="15">
<h2 id="what-is-git">What is Git?</h2>
<ul>
<li data-marpit-fragment="1">Git is a version control tool originally created by Linus Torvalds in 2005</li>
<li data-marpit-fragment="1">Git is a <em><strong>version control</strong></em> tool originally created by Linus Torvalds in 2005</li>
<li data-marpit-fragment="2">Keeps track of code changes</li>
<li data-marpit-fragment="3">Can be used to backup code in the cloud</li>
<li data-marpit-fragment="4">Enables cooperation with other team members</li>
<li data-marpit-fragment="5">Ubiquitous in software development</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="7" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d" lang="en-US" class="invert" data-marpit-pagination="4" style="--paginate:true;--class:invert;--heading-divider:3;--theme:6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d;" data-marpit-pagination-total="14">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="4" data-marpit-fragments="8" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg" lang="en-US" class="invert" data-marpit-pagination="4" style="--paginate:true;--class:invert;--heading-divider:3;--theme:galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg;" data-marpit-pagination-total="15">
<h3 id="why-version-control">Why version control?</h3>
<ul>
<li data-marpit-fragment="1">Without version control, only one version of your code exists
<ul>
<li data-marpit-fragment="2"><em>What happens when you realize you made a mistake and need to roll back changes you've made?</em></li>
</ul>
</li>
<li data-marpit-fragment="3">You could use manual backups, or a cloud storage service
<ul>
<li data-marpit-fragment="4"><em>What happens if two people connect to a cloud service and edit the same file?</em></li>
<li data-marpit-fragment="5">Or maybe not even the same file... <em>What happens when you and your teammate have made changes to code and you need to combine your work into a single, working version?</em></li>
</ul>
</li>
<li data-marpit-fragment="6">Version control handles all the problems above, and you can focus on the important part: programming!
<ul>
<li data-marpit-fragment="7">You can even try out some big changes that break your software completely</li>
<li data-marpit-fragment="8">If that doesn't work out, just roll back into the last working version!</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="7" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg" lang="en-US" class="invert" data-marpit-pagination="5" style="--paginate:true;--class:invert;--heading-divider:3;--theme:galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg;" data-marpit-pagination-total="15">
<h3 id="git-vs-cloud-storage">Git vs cloud storage</h3>
<ul>
<li data-marpit-fragment="1">Git is different from cloud storage services like Dropbox, Google Drive or OneDrive
<ul>
<li data-marpit-fragment="2">Instead of automatic syncing, you deliberately <em>push to</em> and <em>pull from</em> the cloud</li>
<li data-marpit-fragment="3">Cloud services are easier for starters</li>
<li data-marpit-fragment="3">Cloud services are easier for beginners</li>
<li data-marpit-fragment="4">...but in projects of more than one person, tracking changes would be a pain</li>
</ul>
</li>
<li data-marpit-fragment="5">Git has a steep learning curve
<li data-marpit-fragment="5">Git is used via the <em><strong>terminal</strong></em> and has a steep learning curve
<ul>
<li data-marpit-fragment="6">To ease things, there are some visual tools like <strong>Sourcetree</strong> or <strong>Sublime Merge</strong></li>
<li data-marpit-fragment="7">To use them effectively, you still need to understand how Git works, though</li>
<li data-marpit-fragment="6">There are some visual tools like <strong>Sourcetree</strong> or <strong>Sublime Merge</strong></li>
<li data-marpit-fragment="7">To use them effectively, though, <em>you must still understand how Git works</em></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="4" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d" lang="en-US" class="invert" data-marpit-pagination="5" style="--paginate:true;--class:invert;--heading-divider:3;--theme:6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d;" data-marpit-pagination-total="14">
<h2 id="github-and-other-developer-platforms">GitHub and other developer platforms</h2>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="6" data-marpit-fragments="4" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg" lang="en-US" class="invert" data-marpit-pagination="6" style="--paginate:true;--class:invert;--heading-divider:3;--theme:galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg;" data-marpit-pagination-total="15">
<h2 id="remote-storage-services">Remote storage services</h2>
<div class='columns' style='grid-template-columns: 5fr 1fr;' markdown='1'>
<div markdown='1'>
<ul>
<li data-marpit-fragment="1">Git <em>could</em> be used locally, but its usage is almost always combined with a developer platform — a remote storage service like <a href="https://github.com/">GitHub</a>, <a href="https://gitlab.com/">GitLab</a> or <a href="https://bitbucket.com/">BitBucket</a>
<ul>
<li data-marpit-fragment="2">These services can also double as a programming portfolio</li>
<li data-marpit-fragment="2">These services can also double as a programming portfolio that can help getting hired into the industry</li>
<li data-marpit-fragment="3">Commonly used in both open source and commercial projects</li>
</ul>
</li>
<li data-marpit-fragment="4">In Buutti's trainings, GitLab is most commonly used</li>
<li data-marpit-fragment="4">In Buutti's trainings, <em><strong>GitLab</strong></em> is most commonly used</li>
</ul>
</div>
<div markdown='1'>
<p><img src="imgs/git-basics_1.png" alt="" style="width:150px;" /></p>
<p><img src="imgs/git-basics_2.png" alt="" style="width:150px;" /></p>
<p><img src="imgs/git-basics_0.png" alt="" style="width:150px;" /></p>
</div>
</div>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="6" data-marpit-fragments="5" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d" lang="en-US" class="invert" data-marpit-pagination="6" style="--paginate:true;--class:invert;--heading-divider:3;--theme:6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d;" data-marpit-pagination-total="14">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="7" data-marpit-fragments="5" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg" lang="en-US" class="invert" data-marpit-pagination="7" style="--paginate:true;--class:invert;--heading-divider:3;--theme:galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg;" data-marpit-pagination-total="15">
<h2 id="setup">Setup</h2>
<p><img src="imgs/git-basics_3.png" alt="" style="width:450px;" /></p>
<ul>
<li data-marpit-fragment="1">Install Git
<li data-marpit-fragment="1">Installing Git:
<ul>
<li data-marpit-fragment="2">Windows/Mac: <a href="https://git-scm.com">git-scm.com</a>
<ul>
@ -85,7 +117,7 @@
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="7" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d" lang="en-US" class="invert" data-marpit-pagination="7" style="--paginate:true;--class:invert;--heading-divider:3;--theme:6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d;" data-marpit-pagination-total="14">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="8" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg" lang="en-US" class="invert" data-marpit-pagination="8" style="--paginate:true;--class:invert;--heading-divider:3;--theme:galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg;" data-marpit-pagination-total="15">
<h2 id="git-setup-settings-for-windows">Git setup: Settings for Windows</h2>
<div class="columns" markdown="1">
<div markdown="1">
@ -93,17 +125,17 @@
</div>
<div markdown="1">
<p><img src="imgs/git3.png" alt="" /></p>
<p>Set manually after setup with:</p>
<p>To set manually after setup, use:</p>
<pre is="marp-pre" data-auto-scaling="downscale-only"><code>git config --global core.editor &quot;code --wait&quot;
</code></pre>
</div>
</div>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="8" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d" lang="en-US" class="invert" data-marpit-pagination="8" style="--paginate:true;--class:invert;--heading-divider:3;--theme:6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d;" data-marpit-pagination-total="14">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="9" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg" lang="en-US" class="invert" data-marpit-pagination="9" style="--paginate:true;--class:invert;--heading-divider:3;--theme:galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg;" data-marpit-pagination-total="15">
<div class="columns" markdown="1">
<div markdown="1">
<p><img src="imgs/git2.png" alt="" /></p>
<p>Set manually after setup with:</p>
<p>To set manually after setup, use:</p>
<pre is="marp-pre" data-auto-scaling="downscale-only"><code>git config --global init.defaultBranch main
</code></pre>
</div>
@ -112,7 +144,7 @@
</div>
</div>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="9" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d" lang="en-US" class="invert" data-marpit-pagination="9" style="--paginate:true;--class:invert;--heading-divider:3;--theme:6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d;" data-marpit-pagination-total="14">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="10" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg" lang="en-US" class="invert" data-marpit-pagination="10" style="--paginate:true;--class:invert;--heading-divider:3;--theme:galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg;" data-marpit-pagination-total="15">
<div class="columns" markdown="1">
<div markdown="1">
<p><img src="imgs/git5.png" alt="" /></p>
@ -122,11 +154,11 @@
</div>
</div>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="10" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d" lang="en-US" class="invert" data-marpit-pagination="10" style="--paginate:true;--class:invert;--heading-divider:3;--theme:6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d;" data-marpit-pagination-total="14">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="11" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg" lang="en-US" class="invert" data-marpit-pagination="11" style="--paginate:true;--class:invert;--heading-divider:3;--theme:galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg;" data-marpit-pagination-total="15">
<div class="columns" markdown="1">
<div markdown="1">
<p><img src="imgs/git7.png" alt="" /></p>
<p>Set manually after setup with:</p>
<p>To set manually after setup, use:</p>
<pre is="marp-pre" data-auto-scaling="downscale-only"><code>git config --global credential.helper wincred
</code></pre>
</div>
@ -135,7 +167,7 @@
</div>
</div>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="11" data-marpit-fragments="6" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d" lang="en-US" class="invert" data-marpit-pagination="11" style="--paginate:true;--class:invert;--heading-divider:3;--theme:6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d;" data-marpit-pagination-total="14">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="12" data-marpit-fragments="6" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg" lang="en-US" class="invert" data-marpit-pagination="12" style="--paginate:true;--class:invert;--heading-divider:3;--theme:galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg;" data-marpit-pagination-total="15">
<h2 id="command-line">Command line</h2>
<ul>
<li data-marpit-fragment="1">Git is operated via the <em><strong>command line</strong></em>, a.k.a, the <em><strong>terminal</strong></em></li>
@ -145,11 +177,14 @@
<li data-marpit-fragment="4">Linux, (also included in the Windows Git install): <em><strong>bash</strong></em></li>
</ul>
</li>
<li data-marpit-fragment="5">We're using PowerShell, which can be accessed inside VS Code</li>
<li data-marpit-fragment="5">We're using PowerShell, which can be accessed inside <a href="https://code.visualstudio.com/docs/languages/powershell">VS Code</a> or <a href="https://learn.microsoft.com/en-us/visualstudio/ide/reference/command-prompt-powershell?view=vs-2022">Visual Studio</a>
<ul>
<li data-marpit-fragment="6">In VS Code, open/close terminal by pressing <em><strong>CTRL+Ö</strong></em> (in the Fin/Swe layout)</li>
</ul>
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="12" data-marpit-fragments="8" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d" lang="en-US" class="invert" data-marpit-pagination="12" style="--paginate:true;--class:invert;--heading-divider:3;--theme:6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d;" data-marpit-pagination-total="14">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="13" data-marpit-fragments="8" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg" lang="en-US" class="invert" data-marpit-pagination="13" style="--paginate:true;--class:invert;--heading-divider:3;--theme:galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg;" data-marpit-pagination-total="15">
<h3 id="basic-commands-and-the-working-directory">Basic commands and the working directory</h3>
<ul>
<li data-marpit-fragment="1">To do actions in Git, you don't press buttons, you write commands</li>
@ -171,13 +206,13 @@
<li data-marpit-fragment="8"><em><strong>Note</strong></em>: <code>..</code> is a shorthand for to the parent directory, <code>.</code> for the current directory</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="13" data-marpit-fragments="5" data-paginate="true" data-class="extra invert" data-heading-divider="3" data-theme="6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d" lang="en-US" class="extra invert" data-marpit-pagination="13" style="--paginate:true;--class:extra invert;--heading-divider:3;--theme:6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d;" data-marpit-pagination-total="14">
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="14" data-marpit-fragments="5" data-paginate="true" data-class="extra invert" data-heading-divider="3" data-theme="galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg" lang="en-US" class="extra invert" data-marpit-pagination="14" style="--paginate:true;--class:extra invert;--heading-divider:3;--theme:galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg;" data-marpit-pagination-total="15">
<h2 id="extra-help-this-is-horrible">Extra: Help, this is horrible!</h2>
<ul>
<li data-marpit-fragment="1">Do you feel more at home in graphical UIs?
<ul>
<li data-marpit-fragment="2">There are also graphical user interfaces for Git like <a href="https://www.gitkraken.com/">GitKraken</a>, <a href="https://www.sublimemerge.com/">Sublime Merge</a> or <a href="https://desktop.github.com/">GitHub Desktop</a> (GitHub only)</li>
<li data-marpit-fragment="2">There are also graphical user interfaces for Git like <a href="https://www.sublimemerge.com/">Sublime Merge</a>, <a href="https://www.gitkraken.com/">GitKraken</a>, or <a href="https://desktop.github.com/">GitHub Desktop</a> (for use with GitHub only)</li>
<li data-marpit-fragment="3">VS Code also has very useful graphical tools for Git (more about them later!)</li>
</ul>
</li>
@ -188,10 +223,10 @@
</li>
</ul>
</section>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="14" data-marpit-fragments="4" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d" lang="en-US" class="invert" data-marpit-pagination="14" style="--paginate:true;--class:invert;--heading-divider:3;--theme:6utc5o5vxpmafzrv1zs1wd648slmexwsfa03v7jo4d8d;" data-marpit-pagination-total="14">
<h2 id="btw-config">Btw: Config</h2>
</foreignObject></svg><svg data-marpit-svg="" viewBox="0 0 1280 720"><foreignObject width="1280" height="720"><section id="15" data-marpit-fragments="4" data-paginate="true" data-class="invert" data-heading-divider="3" data-theme="galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg" lang="en-US" class="invert" data-marpit-pagination="15" style="--paginate:true;--class:invert;--heading-divider:3;--theme:galct98d0vpgve8tgk1a5752eek9u59mh4p0acv49fg;" data-marpit-pagination-total="15">
<h2 id="note-config">Note: Config</h2>
<ul>
<li data-marpit-fragment="1">To configure your Git username for every project:
<li data-marpit-fragment="1">After installation, you may configure your Git username for every project:
<ul>
<li data-marpit-fragment="2">Use <code>git config --global user.name &quot;myUserName&quot;</code></li>
<li data-marpit-fragment="3">and <code>git config --global user.email &quot;my.email.address@domain.com&quot;</code></li>

@ -24,32 +24,65 @@ theme: buutti
## What is Git?
* Git is a version control tool originally created by Linus Torvalds in 2005
* Git is a ***version control*** tool originally created by Linus Torvalds in 2005
* Keeps track of code changes
* Can be used to backup code in the cloud
* Enables cooperation with other team members
* Ubiquitous in software development
### Why version control?
* Without version control, only one version of your code exists
* *What happens when you realize you made a mistake and need to roll back changes you've made?*
* You could use manual backups, or a cloud storage service
* *What happens if two people connect to a cloud service and edit the same file?*
* Or maybe not even the same file... *What happens when you and your teammate have made changes to code and you need to combine your work into a single, working version?*
* Version control handles all the problems above, and you can focus on the important part: programming!
* You can even try out some big changes that break your software completely
* If that doesn't work out, just roll back into the last working version!
### Git vs cloud storage
* Git is different from cloud storage services like Dropbox, Google Drive or OneDrive
* Instead of automatic syncing, you deliberately *push to* and *pull from* the cloud
* Cloud services are easier for starters
* Cloud services are easier for beginners
* ...but in projects of more than one person, tracking changes would be a pain
* Git has a steep learning curve
* To ease things, there are some visual tools like **Sourcetree** or **Sublime Merge**
* To use them effectively, you still need to understand how Git works, though
* Git is used via the ***terminal*** and has a steep learning curve
* There are some visual tools like **Sourcetree** or **Sublime Merge**
* To use them effectively, though, *you must still understand how Git works*
## GitHub and other developer platforms
## Remote storage services
<div class='columns' style='grid-template-columns: 5fr 1fr;' markdown='1'>
<div markdown='1'>
* Git *could* be used locally, but its usage is almost always combined with a developer platform — a remote storage service like [GitHub](https://github.com/), [GitLab](https://gitlab.com/) or [BitBucket](https://bitbucket.com/)
* These services can also double as a programming portfolio
* These services can also double as a programming portfolio that can help getting hired into the industry
* Commonly used in both open source and commercial projects
* In Buutti's trainings, GitLab is most commonly used
* In Buutti's trainings, ***GitLab*** is most commonly used
</div>
<div markdown='1'>
![w:150px](imgs/git-basics_1.png)
![w:150px](imgs/git-basics_2.png)
![w:150px](imgs/git-basics_0.png)
</div>
</div>
## Setup
* Install Git
![w:450px](imgs/git-basics_3.png)
* Installing Git:
* Windows/Mac: [git-scm.com](https://git-scm.com)
* Installation instructions are included in the following slides.
* If a setting is not mentioned in the instructions, you can leave it as the default option.
@ -67,7 +100,7 @@ theme: buutti
![](imgs/git3.png)
Set manually after setup with:
To set manually after setup, use:
```
git config --global core.editor "code --wait"
```
@ -82,7 +115,7 @@ git config --global core.editor "code --wait"
![](imgs/git2.png)
Set manually after setup with:
To set manually after setup, use:
```
git config --global init.defaultBranch main
```
@ -117,7 +150,7 @@ Set manually after setup with:
![](imgs/git7.png)
Set manually after setup with:
To set manually after setup, use:
```
git config --global credential.helper wincred
@ -137,8 +170,8 @@ git config --global credential.helper wincred
* There are many kinds of command line syntaxes out there. Some examples:
* Windows: ***PowerShell*** (new), ***cmd*** (old)
* Linux, (also included in the Windows Git install): ***bash***
* We're using PowerShell, which can be accessed inside VS Code
* In VS Code, open/close terminal by pressing ***CTRL+Ö*** (in the Fin/Swe layout)
* We're using PowerShell, which can be accessed inside [VS Code](https://code.visualstudio.com/docs/languages/powershell) or [Visual Studio](https://learn.microsoft.com/en-us/visualstudio/ide/reference/command-prompt-powershell?view=vs-2022)
* In VS Code, open/close terminal by pressing ***CTRL+Ö*** (in the Fin/Swe layout)
### Basic commands and the working directory
@ -158,14 +191,14 @@ git config --global credential.helper wincred
<!-- _class: "extra invert" -->
* Do you feel more at home in graphical UIs?
* There are also graphical user interfaces for Git like [GitKraken](https://www.gitkraken.com/), [Sublime Merge](https://www.sublimemerge.com/) or [GitHub Desktop](https://desktop.github.com/) (GitHub only)
* There are also graphical user interfaces for Git like [Sublime Merge](https://www.sublimemerge.com/), [GitKraken](https://www.gitkraken.com/), or [GitHub Desktop](https://desktop.github.com/) (for use with GitHub only)
* VS Code also has very useful graphical tools for Git (more about them later!)
* However, the GUIs make ***a lot*** more sense after you've understood the Git commands that those GUIs still execute under the hood
* There is no free lunch here
## Btw: Config
## Note: Config
* To configure your Git username for every project:
* After installation, you may configure your Git username for every project:
* Use `git config --global user.name "myUserName"`
* and `git config --global user.email "my.email.address@domain.com"`
* If you do not do this, Git will ask to do it anyway at some point

File diff suppressed because one or more lines are too long

@ -5,59 +5,113 @@ paginate: true
math: mathjax
theme: buutti
---
<!-- headingDivider: 3 -->
<!-- headingDivider: 4 -->
<!-- class: invert -->
# Project management 1. Git basics
## Basic Git workflow
* You have to tell everything you want to happen to Git ***explicitly*** by using ***Git commands***
* A common Git workflow consists of these four steps:
1) ***Edit:*** You make changes in some code file
2) ***Stage:*** You tell Git what files you've changed ([`git add`](#git-add))
3) ***Commit:*** You tell Git what changes you made in that file ([`git commit`](#git-commit))
4) ***Push:*** You upload those changes to a remote repository ([`git push`](#git-push))
## Repositories
* ***Repository*** is essentially a place to store code files in
* ***Repository*** ("repo") is essentially a place to store code files in
* Usually, we are dealing with ***two*** repositories: a ***local*** and a ***remote*** one
* A local repository is the one on your computer
* A remote repository is stored in a cloud service like GitHub
* [Here](https://github.com/borbware/unity-basics-course) is the remote repository for the materials of this course
* [Here](https://github.com/borbware/unity-basics-course) is an example of a remote repository on GitHub
* Changes are synced between these two repositories ***manually***
## `git init`
## Git commands
* You have to tell everything you want to happen to Git ***explicitly*** by using ***Git commands***
* Commands are of the form `git commandname`
* Some commands include ***handles*** that give extra modifiers to the commands:
* `git commandname --handle` or a shorthand `git commandname -h`
## Getting started with GitLab
* Go to [www.gitlab.com](http://www.gitlab.com) and create a new account, if you don't already have one
* If you have an existing GitHub account, you can use it to log into GitLab
* (You'll need to set a password to GitLab after logging in)
* After logging in, you can create a new ***project***
* This is what GitLab calls repositories
* In GitLab, projects are located in ***groups*** or ***namespaces***
* *You should have separate repositories for different programs*
* We will store future home assignments in a single repository
* Larger projects will have their own repositories
### Creating a repository
1) In GitLab, *New Project > Create blank project*
2) Give a name to the project, which automatically becomes its URL (see: Project slug)
3) Use your own user namespace (Good for personal projects)
4) You can set project visibility to Private (only you can see it) or Public (anyone can see it)
5) If you want, you can initialize the repository with a README.md file
* It's a **_Markdown_** file, essentially a text file containing information about the project.
* ***Note:*** These lectures are also written in Markdown, and you can use Markdown syntax to format text on Discord. It's neat!
---
* Initialization needs to be done for every new Git repository
<div class='centered'>
![w:950px](imgs/gitlab.png)
</div>
## Initializing a repository
* ***Initialization*** needs to be done for every new Git repository
* There are two ways to initialize a repo:
* a) Creating the local repository first:
* Use `git init` to make your current folder a new Git repository
* b) Creating the remote repository first **/** continuing an existing project:
* a) Creating the remote repository first **/** continuing an existing project:
* *Clone* a remote repository into your computer (See: [`git clone`](#git-clone))
* b) Creating the local repository first with [`git init`](#git-init)
* ***Note:*** Never initialize a Git repository in a cloud storage folder!
## `.git` folder
### `.git` folder
* Initialization adds a hidden `.git` folder inside a directory
* This is where Git stores all its repository data.
* ***Do not touch it!***
* The .git folder ONLY appears in the root directory of the repository
* ***Do not touch it!*** Let Git handle its contents on its own.
* The `.git` folder ONLY appears in the root directory of the repository
* If you see the `.git` folder in any of the subdirectories of the repository, something has gone wrong!
* You have initialized a repository inside repository
* You might have initialized a repository inside repository
* This should never happen!
## `git status`
## `git clone`
* Using the command `git status` shows your current situation.
* Remote repositories have an URL address that can be used to download the code to your machine
* The address can be found under the *Clone* button in the repository webpage
* Use the URL to download a remote repository:
* Run `git clone <URL>`
* Example: `git clone https://github.com/borbware/unity-basics-course.git`
* Remember: this initializes the repo, so `git init` not needed.
* Simplest way to create a new, empty repository:
* 1 - Initialize the repo in the Github/Gitlab/etc website
* 2 - Clone the repo.
## Exercise 1a. Cloning a repo
<!--_class: "exercise invert" -->
Create a new repository on GitLab and clone it with HTTPS to your machine.
## Basic Git workflow
* A common Git workflow consists of three steps:
* These are the steps you have to go through every time you want Git to know about the changes you've made!
* So, after writing some changes, you do this:
1) ***Stage:*** You tell Git what files you've changed ([`git add`](#git-add))
2) ***Commit:*** You tell Git what changes you made in that file ([`git commit`](#git-commit))
3) ***Push:*** You upload those changes to a remote repository ([`git push`](#git-push))
### Note: `git status`
* When inside a repository, using the command `git status` shows your current situation.
* If you're unsure what to do, it's never a bad idea to run `git status`
![bg right width: 80%](imgs/git-status.png)
## `git add`
### `git add`
* Uploading changes to GitHub from your local machine takes three steps (see [Basic Git workflow](1-git-basics#basic-git-workflow) from earlier)
* The first phase is ***staging*** with `git add`:
* The first step is ***staging*** with `git add`:
* The command `git add readme.md` stages the file `readme.md`
* After doing it, `git status` tells this:
```
@ -68,30 +122,34 @@ theme: buutti
---
* Basically, with `git add file` you tell Git that you want to do *something* with `file`.
* ***Note:*** If you just want to push all the changes you've made, you can use `git add .` to stage all the files in your current folder and its subfolders
* Be careful! Only do this after checking what changes have been made with `git status`
* ***Note 2:*** Use `git add <filename> -p` if you only want to stage **some** lines from a file you've worked on.
* ***Note 3:*** The counterpart to `git add` is `git rm`, which removes previously added files from Git's perspective
* With `git add file`, you tell Git that you have done something to `file`, and want to record those changes into Git history.
* This doesn't record those changes yet! This is just a preparation step.
* To undo `git add readme.md`, use `git restore --staged readme.md`
* ***Note 1:*** Use `git add <filename> -p` if you only want to stage ***some*** lines from a file you've worked on.
* ***Note 2:*** You can use `git add .` to stage ***all*** the files in your current folder and its subfolders at once
* This is a neat way to shoot yourself in the foot and stage something you didn't intend to!
## `git commit`
### `git commit`
* After you have staged all the files you want, the second step is to ***commit*** your changes
* In the commit, you will explain what changes you've made
* This message will be visible in GitHub
* `git commit -m "add new enemy"`
* In the commit, you will explain what changes you've made
* This message will be visible in the Git history
* `git commit -m "add new feature"`
* Commit message should clearly, concisely tell what kind of changes you have made
* Prefer present tense ("Do x" instead of "Did x")
* Every new commit creates a new point in the project timeline.
* You can always jump back between different points (See `git checkout`)
* Commit message should clearly, concisely tell what kind of changes you have made
* You can always jump between different points in timeline (See `git checkout`)
## `git push`
### `git push`
* The third step is ***pushing*** the changes to GitHub
* The previously-made commit action is **local**
* The third step is ***pushing*** the changes to a remote repository
* The previously-made commit action is ***local***
* No changes have gone to the remote repository yet!
* To upload changes to the remote repository, use `git push`
* Then you're done!
---
* Then you're done, and you can check your changes are visible in the remote repository
#### Setting upstream
* ***Note:*** When pushing for the first time, Git might nag you:
```
fatal: The current branch master has no upstream branch.
@ -101,73 +159,70 @@ theme: buutti
```
* You can just follow its orders (see the command on the third line!) and you're good to go
* Generally, when Git gives you a warning, error, or some other message, it's a good idea to ***read it and follow the orders***.
## Exercise 1b. Pushing changes
<!--_class: "exercise invert" -->
Continue the previous exercise.
1) In your local repository, create a new file `GitTest.md` with some lines of text in it.
2) Commit and push changes to GitLab.
3) Go to GitLab and see that the file is there!
## `git init`
* `git clone` always creates a new folder for a project
* If we have started working on a project without using Git, and have a project folder locally, it might be easier to use `git init` to initialize the project instead
* To do so, navigate to your project folder in the command line, and use `git init` to make your current folder a new Git repository
## `git remote`
* If you have initialized a Git repo already with `git init`, don't use `git clone`!
* Now, your local repo needs to be connected to a remote repository
* Create an ***empty*** remote repo with no Readme file, so your remote repository doesn't clash with your local one.
* If you have initialized a Git repo with `git init`, you can't use `git clone` to connect your local repo to a remote one
* Instead, run `git remote add origin <URL>`
* Here, the name `origin` refers to the remote repository
* `origin` is just the default name for a remote: other names can be used instead!
* `origin` is just the default name for a remote: other names can be used as well
* To check which remote repository the current local repository is linked to, use
* `git remote -v`
<!-- _footer: "A repository can have multiple remotes. Use `git remote` to list them all." -->
## Exercise 1a. Initializing a repo
## Exercise 2. Initializing a repo the local way
<!--_class: "exercise invert" -->
* Initialize a new repository locally.
* Create a new file `GitTest.md` with some lines of text in it.
* Commit changes.
* Create a new empty repository on GitHub.
* Use `git remote add origin <url>` to connect your local repo to the GitHub repo.
* Push changes to GitHub. Go to GitHub and see that `GitTest.md` is there!
1) Initialize a new repository locally with `git init`.
2) Create a new file `GitTest.md` with some lines of text in it.
3) Commit changes.
4) Create a new empty repository on GitHub.
5) Use `git remote add origin <url>` to connect your local repo to the GitHub repo.
6) Push changes to GitHub. Go to GitHub and see that `GitTest.md` is there!
## `git pull`
* `git pull` applies changes from the remote repository into the local repository
* Counterpart to `push`
* Very common when working in a team
* Counterpart to `push`, but does actually two commands in one
* It's the same thing as doing `git fetch <branch>`, and then `git merge <branch>`"
* Using `git pull` is very common when working in a team
* **Note**: During teamwork it's a good idea to ***always pull before pushing***
* If you only work alone on a single computer, seldom needed
<!-- _footer: "`git pull` is actually two commands in one. It's the same thing as doing `git fetch <branch>` + `git merge <branch>`" -->
## `git clone`
* Remote repositories have an URL address that can be used to download the code to your machine
* The address can be found under the *Clone* button in the repository webpage
* Use the URL to download a remote repository:
* Run `git clone <URL>`
* Example: `git clone https://github.com/borbware/unity-basics-course.git`
* Remember: this initializes the repo, so `git init` not needed.
* Simplest way to create a new, empty repository:
* 1 - Initialize the repo in the Github/Gitlab/etc website
* 2 - Clone the repo.
## Exercise 1b. Cloning a repo
<!--_class: "exercise invert" -->
* Create a new repository on GitHub and clone it with HTTPS to your machine.
* Then, create a new file `GitTest.md` with some lines of text in it.
* Commit and push changes to GitHub.
* Go to GitHub and see that the file is there!
## Extra: HTTPS vs SSH
<!-- _class: "extra invert" -->
* There are two ways to communicate with GitHub, ***HTTPS*** and ***SSH***
* HTTPS: `https://github.com/borbware/unity-basics-course.git`
* the easier way
* you log in with your GitHub credentials that get stored in the Git Credential Manager
* The easier way
* You log in with your GitLab credentials that get stored in the Git Credential Manager
* SSH: `git@github.com:borbware/unity-basics-course.git`
* [Connecting to GitLab with SSH](https://docs.gitlab.com/user/ssh/)
* [Connecting to GitHub with SSH](https://docs.github.com/en/authentication/connecting-to-github-with-ssh)
* You need to generate a computer-specific SSH key and add it to your GitHub settings
* You need to generate a computer-specific ***SSH key*** and add it to your GitHub settings
## `.gitignore`
* Sometimes your project has local files that should ***NOT*** be uploaded to GitHub
* Sometimes your project has local files that should ***NOT*** be uploaded to GitLab
* List those files in a `.gitignore` file in your Git project folder
* You can create it by yourself and define file names or folders which Git will then ignore in the commits, e.g.,
```
@ -175,7 +230,7 @@ theme: buutti
/folder
*.html
```
* ***Note:*** If you add a file to `.gitignore` that was committed earlier, Git doesn't "forget" it automatically.
* ***Note:*** If you add a file to `.gitignore` that was committed earlier, Git doesn't "forget" it automatically
* You can make Git forget it with `git rm --cached filename`
## VS code: Source control
@ -195,35 +250,39 @@ theme: buutti
![bg height:90%](imgs/vscode-working-tree.png)
## Exercise 2. Git collaboration
## Exercise 3. Git collaboration
<!--_class: "exercise invert" -->
* Work on this exercise with your group.
* Choose someone's test repository from Exercise 1b to use in this exercise.
* While others clone the repo to their machine, the owner should add other group members as collaborators of the repo in the repository's settings on GitHub.
* Then, everyone should make changes to the markdown file in the repository!
Work on this exercise with your group.
1) Choose someone's test repository from Exercise 1a to use in this exercise.
2) While others clone the repo to their machine, the owner should add other group members as ***collaborators*** of the repo in the repository's settings on GitLab.
* Left sidebar: *Manage > Members*
* Click *Invite members* and add others as *Developer* or *Maintainer*.
3) Then, everyone should make changes to the markdown file in the repository!
What happens if you make changes to the same line simultaneously?
<!-- _footer: In GitLab, the setting is under Manage > Members -->
## Note about longer `push` and `pull` commands
* After initialization, why don't `push` and `pull` commands work?
* Answer: because when you don't clone the repo, but add the remote into an empty repo with `git remote add origin`, the remote and local branches aren't connected yet.
* Thus, Git doesn't yet know which ***branch*** to pull from
* You can decide it manually on each pull with `git pull origin main`
* The branches can be connected in the first `push` with `git push --set-upstream origin main`
* Afterwards, we can just use `git push` and `git pull`.
## Troubleshooting: master vs. main
## Troubleshooting: `master` vs. `main`
```
error: failed to push some refs to [your-url]
```
* Possible reason: GitHub has a `main` branch, while your local repository has `master`
* Possible reason: GitLab has a `main` branch, while your local repository has `master`
* ***Fix:*** Run `git branch -m main` to rename your local `master` to `main`
## Note about longer `push` and `pull` commands
* After initialization, why do I have to use longer `push` and `pull` commands?
* Short answer: because we didn't clone the repo, but rather added the remote into an empty one with `git remote add origin`.
* `git pull origin main`: After adding a remote, we don't yet know which ***branch*** to pull from. `main` (or `master`!) is the default branch
* `git push --set-upstream origin main`: In the first `push`, we decide which branch to link our current branch into.
* Afterwards, we can just use `git push` and `git pull`.
## Reading
* [Using version control in VS code](https://code.visualstudio.com/docs/sourcecontrol/overview)
* [Using version control in VS code](https://code.visualstudio.com/docs/sourcecontrol/overview)
* [GitHub Git cheat sheet](https://education.github.com/git-cheat-sheet-education.pdf)

@ -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" -->

File diff suppressed because one or more lines are too long

@ -10,6 +10,15 @@ theme: buutti
# Project management 4. Scrum
## Contents
- [What is Scrum?](#what-is-scrum)
- [Scrum roles](#scrum-roles)
- [Project timeline](#project-timeline)
- [Events](#events)
- [Scrum Master tasks](#scrum-master-tasks)
## What is Scrum?
* [Scrum](https://en.wikipedia.org/wiki/Scrum_(software_development)) is a framework for delivering products (usually software)
@ -21,22 +30,23 @@ theme: buutti
* Sprints are most commonly two weeks long (for us, shorter)
* Progress is tracked and re-planned in ***Dailies***, 15-minute time-boxed meetings
## Why Scrum for game development?
### Why Scrum?
* Through its practices and principles, Scrum creates ***conditions*** to achieve good results
* Scrum gives ***agency*** to team members: meeting the goal is a team effort
* Scrum creates ***transparency***: problems get addressed early
* Scrum isn't magic: you need to continuously enforce its practices in action
* Scrum facilitates communication, but doesn't solve any problems for you!
* Scrum facilitates communication, but doesn't solve any problems for you — you have to actively enforce its usage!
---
<!--
---
* ***Cross-discipline teams***: Enables teams to deliver features and mechanics that have clear value
* ***Self-management***: Enables teams to select the amount of work they can commit to every sprint and complete that work through whatever means they find appropriate
* ***Self-organization***: Enables teams to have a degree of authority and responsibility to select their membership
* ***True leadership***: Provides leadership focused on mentoring and facilitation to free the best performance possible from the team -->
<!--
* ***True leadership***: Provides leadership focused on mentoring and facilitation to free the best performance possible from the team
## Cross-discipline teams
* Team members share the same goal and therefore the same priorities
* To make sure ***no work goes to waste***, synchronization of the disciplines happens every sprint.
@ -58,12 +68,13 @@ theme: buutti
* Some sprints, like before release, might require a complete reorganization
-->
# Scrum basics
## Scrum people
## Scrum roles
![](imgs/scrum-people.png)
Scrum Team consists of three roles: Product Owner, Scrum Master and the Dev team.
### Dev team
* Small team that aims to deliver a product
@ -71,48 +82,54 @@ theme: buutti
* Collaborates with Product owner
* Creates product increments in a series of sprints
### Scrum master
### Scrum Master
* Helps to facilitate usage of Scrum to the team
* Helps to facilitate usage of Scrum for the team
* Ensures the Scrum framework is followed
* Aims to improve team's workflow
* Basically an acting producer!
* Can be a part of the dev team (a "peer leader")
* ...but should not be the product owner
* ...but should not be the Product Owner
* Can be a different person every Sprint
* [Scrum.org](https://www.scrum.org/professional-scrum-certifications/professional-scrum-master-assessments) gives courses where you can get a Professional Scrum Master™ certification ($200)
### Product owner
### Product Owner
* Accountable for profit & loss
* Listens to the client's wishes
* Listens to the customer's wishes
* Manages the Product Backlog
* Representation of stakeholders and clients to the Dev Team
* Chooses what to release - and when
* Representation of stakeholders and customers to the Dev Team
* Chooses what to release and when
<!-- _footer: "In this course, the teacher will act as this." -->
### Other Scrum-adjacent roles
### The rest
* These aren't part of the Scrum team, but can be important personnel in the product lifecycle:
* Stakeholders
* People outside the Scrum team who have an interest in the product
* Sales, marketing, end customers, etc
* Customers
* Communicates their needs and wishes to the Product Owner
* Is often more interested in the end result than technicalities
* Stakeholders (not actually part of the team)
* People outside the Scrum team who have an interest in the product
* Sales, marketing, end customers, etc
* Client
* Monitors product backlog
* Is responsible for the upkeep of the product backlog
## Project timeline
<!-- _footer: "In this course, the teacher will act as these." -->
### Starting a new project
* When a new project is started, a ***Product backlog*** is created based on the customer's needs and the available time
* The project timeline is split into *Sprints*, around which the whole Scrum process revolves around
* Sprints are usually from one week to a few weeks long
* New Sprint menas new tasks to the Dev Team.
## Backlogs
### Product backlog
* Holds the requirements for the product
* Managed by the Product Owner
* Composed of ***tasks***
* unit of deliverable work
* well-defined completeness
* completable during a single Sprint
* Features, Bugfixes, Content...
* Unit of deliverable work
* Well-defined completeness
* Ideally completable during a single Sprint
* Features, Bugfixes, etc...
---
![](https://i.pinimg.com/originals/f8/6c/f4/f86cf4e5a8e7b0ab905ed53e8786aa28.png)
@ -121,59 +138,65 @@ theme: buutti
* A list of tasks to be completed during the Sprint
* Selected from the Product backlog
* A *forecast* of what is aimed to be done during the Sprint, not a promise!!!
* A *forecast* of what is aimed to be done during the Sprint, not a promise!!
* Often visualized as a [Kanban board](https://en.wikipedia.org/wiki/Kanban_board) in Trello, GitHub, GitLab, etc.
* In GitLab, Sprint backlogs can be created in the *Milestones* tab
---
![bg width: 80%](imgs/sprint-backlog.png)
### Definition of Done
### Definition of Done (DoD)
* When is a task considered done?
* This is decided by the Dev team in Sprint ***Retrospective*** ("Retro")
* Can change as project progresses
* This is decided by the Dev team in a Sprint Retrospective (more about it [soon](#sprint-retrospective-retro))
* DoD can change as project progresses
* "It works" -> "It passes tests"
<!-- * "Fully completed" should refer to ***completely releasable*** -->
## Sprint Events
## Events
### Sprint events
* First day: Sprint Planning
* Every day: Daily Scrum
* Last day: Sprint Review & Sprint Retrospective
* In Scrum, Sprints are paced by ***events***, also known as [Scrum "ceremonies"](https://www.atlassian.com/agile/scrum/ceremonies)
* First day: *Sprint Planning*
* Every day: *Daily Scrum*
* Last day: *Sprint Review* & *Sprint Retrospective*
### Sprint planning
### Sprint Planning
* Starts a new Sprint
* *Sprint Planning* starts a new Sprint
* The whole Scrum team attends
* inspects the whole Product Backlog
* The whole Product Backlog is inspected
* A Sprint Goal is created and dissected into a new Sprint Backlog
* The Sprint Goal is ***immutable***
* The exact implementations are not discussed
* those are rather left for the Dev Team to decide
* Those are rather left for the Dev Team to decide!
* New tasks are given to the Dev Team
### Daily Scrum ("Daily")
* Only Dev Team attends, with these goals:
* Only the Dev Team attends the *Daily*, with these goals in mind:
* Inspect the progression towards the Sprint Goal
* Inspect how the Sprint Backlog is clearing out
* Create a plan for the next 24 hours
* Max. 15 min long!
* Keeps everyone on the same page
* $\Rightarrow$ Optimizes collaboration and performance of the Dev Team
* Sometimes held as a [stand-up meeting](https://en.wikipedia.org/wiki/Stand-up_meeting): Nobody sits down to enforce the sense of urgency and minimize time-wasting chit-chat
---
* Example topics to address in a Daily:
* Example topics to address in a *Daily*:
* What have you achieved since the last Daily?
* What problems have you faced?
* How does the team address problems?
* Is there need for (re)allocation of tasks?
### Sprint review
### Sprint Review
* Attended by the Scrum team and stakeholders
* The *Sprint Review* is attended by the Scrum team and stakeholders
* Goal: Offer feedback and open up discussions about the Sprint
* Starts off with a feature demonstration
* Product Owner presents the state of the Product Backlog
@ -185,25 +208,28 @@ theme: buutti
### Sprint retrospective ("Retro")
* After every Sprint Review
* Only the Scrum team attends
* worries and thoughts are brought up
* A *Retro* is held after every Sprint Review
* Only the Scrum Team attends
* Worries and thoughts are brought up
* Possible discussion topics
* What went right?
* What should be improved?
* Tools needed and used?
* The suitability of the Scrum process.
* The suitability of the Scrum process?
* What does Done mean, and should it be redefined?
## Scrum master tasks
## Scrum Master tasks
### Continuous tasks
* Continuously:
1. Make sure the task board on GitHub is up to date.
2. Make sure everyone is able to attend the dailies.
3. Make sure everyone is heard and contributes at dailies.
4. If someone needs help, you help them find assistance or assist them yourself.
* Before the dev meeting:
1. Make sure the task board on GitHub is up to date.
### Before the dev meeting
1. Make sure the task board on GitLab is up to date.
2. Make sure someone is ready to present the newest working version of the program, with all the new changes pushed
3. Write down the state of tasks listed in the Sprint backlog
4. Discuss what problems were encountered during the last Sprint, and how were they addressed.

@ -2,12 +2,12 @@
| # | Lecture | Slides |
|:--|:----------------------------------------------------------|:-----------------------------------------------------|
| 0 | [Project management 0. Git setup](0-git-setup.md) | [Download slides](0-git-setup-slides.html?raw=1) |
| 1 | [Project management 1. Git basics](1-git-basics.md) | [Download slides](1-git-basics-slides.html?raw=1) |
| 2 | [Project management 2. Git continued](2-git-continued.md) | [Download slides](2-git-continued-slides.html?raw=1) |
| 0 | [Git setup](0-git-setup.md) | [Download slides](0-git-setup-slides.html?raw=1) |
| 1 | [Git basics](1-git-basics.md) | [Download slides](1-git-basics-slides.html?raw=1) |
| 2 | [Git continued](2-git-continued.md) | [Download slides](2-git-continued-slides.html?raw=1) |
| | [Git cheat sheet](git-cheat-sheet.md) | [Download slides](git-cheat-sheet-slides.html?raw=1) |
| 3 | [Project management 3. GitHub tools](3-github-tools.md) | [Download slides](3-github-tools-slides.html?raw=1) |
| 4 | [Project management 4. Scrum](4-scrum.md) | [Download slides](4-scrum-slides.html?raw=1) |
| 3 | [GitHub tools](3-github-tools.md) | [Download slides](3-github-tools-slides.html?raw=1) |
| 4 | [Scrum](4-scrum.md) | [Download slides](4-scrum-slides.html?raw=1) |
| | [VS Code setup](vscode-setup.md) | [Download slides](vscode-setup-slides.html?raw=1) |
| | [Using VS Code](using-vscode.md) | [Download slides](using-vscode-slides.html?raw=1) |
| | [Best practices for programming](best-practices.md) | [Download slides](best-practices-slides.html?raw=1) |

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Loading…
Cancel
Save