|
|
<!DOCTYPE html>
|
|
|
<html>
|
|
|
<head>
|
|
|
<meta charset="utf-8">
|
|
|
<meta name="generator" content="pandoc">
|
|
|
<meta name="author" content="Will King (presentation+git@youainti.com)">
|
|
|
<title>Introduction to Version Control Systems (GIT) for Economists</title>
|
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
|
|
|
<link rel="stylesheet" href="https://unpkg.com/reveal.js//dist/reset.css">
|
|
|
<link rel="stylesheet" href="https://unpkg.com/reveal.js//dist/reveal.css">
|
|
|
<style>
|
|
|
.reveal .sourceCode { /* see #7635 */
|
|
|
overflow: visible;
|
|
|
}
|
|
|
code{white-space: pre-wrap;}
|
|
|
span.smallcaps{font-variant: small-caps;}
|
|
|
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
|
|
div.column{flex: auto; overflow-x: auto;}
|
|
|
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
|
|
/* The extra [class] is a hack that increases specificity enough to
|
|
|
override a similar rule in reveal.js */
|
|
|
ul.task-list[class]{list-style: none;}
|
|
|
ul.task-list li input[type="checkbox"] {
|
|
|
font-size: inherit;
|
|
|
width: 0.8em;
|
|
|
margin: 0 0.8em 0.2em -1.6em;
|
|
|
vertical-align: middle;
|
|
|
}
|
|
|
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
|
|
/* CSS for syntax highlighting */
|
|
|
pre > code.sourceCode { white-space: pre; position: relative; }
|
|
|
pre > code.sourceCode > span { line-height: 1.25; }
|
|
|
pre > code.sourceCode > span:empty { height: 1.2em; }
|
|
|
.sourceCode { overflow: visible; }
|
|
|
code.sourceCode > span { color: inherit; text-decoration: inherit; }
|
|
|
div.sourceCode { margin: 1em 0; }
|
|
|
pre.sourceCode { margin: 0; }
|
|
|
@media screen {
|
|
|
div.sourceCode { overflow: auto; }
|
|
|
}
|
|
|
@media print {
|
|
|
pre > code.sourceCode { white-space: pre-wrap; }
|
|
|
pre > code.sourceCode > span { display: inline-block; text-indent: -5em; padding-left: 5em; }
|
|
|
}
|
|
|
pre.numberSource code
|
|
|
{ counter-reset: source-line 0; }
|
|
|
pre.numberSource code > span
|
|
|
{ position: relative; left: -4em; counter-increment: source-line; }
|
|
|
pre.numberSource code > span > a:first-child::before
|
|
|
{ content: counter(source-line);
|
|
|
position: relative; left: -1em; text-align: right; vertical-align: baseline;
|
|
|
border: none; display: inline-block;
|
|
|
-webkit-touch-callout: none; -webkit-user-select: none;
|
|
|
-khtml-user-select: none; -moz-user-select: none;
|
|
|
-ms-user-select: none; user-select: none;
|
|
|
padding: 0 4px; width: 4em;
|
|
|
color: #aaaaaa;
|
|
|
}
|
|
|
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
|
|
|
div.sourceCode
|
|
|
{ }
|
|
|
@media screen {
|
|
|
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
|
|
|
}
|
|
|
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
|
|
|
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
|
|
|
code span.at { color: #7d9029; } /* Attribute */
|
|
|
code span.bn { color: #40a070; } /* BaseN */
|
|
|
code span.bu { color: #008000; } /* BuiltIn */
|
|
|
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
|
|
|
code span.ch { color: #4070a0; } /* Char */
|
|
|
code span.cn { color: #880000; } /* Constant */
|
|
|
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
|
|
|
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
|
|
|
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
|
|
|
code span.dt { color: #902000; } /* DataType */
|
|
|
code span.dv { color: #40a070; } /* DecVal */
|
|
|
code span.er { color: #ff0000; font-weight: bold; } /* Error */
|
|
|
code span.ex { } /* Extension */
|
|
|
code span.fl { color: #40a070; } /* Float */
|
|
|
code span.fu { color: #06287e; } /* Function */
|
|
|
code span.im { color: #008000; font-weight: bold; } /* Import */
|
|
|
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
|
|
|
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
|
|
|
code span.op { color: #666666; } /* Operator */
|
|
|
code span.ot { color: #007020; } /* Other */
|
|
|
code span.pp { color: #bc7a00; } /* Preprocessor */
|
|
|
code span.sc { color: #4070a0; } /* SpecialChar */
|
|
|
code span.ss { color: #bb6688; } /* SpecialString */
|
|
|
code span.st { color: #4070a0; } /* String */
|
|
|
code span.va { color: #19177c; } /* Variable */
|
|
|
code span.vs { color: #4070a0; } /* VerbatimString */
|
|
|
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
|
|
|
</style>
|
|
|
<link rel="stylesheet" href="https://unpkg.com/reveal.js//dist/theme/league.css" id="theme">
|
|
|
<style>
|
|
|
.slides {
|
|
|
font-size: 0.75em;
|
|
|
}
|
|
|
.reveal ul {
|
|
|
display: block;
|
|
|
}
|
|
|
.reveal ol {
|
|
|
display: block;
|
|
|
}
|
|
|
|
|
|
img {
|
|
|
max-height: 350px !important;
|
|
|
}
|
|
|
|
|
|
figcaption {
|
|
|
font-size: 0.6em !important;
|
|
|
font-style: italic !important;
|
|
|
}
|
|
|
|
|
|
.subtitle {
|
|
|
font-style: italic !important;
|
|
|
}
|
|
|
|
|
|
.date {
|
|
|
font-size: 0.75em !important;
|
|
|
}
|
|
|
|
|
|
p {
|
|
|
text-align: left;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.license-footer {
|
|
|
opacity: 0.6;
|
|
|
transition: opacity 0.3s ease;
|
|
|
}
|
|
|
|
|
|
.license-footer:hover {
|
|
|
opacity: 1;
|
|
|
}
|
|
|
|
|
|
.license-icons {
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
|
|
|
.license-tooltip {
|
|
|
display: none;
|
|
|
position: absolute;
|
|
|
background-color: rgba(0, 0, 0, 0.8);
|
|
|
color: #fff;
|
|
|
padding: 5px 10px;
|
|
|
border-radius: 4px;
|
|
|
font-size: 12px;
|
|
|
white-space: nowrap;
|
|
|
top: 100%;
|
|
|
right: 0;
|
|
|
margin-top: 5px;
|
|
|
}
|
|
|
|
|
|
.license-footer:hover .license-tooltip {
|
|
|
display: block;
|
|
|
}
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
|
<div class="reveal">
|
|
|
<div class="slides">
|
|
|
|
|
|
<section id="title-slide">
|
|
|
<h1 class="title">Introduction to Version Control Systems (GIT) for
|
|
|
Economists</h1>
|
|
|
<p class="author">Will King (presentation+git@youainti.com)</p>
|
|
|
</section>
|
|
|
|
|
|
<div class="reveal">
|
|
|
<div class="slides">
|
|
|
<section>
|
|
|
<section id="what-is-git" class="title-slide slide level1">
|
|
|
<h1>What Is Git?</h1>
|
|
|
|
|
|
</section>
|
|
|
<section id="what-is-git-1" class="slide level2">
|
|
|
<h2>What is Git?</h2>
|
|
|
<figure>
|
|
|
<img data-src="https://imgs.xkcd.com/comics/git.png"
|
|
|
alt="What is Git? Explanation at ExplainXKCD" />
|
|
|
<figcaption aria-hidden="true">What is Git?
|
|
|
<a ref=https://explainxkcd.com/wiki/index.php/1597:_Git#Transcript>Explanation
|
|
|
at ExplainXKCD</a></figcaption>
|
|
|
</figure>
|
|
|
</section>
|
|
|
<section id="what-problems-are-we-trying-to-solve"
|
|
|
class="slide level2">
|
|
|
<h2>What problems are we trying to solve?</h2>
|
|
|
<ul>
|
|
|
<li>How can we keep track of our work?</li>
|
|
|
<li>How can we coordinate working with others?</li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="git-is" class="slide level2">
|
|
|
<h2>Git is…</h2>
|
|
|
<ul>
|
|
|
<li>a distributed version control system.</li>
|
|
|
<li>a method of communicating changes in (text) documents.</li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="git-is-not.." class="slide level2">
|
|
|
<h2>Git is not..</h2>
|
|
|
<ul>
|
|
|
<li>a programming environment</li>
|
|
|
<li>a panacea for having to write your dissertation</li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="our-goal" class="slide level2">
|
|
|
<h2>Our goal</h2>
|
|
|
<ul>
|
|
|
<li>Introduce how to work on the command line</li>
|
|
|
<li>Introduce the basic commands to get started</li>
|
|
|
<li>review how git works</li>
|
|
|
<li>dive into normal tasks that you will face</li>
|
|
|
</ul>
|
|
|
</section></section>
|
|
|
<section>
|
|
|
<section id="preliminaries" class="title-slide slide level1">
|
|
|
<h1>Preliminaries</h1>
|
|
|
|
|
|
</section>
|
|
|
<section id="have-you-installed-git-and-the-assoicated-tools"
|
|
|
class="slide level2">
|
|
|
<h2>Have you installed Git and the assoicated tools?</h2>
|
|
|
<table>
|
|
|
<colgroup>
|
|
|
<col style="width: 26%" />
|
|
|
<col style="width: 24%" />
|
|
|
<col style="width: 24%" />
|
|
|
<col style="width: 24%" />
|
|
|
</colgroup>
|
|
|
<thead>
|
|
|
<tr>
|
|
|
<th><strong>Operating System</strong></th>
|
|
|
<th>Windows</th>
|
|
|
<th>MacOS</th>
|
|
|
<th>Linux</th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody>
|
|
|
<tr>
|
|
|
<td>Git Source</td>
|
|
|
<td><a href="https://gitforwindows.org/">git for windows</a></td>
|
|
|
<td><a href="https://git-scm.com/download/mac">homebrew or
|
|
|
Xcode</a></td>
|
|
|
<td><code>sudo apt/yum/pkg/zypper install git</code></td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td>Text Editor</td>
|
|
|
<td>Nano (comes with git for windows)</td>
|
|
|
<td>Nano (already installed)</td>
|
|
|
<td>Nano/Vim/Emacs</td>
|
|
|
</tr>
|
|
|
</tbody>
|
|
|
</table>
|
|
|
</section>
|
|
|
<section id="quick-intro-to-the-command-line" class="slide level2">
|
|
|
<h2>Quick intro to the command line</h2>
|
|
|
<ul>
|
|
|
<li>Used to be <em>the</em> way to control a computer.</li>
|
|
|
<li>Very powerful.</li>
|
|
|
<li>Not just one command line, there are multiple different “shells”
|
|
|
<ul>
|
|
|
<li>Window: CommandPrompt, PowerShell, <strong>GitBash</strong></li>
|
|
|
<li>MacOS: <strong>Bash</strong></li>
|
|
|
<li>Linux: <strong>Bash</strong></li>
|
|
|
</ul></li>
|
|
|
</ul>
|
|
|
<p>Why are we using the command line?</p>
|
|
|
<ul>
|
|
|
<li>Git was built to be used on the command line.</li>
|
|
|
<li>All the instructions to fix problems are written with the CLI in
|
|
|
mind.</li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="basic-bash-syntax" class="slide level2">
|
|
|
<h2>Basic Bash syntax</h2>
|
|
|
<div class="sourceCode" id="cb1"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="bu">command</span> [arguments separated by spaces]</span></code></pre></div>
|
|
|
<p>Pay attention to spelling, spaces, and capitalization.</p>
|
|
|
<div class="sourceCode" id="cb2"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="bu">command</span> this has four arguments</span>
|
|
|
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="bu">command</span> <span class="st">"this has one argument"</span></span></code></pre></div>
|
|
|
</section>
|
|
|
<section id="navigating-the-command-line" class="slide level2">
|
|
|
<h2>Navigating the command line</h2>
|
|
|
<ul>
|
|
|
<li><code>pwd</code>: Print Working Directory.</li>
|
|
|
<li><code>ls</code>: LiSt.</li>
|
|
|
<li><code>cd</code>: Change Directory.</li>
|
|
|
<li><code>nano</code>: The text editor we will be using.</li>
|
|
|
</ul>
|
|
|
<aside class="notes">
|
|
|
<p>Get everyone to open bash at their home location. pwd, then talk
|
|
|
about slashes etc. Talk about spaces and quoting and escaping. Show
|
|
|
a variety of paths.</p>
|
|
|
</aside>
|
|
|
</section>
|
|
|
<section id="bash-activity" class="slide level2">
|
|
|
<h2>Bash Activity</h2>
|
|
|
<p>Prep: <a href="https://www.youainti.com">Download</a> and extract
|
|
|
the zip file I’ve provided.</p>
|
|
|
<ol type="1">
|
|
|
<li>Open bash/gitbash in the extracted directory.</li>
|
|
|
<li>Figure out what directory you are in.</li>
|
|
|
<li>Start exploring the directories using the command line.</li>
|
|
|
</ol>
|
|
|
<p>How is this similar to using your file browser?</p>
|
|
|
<p>Try typing <code>nano [filename]</code> to open one of the text
|
|
|
files</p>
|
|
|
<aside class="notes">
|
|
|
<p>There are a couple of files with useful information.</p>
|
|
|
<p>Please go through them with the students as you explore the
|
|
|
filetree.</p>
|
|
|
<p>It might be helpful to go through the directory outside of the
|
|
|
command line too.</p>
|
|
|
</aside>
|
|
|
</section>
|
|
|
<section id="getting-help-on-the-command-line" class="slide level2">
|
|
|
<h2>Getting help on the command line</h2>
|
|
|
<p>When you run into issues on the command line, you need to know
|
|
|
how to get help:</p>
|
|
|
<ul>
|
|
|
<li>internet searches (google, stackoverflow, etc)</li>
|
|
|
<li>local resources
|
|
|
<ul>
|
|
|
<li>command help pages</li>
|
|
|
<li>man pages</li>
|
|
|
<li>info pages</li>
|
|
|
</ul></li>
|
|
|
</ul>
|
|
|
<div class="sourceCode" id="cb3"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="fu">ls</span> <span class="at">--help</span></span>
|
|
|
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="fu">man</span> ls</span>
|
|
|
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="ex">info</span> ls</span></code></pre></div>
|
|
|
<aside class="notes">
|
|
|
<p>Examine some of the CLI options for the command presented
|
|
|
earlier. Maybe:</p>
|
|
|
<ul>
|
|
|
<li><code>ls -l</code></li>
|
|
|
<li><code>ls -a</code></li>
|
|
|
</ul>
|
|
|
</aside>
|
|
|
</section></section>
|
|
|
<section>
|
|
|
<section id="git-basics---recording-file-changes"
|
|
|
class="title-slide slide level1">
|
|
|
<h1>Git Basics - Recording file changes</h1>
|
|
|
|
|
|
</section>
|
|
|
<section id="concepts" class="slide level2">
|
|
|
<h2>Concepts</h2>
|
|
|
<ul>
|
|
|
<li>Repositories: A directory where you will be tracking
|
|
|
changes.</li>
|
|
|
<li>Snapshots: A copy of the state of the repository at a given
|
|
|
time.</li>
|
|
|
<li>Working Copy: Changes that haven’t been recorded in a snapshot
|
|
|
yet.</li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="initializing-repositories" class="slide level2">
|
|
|
<h2>Initializing Repositories</h2>
|
|
|
<p>Let’s start a new repository.</p>
|
|
|
<ol type="1">
|
|
|
<li>navigate to the extracted directory I gave you.</li>
|
|
|
<li>create a new folder with a random name (don’t use spaces!)</li>
|
|
|
<li>open the command line in this new folder</li>
|
|
|
<li><code>git init .</code></li>
|
|
|
</ol>
|
|
|
<p>The <code>git init</code> command turned the current directory
|
|
|
(<code>.</code>) into a git repository.</p>
|
|
|
<p>If you were to type <code>git init repo_name</code> it would
|
|
|
create a new directory named <code>repo_name/</code> and then turn
|
|
|
it into a git repo.</p>
|
|
|
</section>
|
|
|
<section id="configurations" class="slide level2">
|
|
|
<h2>Configurations</h2>
|
|
|
<p>Now let’s set some defaults that will make your life easier:</p>
|
|
|
<div class="sourceCode" id="cb4"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> config <span class="at">--global</span> core.editor <span class="st">"nano"</span></span>
|
|
|
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> config <span class="at">--global</span> user.email <span class="st">"your_email@example.com"</span></span>
|
|
|
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> config <span class="at">--global</span> user.name <span class="st">"Your Name"</span></span></code></pre></div>
|
|
|
</section>
|
|
|
<section id="writing-files-no-git-involved" class="slide level2">
|
|
|
<h2>Writing Files (No git involved)</h2>
|
|
|
<p>Ok, time to make some changes</p>
|
|
|
<div class="sourceCode" id="cb5"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="fu">nano</span> README.txt</span>
|
|
|
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="fu">nano</span> test.txt</span></code></pre></div>
|
|
|
<p>Now let’s see what git has to say:</p>
|
|
|
<div class="sourceCode" id="cb6"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> status</span></code></pre></div>
|
|
|
</section>
|
|
|
<section id="marking-files-for-inclusion-staging-changes"
|
|
|
class="slide level2">
|
|
|
<h2>Marking Files for Inclusion (Staging changes)</h2>
|
|
|
<p>Now let’s stage these files (mark that we want to track these
|
|
|
files)</p>
|
|
|
<div class="sourceCode" id="cb7"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> add README.txt test.txt</span></code></pre></div>
|
|
|
<p>Now let’s see what git has to say:</p>
|
|
|
<div class="sourceCode" id="cb8"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> status</span></code></pre></div>
|
|
|
</section>
|
|
|
<section id="snapshotting-changes-commits" class="slide level2">
|
|
|
<h2>Snapshotting changes (Commits)</h2>
|
|
|
<p>Now let’s take a snapshot. In git this is called a commit.</p>
|
|
|
<div class="sourceCode" id="cb9"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> commit</span></code></pre></div>
|
|
|
</section>
|
|
|
<section id="commit-messages" class="slide level2">
|
|
|
<h2>Commit Messages</h2>
|
|
|
<ul>
|
|
|
<li>When writing a commit, you have the responsibility of explaining
|
|
|
what happened.</li>
|
|
|
<li>This helps teammates - including future you - know what you were
|
|
|
doing and why.</li>
|
|
|
<li>Let’s write a meaningful commit.</li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="lets-practice" class="slide level2">
|
|
|
<h2>Let’s Practice</h2>
|
|
|
<p>Let’s make personal wiki’s to keep track of what we are
|
|
|
doing.</p>
|
|
|
<ol type="1">
|
|
|
<li>navigate to the <code>git_intro_download/</code> directory.</li>
|
|
|
<li>initialize a git repo using <code>git init wiki</code></li>
|
|
|
<li>change directory to wiki</li>
|
|
|
<li><code>nano basic_git_workflow.txt</code></li>
|
|
|
<li>write something</li>
|
|
|
<li>stage it</li>
|
|
|
<li>write a commit message and commit it.</li>
|
|
|
<li>add some more files and edits and repeat steps 5-7 a few
|
|
|
times.</li>
|
|
|
</ol>
|
|
|
</section>
|
|
|
<section id="git-log---noticing-what-happens" class="slide level2">
|
|
|
<h2>Git Log - noticing what happens</h2>
|
|
|
<p>Lets take a look at what you just did.</p>
|
|
|
<div class="sourceCode" id="cb10"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> log</span>
|
|
|
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> log <span class="at">--oneline</span></span></code></pre></div>
|
|
|
</section>
|
|
|
<section id="ready-to-move-on" class="slide level2">
|
|
|
<h2>Ready to move on?</h2>
|
|
|
<ul>
|
|
|
<li>Is everyone comfortable and ready to move on?</li>
|
|
|
<li>Have you committed everything you have?</li>
|
|
|
<li>What questions do you have?</li>
|
|
|
</ul>
|
|
|
</section></section>
|
|
|
<section>
|
|
|
<section id="git-concepts" class="title-slide slide level1">
|
|
|
<h1>Git Concepts</h1>
|
|
|
|
|
|
</section>
|
|
|
<section id="how-git-works" class="slide level2">
|
|
|
<h2>How Git Works</h2>
|
|
|
<p>Please take notes in your wiki; saving, staging, and committing
|
|
|
as you go. Put each topic into it’s own file; we will use them
|
|
|
later.</p>
|
|
|
<p>If you run into issues, please let me know and I’ll pause to
|
|
|
help.</p>
|
|
|
<p>I owe this approach to explaining git to <a
|
|
|
href="https://tom.preston-werner.com/2009/05/19/the-git-parable">Tom
|
|
|
Preston-Werner’s Git Parable</a></p>
|
|
|
</section>
|
|
|
<section id="snapshots" class="slide level2">
|
|
|
<h2>Snapshots</h2>
|
|
|
<p>When working with a project, you might want to know the history
|
|
|
of that project. A simple way to do this is to make copies or
|
|
|
snapshots at regular or important points.</p>
|
|
|
<blockquote>
|
|
|
<p>Imagine I am writing a novel. I start by writing “It was a dark
|
|
|
and stormy knight.” In order to avoid loosing my work, I save my
|
|
|
working version, and then make a copy to google drive called
|
|
|
<code>novel-(date1).docx</code>. Later I decide to fix my error and
|
|
|
change it to “It was a dark and stormy night.” I then save my
|
|
|
working version and make a second copy
|
|
|
<code>novel-(date2).docx</code>.</p>
|
|
|
</blockquote>
|
|
|
</section>
|
|
|
<section id="storing-objects" class="slide level2">
|
|
|
<h2>Storing Objects</h2>
|
|
|
<p>This is the basic way git works. Each time a file is committed, a
|
|
|
copy is saved to a hidden directory in the <code>.git</code> folder.
|
|
|
Staging the file marks that you want to save the current version of
|
|
|
the file.</p>
|
|
|
<details>
|
|
|
<summary>Explore</summary>
|
|
|
In your wiki, stage a change for a file.
|
|
|
Look at 'git status' to see what has been staged.
|
|
|
Now change the same file, and check 'git status' again.
|
|
|
The old version is staged, but the new one is not.
|
|
|
</details>
|
|
|
</section>
|
|
|
<section id="how-does-git-name-each-file-version"
|
|
|
class="slide level2">
|
|
|
<h2>How does git name each file version?</h2>
|
|
|
<p>There is a computer science tool called a <a
|
|
|
href="https://en.wikipedia.org/wiki/Hash_function">hash
|
|
|
function</a>. It allows us to give each version of a file a (nearly)
|
|
|
unique name that depends on the file’s contents.</p>
|
|
|
<ol type="1">
|
|
|
<li>Navigate to the <code>bash_exploration/</code> directory.</li>
|
|
|
<li>run <code>sha1sum c.txt</code></li>
|
|
|
<li>Does it match
|
|
|
<code>cf44e4a24958c62790979deaad545d23c8fbe98e</code>?</li>
|
|
|
<li>Edit <code>c.txt</code> by removing the ‘(txt)’ part of the
|
|
|
first line.</li>
|
|
|
<li>What is the new sha1sum?</li>
|
|
|
</ol>
|
|
|
<p>This is called a Content Addressible System, because we can
|
|
|
address each unique version of our content.</p>
|
|
|
</section>
|
|
|
<section id="incremental-snapshots" class="slide level2">
|
|
|
<h2>Incremental Snapshots</h2>
|
|
|
<p>Imagine if I had 100 different files, and I was taking full
|
|
|
snapshots each time I changed one or two of them. I would end up
|
|
|
with a lot of copies of the same content.</p>
|
|
|
<p>If I wanted to save on storage space, I could instead copy just
|
|
|
the versions that I changed.</p>
|
|
|
<p>This is what Git does. Each snapshot contains just a list of the
|
|
|
staged files, i.e. the files that we have said have changed in an
|
|
|
important way.</p>
|
|
|
<p>This is done by saving the staged objects with SHA1SUM names, and
|
|
|
then writing a small file that contains the filenames and SHA1SUM
|
|
|
names of the change. This is what committing a change does.</p>
|
|
|
</section>
|
|
|
<section id="constructing-a-dag---commit-parents"
|
|
|
class="slide level2">
|
|
|
<h2>Constructing a DAG - Commit Parents</h2>
|
|
|
<p>Now notice one problem with Incremental Snapshots. If I miss a
|
|
|
snapshot somewhere, I am left without those changes. So, I need a
|
|
|
way to know which previous snapshots are required to get to a
|
|
|
specific state.</p>
|
|
|
<p>The solution is to allow commits to include information on
|
|
|
<strong>‘parent’</strong> commits. Now we can draw a graph of how we
|
|
|
get to a specific state.</p>
|
|
|
<figure>
|
|
|
<img data-src="./SimpleCommitDAG.drawio.svg"
|
|
|
alt="Simple Commit DAG" />
|
|
|
<figcaption aria-hidden="true">Simple Commit DAG</figcaption>
|
|
|
</figure>
|
|
|
</section>
|
|
|
<section id="confusing-dags" class="slide level2">
|
|
|
<h2>Confusing DAGS</h2>
|
|
|
<p>Imagine the following commit DAG</p>
|
|
|
<figure>
|
|
|
<img data-src="./ComplicatedCommitDAG.drawio.svg"
|
|
|
alt="Complicated Commit DAG" />
|
|
|
<figcaption aria-hidden="true">Complicated Commit DAG</figcaption>
|
|
|
</figure>
|
|
|
<p>How can we know what state we should have?</p>
|
|
|
</section>
|
|
|
<section id="pointers-branches-tags-head" class="slide level2">
|
|
|
<h2>Pointers (branches, tags, HEAD)</h2>
|
|
|
<p>In CS, a pointer is something that records an address to
|
|
|
something else.</p>
|
|
|
<figure>
|
|
|
<img data-src="./ComplicatedCommitDAG_WithPointers.drawio.svg"
|
|
|
alt="Complicated Commit DAG with Pointers" />
|
|
|
<figcaption aria-hidden="true">Complicated Commit DAG with
|
|
|
Pointers</figcaption>
|
|
|
</figure>
|
|
|
<p>Three common types of pointers: Branches, Tags, and HEAD</p>
|
|
|
</section>
|
|
|
<section id="branches" class="slide level2">
|
|
|
<h2>Branches</h2>
|
|
|
<p>A branch is a flexible marker that simplifies isolating work from
|
|
|
different parts of the codebase. It is used to track areas of work.
|
|
|
For example, if I:</p>
|
|
|
<ul>
|
|
|
<li>Wanted to experiment with something without messing with the
|
|
|
main code.</li>
|
|
|
<li>Was trying to fix a bug and needed to add a bunch of
|
|
|
debugging.</li>
|
|
|
<li>Wanted to try implementing a specific advisor’s suggestions
|
|
|
before going all in on it.</li>
|
|
|
<li>Try to incorporate all the work of a collaborator who’s work I’m
|
|
|
going to need to fix.</li>
|
|
|
</ul>
|
|
|
<p>When you create a commit, a branch will change to point to the
|
|
|
new commit.</p>
|
|
|
<blockquote>
|
|
|
<p>Branches are cheap, use them.</p>
|
|
|
</blockquote>
|
|
|
</section>
|
|
|
<section id="tags" class="slide level2">
|
|
|
<h2>Tags</h2>
|
|
|
<p>A tag points to a specific commit. They are useful for:</p>
|
|
|
<ul>
|
|
|
<li>Marking releases or versions of software.</li>
|
|
|
<li>Identifying a commit where an error was added.</li>
|
|
|
<li>In Economics: Marking the version of an analysis you presented
|
|
|
in your dissertation.</li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="head" class="slide level2">
|
|
|
<h2>HEAD</h2>
|
|
|
<p>Points to the commit that your current working copy is based
|
|
|
on.</p>
|
|
|
<p>You may see a <strong>detached HEAD</strong> error. No the
|
|
|
revolution hasn’t started yet, you just got your HEAD pointing to a
|
|
|
specific commit instead of a branch pointer.</p>
|
|
|
</section>
|
|
|
<section id="return-of-the-dag" class="slide level2">
|
|
|
<h2>Return of the DAG</h2>
|
|
|
<figure>
|
|
|
<img data-src="./ComplicatedCommitDAG_WithPointers.drawio.svg"
|
|
|
alt="Complicated Commit DAG with Pointers" />
|
|
|
<figcaption aria-hidden="true">Complicated Commit DAG with
|
|
|
Pointers</figcaption>
|
|
|
</figure>
|
|
|
<ul>
|
|
|
<li>How can we know what state we should have?</li>
|
|
|
<li>What is HEAD pointing to? What should it be pointing to?</li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="conflicts" class="slide level2">
|
|
|
<h2>Conflicts</h2>
|
|
|
<figure>
|
|
|
<img data-src="./ComplicatedCommitDAG.drawio.svg"
|
|
|
alt="Complicated Commit DAG" />
|
|
|
<figcaption aria-hidden="true">Complicated Commit DAG</figcaption>
|
|
|
</figure>
|
|
|
<p>Take a look at <code>commit 10</code>. Notice how it has to
|
|
|
handle the cases where</p>
|
|
|
<ul>
|
|
|
<li><code>Commit 5</code> has removed <code>b.txt</code> but
|
|
|
<code>commit 9</code> hasn’t</li>
|
|
|
<li><code>Commit 5</code> and <code>Commit 4</code> have conflicting
|
|
|
edits of <code>e.txt</code></li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section class="slide level2">
|
|
|
|
|
|
<blockquote>
|
|
|
<p>Notice how it has to handle the cases where</p>
|
|
|
<ul>
|
|
|
<li><code>Commit 5</code> has removed <code>b.txt</code> but
|
|
|
<code>commit 9</code> hasn’t</li>
|
|
|
<li><code>Commit 5</code> and <code>Commit 4</code> have conflicting
|
|
|
edits of <code>e.txt</code></li>
|
|
|
</ul>
|
|
|
</blockquote>
|
|
|
<p>This is called a conflict, where the same file has had different
|
|
|
changes happen in different branches.</p>
|
|
|
<p>To handle this, Git asks you to resolve it, choosing what should
|
|
|
be kept or removed. Resolving a conflict is part of merging
|
|
|
branches.</p>
|
|
|
<p>Merging is the main skill we want to develop.</p>
|
|
|
</section>
|
|
|
<section id="rewriting-history---the-dag-can-be-modified-kind-of"
|
|
|
class="slide level2">
|
|
|
<h2>Rewriting History - the DAG can be modified (kind of)</h2>
|
|
|
<p>Because the DAG is just a bunch of records pointing to other
|
|
|
records, you can rewrite it, <strong><em>BUT</em></strong> if you
|
|
|
rewrite a copy of the DAG and your coworkers don’t, then you’re in
|
|
|
for a world of hurt.</p>
|
|
|
<p>This is what advanced GIT consists of: rewriting the commit DAG
|
|
|
so that it clearly, cleanly, and consisely represents how the
|
|
|
codebase grew.</p>
|
|
|
<p>We will only take the briefest of looks at one way to do
|
|
|
that.</p>
|
|
|
</section></section>
|
|
|
<section>
|
|
|
<section id="how-to-work-with-git" class="title-slide slide level1">
|
|
|
<h1>How to work with Git</h1>
|
|
|
|
|
|
</section>
|
|
|
<section id="review-of-basic-git-workflow." class="slide level2">
|
|
|
<h2>Review of basic git workflow.</h2>
|
|
|
<p>Remember!</p>
|
|
|
<ol type="1">
|
|
|
<li>init repo</li>
|
|
|
<li>add and edit files</li>
|
|
|
<li>stage files</li>
|
|
|
<li>commit files</li>
|
|
|
<li>repeate 2-4 as many times as needed.</li>
|
|
|
</ol>
|
|
|
</section>
|
|
|
<section id="git-log" class="slide level2">
|
|
|
<h2>Git Log</h2>
|
|
|
<p>You can inspect what has been going on using:</p>
|
|
|
<div class="sourceCode" id="cb11"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> log</span>
|
|
|
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> log <span class="at">--graph</span></span>
|
|
|
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> log <span class="at">--oneline</span></span>
|
|
|
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> log <span class="at">--oneline</span> <span class="at">--graph</span></span>
|
|
|
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a><span class="ex">...</span></span></code></pre></div>
|
|
|
</section>
|
|
|
<section id="git-help" class="slide level2">
|
|
|
<h2>Git Help</h2>
|
|
|
<p>If you ever forget what options are available for git:</p>
|
|
|
<div class="sourceCode" id="cb12"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> <span class="at">--help</span></span>
|
|
|
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> <span class="pp">[</span><span class="ss">option</span><span class="pp">]</span> <span class="at">--help</span></span></code></pre></div>
|
|
|
<p>For example</p>
|
|
|
<div class="sourceCode" id="cb13"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> log <span class="at">--help</span></span></code></pre></div>
|
|
|
</section>
|
|
|
<section id="lets-start-branching" class="slide level2">
|
|
|
<h2>Let’s Start Branching</h2>
|
|
|
<p>To create a new branch, either of the following work:</p>
|
|
|
<div class="sourceCode" id="cb14"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> checkout <span class="at">-b</span> <span class="pp">[</span><span class="ss">new_branch_name</span><span class="pp">]</span></span>
|
|
|
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> switch <span class="at">-c</span> <span class="pp">[</span><span class="ss">new_branch_name</span><span class="pp">]</span></span></code></pre></div>
|
|
|
<p>In our wiki repo, let’s create a branch named
|
|
|
<em>spellcheck</em></p>
|
|
|
<pre class="git"><code>git checkout -b spellcheck</code></pre>
|
|
|
<p>Now check which branch we are on</p>
|
|
|
<div class="sourceCode" id="cb16"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> branch</span>
|
|
|
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> status</span></code></pre></div>
|
|
|
</section>
|
|
|
<section id="swapping-between-branches" class="slide level2">
|
|
|
<h2>Swapping between branches</h2>
|
|
|
<p>There are two ways to change between branches</p>
|
|
|
<div class="sourceCode" id="cb17"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> checkout <span class="pp">[</span><span class="ss">branch</span><span class="pp">]</span></span>
|
|
|
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> switch <span class="pp">[</span><span class="ss">branch</span><span class="pp">]</span></span></code></pre></div>
|
|
|
<ul>
|
|
|
<li><code>git switch</code>: only used to change branches</li>
|
|
|
<li><code>git checkout</code>: does so much more</li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="merging-branches-ff-merges" class="slide level2">
|
|
|
<h2>Merging Branches (FF Merges)</h2>
|
|
|
<p>Ok, let’s do the following:</p>
|
|
|
<ul>
|
|
|
<li>add a file in our spellcheck branch</li>
|
|
|
<li>switch to the main branch</li>
|
|
|
<li>merge spellcheck into main</li>
|
|
|
</ul>
|
|
|
<div class="sourceCode" id="cb18"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> switch spellcheck</span>
|
|
|
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="bu">echo</span> <span class="st">"hello world"</span> <span class="op">></span> n.txt</span>
|
|
|
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> add n.txt</span>
|
|
|
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> commit <span class="at">-m</span> <span class="st">"said hello to terra"</span></span>
|
|
|
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> switch main</span>
|
|
|
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a><span class="fu">ls</span> <span class="co">#note how n is missing</span></span>
|
|
|
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> log <span class="at">--oneline</span></span>
|
|
|
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> merge spellcheck</span>
|
|
|
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> log <span class="at">--oneline</span></span></code></pre></div>
|
|
|
<p>This is called a fast-forward merge and occurrs when branches
|
|
|
don’t have conflicts.</p>
|
|
|
</section>
|
|
|
<section id="creating-conflicts" class="slide level2">
|
|
|
<h2>Creating Conflicts</h2>
|
|
|
<blockquote>
|
|
|
<p>Conflicts are not bad, they are inconvenient and necessary.</p>
|
|
|
</blockquote>
|
|
|
<p>A conflict occurs when two commits have different versions of the
|
|
|
same file(s).</p>
|
|
|
<p>Let’s create a conflict in our wiki repo.</p>
|
|
|
<div class="sourceCode" id="cb19"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> checkout spellcheck</span>
|
|
|
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="fu">nano</span> favorites.txt <span class="co">#Talk about your favorite color</span></span>
|
|
|
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> add favorites.txt</span>
|
|
|
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> commit <span class="at">-m</span> <span class="st">"write an actual description"</span></span>
|
|
|
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> switch main</span>
|
|
|
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a><span class="fu">nano</span> favorites.txt <span class="co">#Talk about your favorite food"</span></span>
|
|
|
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> add favorites.txt</span>
|
|
|
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> commit <span class="at">-m</span> <span class="st">"write an actual description"</span></span>
|
|
|
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> log <span class="at">--oneline</span></span>
|
|
|
<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> merge spellcheck</span></code></pre></div>
|
|
|
</section>
|
|
|
<section id="three-way-merges" class="slide level2">
|
|
|
<h2>Three Way Merges</h2>
|
|
|
<p>In this case we have a warning message:
|
|
|
<code>CONFLICT (add/add): Merge conflict in favorites.txt</code></p>
|
|
|
<div class="sourceCode" id="cb20"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> status</span>
|
|
|
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a><span class="fu">nano</span> favorites.txt</span></code></pre></div>
|
|
|
<p>Note the symbols “<<<<<” “======”
|
|
|
“>>>>>”. These tell us what the differences are
|
|
|
between the commits</p>
|
|
|
<p>To resolve the commit:</p>
|
|
|
<ul>
|
|
|
<li>we edit the files in conflict to get what we want from
|
|
|
them.</li>
|
|
|
<li>stage the changes.</li>
|
|
|
<li>commit the merged files.</li>
|
|
|
</ul>
|
|
|
<div class="sourceCode" id="cb21"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> log <span class="at">--graph</span> <span class="at">--oneline</span></span></code></pre></div>
|
|
|
</section>
|
|
|
<section id="practice-5-min" class="slide level2">
|
|
|
<h2>Practice (5 min)</h2>
|
|
|
<ul>
|
|
|
<li>checkout main and start writing some more about your favorite
|
|
|
food.</li>
|
|
|
<li>checkout spellcheck and start writing more about your favorite
|
|
|
color. Notice that spellcheck didn’t get the changes from main.</li>
|
|
|
<li>merge spellcheck into main (checkout main then
|
|
|
<code>git merge spellcheck</code>)</li>
|
|
|
<li>Resolve the merge.</li>
|
|
|
<li>merge main into spellcheck at some point.</li>
|
|
|
</ul>
|
|
|
<p>Why would normal practice be to merge your release branch into
|
|
|
your development branch, then merge back?</p>
|
|
|
</section>
|
|
|
<section id="introducing-a-normal-workflow" class="slide level2">
|
|
|
<h2>Introducing a normal workflow</h2>
|
|
|
<p>Usually, you have branches that represent releases and branches
|
|
|
that represent areas you are working on.</p>
|
|
|
<p>Consider the following branches.</p>
|
|
|
<ul>
|
|
|
<li><code>main</code>: This is the branch that you are using to
|
|
|
present work that you consider somewhat complete, i.e. when you have
|
|
|
a first draft of your data processing code, or the output data.</li>
|
|
|
<li><code>data_processing</code>: This is where you write your data
|
|
|
processing code, e.g. a web scraper and data munging tools. It might
|
|
|
include a copy of a <code>.csv</code> file or <code>.rdata</code>
|
|
|
file that you will use in the analysis later.</li>
|
|
|
<li><code>regression_analysis</code>: This is where you develop the
|
|
|
analysis that you will apply to the data you have. This will require
|
|
|
pulling the most recent data to analyze.</li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section class="slide level2">
|
|
|
|
|
|
<p>What this might look like.</p>
|
|
|
<ol type="1">
|
|
|
<li>init repo</li>
|
|
|
</ol>
|
|
|
<ol start="2" type="1">
|
|
|
<li class="fragment">write things such as README in main.</li>
|
|
|
<li class="fragment">Create <code>data_processing</code> branch</li>
|
|
|
<li class="fragment">Get <code>data_processing</code> to a working
|
|
|
state (committing along the way).</li>
|
|
|
<li class="fragment">merge main into data processing, fix conflicts,
|
|
|
then merge<code>data_processing</code> into main.</li>
|
|
|
<li class="fragment">create a branch
|
|
|
<code>regression_analysis</code> from main.</li>
|
|
|
<li class="fragment">start writing your analysis, committing along
|
|
|
the way.</li>
|
|
|
<li class="fragment">Notice that the data is incorrect.</li>
|
|
|
<li class="fragment">checkout <code>data_processing</code></li>
|
|
|
<li class="fragment">fix the error that is giving you the incorrect
|
|
|
data</li>
|
|
|
<li class="fragment">merge the fixes into main with a helpful
|
|
|
description.</li>
|
|
|
<li class="fragment">checkout <code>data_analysis</code> and merge
|
|
|
the fixes from main.</li>
|
|
|
<li class="fragment">finish your analysis with the corrected
|
|
|
data</li>
|
|
|
<li class="fragment">push analysis to main.</li>
|
|
|
<li class="fragment">Start a new branch <code>report</code> and
|
|
|
begin writing your report.</li>
|
|
|
</ol>
|
|
|
</section>
|
|
|
<section id="view-from-main-street" class="slide level2">
|
|
|
<h2>View from main street</h2>
|
|
|
<p>To someone looking at your main branch, they would see.</p>
|
|
|
<ol type="1">
|
|
|
<li>You created data processing tools.</li>
|
|
|
<li>You fixed an error in the data processing tools.</li>
|
|
|
<li>You then used that corrected data to perform an analysis.</li>
|
|
|
</ol>
|
|
|
</section>
|
|
|
<section id="quick-mention---squashes" class="slide level2">
|
|
|
<h2>Quick Mention - Squashes</h2>
|
|
|
<p>Sometimes when you have a bunch of small rough changes, you might
|
|
|
want to turn them into a single (nice looking) commit.</p>
|
|
|
<p>This is called squashing</p>
|
|
|
<div class="sourceCode" id="cb22"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> merge <span class="at">--squash</span> [branch name]</span></code></pre></div>
|
|
|
<p>For example, if we had 3 commits in spellcheck, we could squash
|
|
|
merge them into main by:</p>
|
|
|
<div class="sourceCode" id="cb23"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> switch main</span>
|
|
|
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> merge <span class="at">--squash</span> spellcheck</span></code></pre></div>
|
|
|
<p>This is one way to rewrite the DAG. It depends on the fact that
|
|
|
branches are disposable. There is no need to keep a branch around
|
|
|
after it is squashed.</p>
|
|
|
</section></section>
|
|
|
<section>
|
|
|
<section id="remotes" class="title-slide slide level1">
|
|
|
<h1>Remotes</h1>
|
|
|
|
|
|
</section>
|
|
|
<section id="git-is-a-distributed-vcs" class="slide level2">
|
|
|
<h2>Git is a Distributed VCS</h2>
|
|
|
<p>We have focused on the Version Control System portions of Git.
|
|
|
Now it is time to look at how to use it as a “distributed” VCS and
|
|
|
how to collaborate together.</p>
|
|
|
<blockquote>
|
|
|
<p>Git originated as a tool to develop the Linux Kernel. It is now
|
|
|
the most popular VCS in the world. This is - in part - because
|
|
|
people can work on the same thing without getting in each other’s
|
|
|
way.</p>
|
|
|
</blockquote>
|
|
|
<p>Because Git is flexible, it supports many different workflows.
|
|
|
When you work with an established team, learn their workflow.</p>
|
|
|
</section>
|
|
|
<section id="adding-a-local-remote" class="slide level2">
|
|
|
<h2>Adding a local Remote</h2>
|
|
|
<p>A remote is somewhere that git will fetch commits from. A
|
|
|
repository can have more than one remote.</p>
|
|
|
<blockquote>
|
|
|
<p>A local remote is a remote that is on the same computer, e.g. a
|
|
|
separate HDD or USB drive.</p>
|
|
|
</blockquote>
|
|
|
<p>How would we add a remote?</p>
|
|
|
<ul>
|
|
|
<li><code>git remote --help</code></li>
|
|
|
</ul>
|
|
|
<ul>
|
|
|
<li
|
|
|
class="fragment">e.g. <code>git remote add usb_drive /path/to/usb/drive/repo</code></li>
|
|
|
<li class="fragment"><code>git clone --help</code></li>
|
|
|
<li
|
|
|
class="fragment"><code>git clone /path/to/onedrive/folder/with/repo</code></li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="remote-workflow" class="slide level2">
|
|
|
<h2>Remote workflow</h2>
|
|
|
<div class="sourceCode" id="cb24"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="co"># Begin by fetching chagnes</span></span>
|
|
|
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> fetch remote/branch</span>
|
|
|
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a><span class="co"># Merge changes from remote branch into your current branch</span></span>
|
|
|
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> merge remote/branch</span>
|
|
|
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a></span>
|
|
|
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a><span class="co"># Work like normal</span></span>
|
|
|
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a></span>
|
|
|
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a><span class="co"># Give your updates back</span></span>
|
|
|
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> push remote/branch</span></code></pre></div>
|
|
|
<p>There is a command that combines the fetch and merge steps:</p>
|
|
|
<div class="sourceCode" id="cb25"><pre
|
|
|
class="sourceCode bash"><code class="sourceCode bash"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> pull remote/branch</span></code></pre></div>
|
|
|
</section>
|
|
|
<section id="exercise" class="slide level2">
|
|
|
<h2>Exercise</h2>
|
|
|
<ul>
|
|
|
<li>I’ve got a usb drive that we can pass around.</li>
|
|
|
<li>It already has a git repo on it.</li>
|
|
|
<li>We are going to create a joint wiki.
|
|
|
<ul>
|
|
|
<li>Each person chooses a topic or two from their personal
|
|
|
wiki.</li>
|
|
|
<li>We will pass around the USB a couple of times, allowing people
|
|
|
to
|
|
|
<ul>
|
|
|
<li>clone the repo</li>
|
|
|
<li>add their topics</li>
|
|
|
<li>push to the repo</li>
|
|
|
</ul></li>
|
|
|
<li>We will then divide into editing teams and I’ll assign you a
|
|
|
topic or two that you will edit.</li>
|
|
|
<li>As we pass the USB around, you’ll get a chance to pull and push
|
|
|
changes.</li>
|
|
|
<li>Talk as an editing team, but don’t share computers.</li>
|
|
|
</ul></li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="git-forges" class="slide level2">
|
|
|
<h2>Git Forges</h2>
|
|
|
<p>When people think of git, they usually think of github.</p>
|
|
|
<blockquote>
|
|
|
<p>Git is to Github as video is to YouTube. <a
|
|
|
href="https://santoshhari.wordpress.com/2020/06/17/git-github-p0rn-p0rnhub-problematic-alternatives/">Quoted
|
|
|
in Hari-up</a></p>
|
|
|
</blockquote>
|
|
|
<p>A Git Forge provides</p>
|
|
|
<ul>
|
|
|
<li>A non-local git remote</li>
|
|
|
<li>features such as bug trackers and wiki’s to help coordinate
|
|
|
software development.</li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="demo-git-forge" class="slide level2">
|
|
|
<h2>Demo Git Forge</h2>
|
|
|
<p>I have a git forge that we are going to practice using</p>
|
|
|
<p>We are going to</p>
|
|
|
<ul>
|
|
|
<li>add it as a remote</li>
|
|
|
<li>continue the experiment using the remote.</li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="cloning-non-local-remote" class="slide level2">
|
|
|
<h2>Cloning non-local remote</h2>
|
|
|
<ul>
|
|
|
<li>Login</li>
|
|
|
<li>Getting the URL</li>
|
|
|
<li>add the remote</li>
|
|
|
<li>Making branches</li>
|
|
|
<li>Pushing branches from CLI</li>
|
|
|
<li>Merging to Main.</li>
|
|
|
</ul>
|
|
|
<blockquote>
|
|
|
<p>NOTE!!! I will be removing your access to this git remote
|
|
|
sometime after the lab is over. You will still have a local copy of
|
|
|
the wiki though!</p>
|
|
|
</blockquote>
|
|
|
</section></section>
|
|
|
<section>
|
|
|
<section id="final-thoughts" class="title-slide slide level1">
|
|
|
<h1>Final Thoughts</h1>
|
|
|
|
|
|
</section>
|
|
|
<section id="how-have-i-used-git-in-my-work" class="slide level2">
|
|
|
<h2>How have I used Git in my work?</h2>
|
|
|
<ul>
|
|
|
<li><p>I have used git to track my code for both data processing and
|
|
|
data analysis</p></li>
|
|
|
<li><p>If I were taking a class on econometrics where we have to
|
|
|
code up some analyses, I might keep track of it in Git. A folder for
|
|
|
each homework, tagging it right before submitting it. I would only
|
|
|
use one branch probably.</p></li>
|
|
|
<li><p>I have used git to coordinate work for an econometrics group
|
|
|
project.</p></li>
|
|
|
<li><p>I use it to recover an analysis that I deleted by
|
|
|
accident.</p></li>
|
|
|
<li><p>I am currently working on my disseration in LaTeX.</p></li>
|
|
|
<li><p>I use git to be able to revert mistakes and sync work across
|
|
|
multiple computers.</p></li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="what-should-you-continue-learning"
|
|
|
class="slide level2">
|
|
|
<h2>What should you continue learning?</h2>
|
|
|
<ul>
|
|
|
<li><strong>.gitignore files</strong> - Sometimes you don’t want to
|
|
|
stage a whole class of files. A <code>.gitignore</code> file tell
|
|
|
git to not to stage them. For example, if you are doing an analysis
|
|
|
in python, you might get a <code>__pycache__/</code> directory. If
|
|
|
you put a line that says <code>*/__pycache__/</code> in your
|
|
|
<code>.gitignore</code>, it will not be suggested that you stage
|
|
|
anything in that directory.</li>
|
|
|
<li><strong>Git LFS</strong> - Saving large files that are not text
|
|
|
can be difficult, such as when you are saving <code>.pdf</code>,
|
|
|
<code>.jpg</code>, <code>.png</code>,<code>.xlsx</code>,
|
|
|
<code>.docx</code>, or <code>.zip</code> files. Any change will
|
|
|
cause the whole thing to be resaved, and this can quickly add up to
|
|
|
lots of storage being used. Git LFS does a couple of things to
|
|
|
reduce how much storage will be used.</li>
|
|
|
<li><strong>Branching Strategies</strong> - Knowing how to setup and
|
|
|
use branches properly is a powerful thing. There are tons of blogs
|
|
|
with information from different companies explaining how they are
|
|
|
doing it.</li>
|
|
|
<li><strong>Advanced Merging and Rebasing</strong> - There is so
|
|
|
much to do here.</li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="most-of-all" class="slide level2">
|
|
|
<h2>Most of All</h2>
|
|
|
<h3 id="practice">Practice!</h3>
|
|
|
</section>
|
|
|
<section id="conclusion" class="slide level2">
|
|
|
<h2>Conclusion</h2>
|
|
|
<figure>
|
|
|
<img data-src="https://imgs.xkcd.com/comics/git.png"
|
|
|
alt="If that doesn’t fix it, git.txt contains the phone number of a friend of mine who understands git. Just wait through a few minutes of ‘It’s really pretty simple, just think of branches as…’ and eventually you’ll learn the commands that will fix everything." />
|
|
|
<figcaption aria-hidden="true">If that doesn’t fix it, git.txt
|
|
|
contains the phone number of a friend of mine who understands git.
|
|
|
Just wait through a few minutes of ‘It’s really pretty simple, just
|
|
|
think of branches as…’ and eventually you’ll learn the commands that
|
|
|
will fix everything.</figcaption>
|
|
|
</figure>
|
|
|
<p>I’m sorry, you just became the local git expert…</p>
|
|
|
</section>
|
|
|
<section id="seriously-though" class="slide level2">
|
|
|
<h2>Seriously though</h2>
|
|
|
<ul>
|
|
|
<li>Git is a useful tool to keep track of software versions and
|
|
|
coordinate work.</li>
|
|
|
<li>Most of the time you can get away with just memorizing some
|
|
|
basic commands and workflow</li>
|
|
|
<li>When things are hard, remember
|
|
|
<ul>
|
|
|
<li>The basic model of how it works. Try to figure out what went
|
|
|
wrong.</li>
|
|
|
<li>DuckDuckGo search is your friend. Google might be as well.</li>
|
|
|
<li>ChatGPT/Claude.ai are pretty good at explaining errors,
|
|
|
commands, etc.</li>
|
|
|
</ul></li>
|
|
|
<li>Don’t commit anything that needs to remain secret. It is rather
|
|
|
hard to delete something from a Git repo.</li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="feedback" class="slide level2">
|
|
|
<h2>Feedback</h2>
|
|
|
<ul>
|
|
|
<li>What questions do you have?</li>
|
|
|
<li>What would you like to keep practicing?</li>
|
|
|
<li>How could I improve this presentation?</li>
|
|
|
</ul>
|
|
|
</section>
|
|
|
<section id="license" class="slide level2">
|
|
|
<h2>License</h2>
|
|
|
<p xmlns:cc="http://creativecommons.org/ns#" xmlns:dct="http://purl.org/dc/terms/">
|
|
|
<a property="dct:title" rel="cc:attributionURL" href="https://git.youainti.com/Teaching/git-introduction">Introduction to Version Control Systems (GIT) for Economists</a>
|
|
|
by
|
|
|
<a rel="cc:attributionURL dct:creator" property="cc:attributionName" href="https://www.youainti.com">Will King</a>
|
|
|
is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/?ref=chooser-v1" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">CC BY-NC-SA 4.0<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/nc.svg?ref=chooser-v1" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg?ref=chooser-v1" alt=""></a></p>
|
|
|
</section></section>
|
|
|
<div class="license-footer" style="position: fixed; top: 5px; right: 5px; z-index: 1000;">
|
|
|
<a href="#" class="license-icons" data-toggle="license-tooltip">
|
|
|
<img style="height:16px; margin-left:2px;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" alt="CC">
|
|
|
<img style="height:16px; margin-left:2px;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg" alt="BY">
|
|
|
<img style="height:16px; margin-left:2px;" src="https://mirrors.creativecommons.org/presskit/icons/nc.svg" alt="NC">
|
|
|
<img style="height:16px; margin-left:2px;" src="https://mirrors.creativecommons.org/presskit/icons/sa.svg" alt="SA">
|
|
|
</a>
|
|
|
<div class="license-tooltip">
|
|
|
Introduction to Git for Economists by Will King is licensed under CC BY-NC-SA 4.0
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<script src="https://unpkg.com/reveal.js//dist/reveal.js"></script>
|
|
|
|
|
|
<!-- reveal.js plugins -->
|
|
|
<script src="https://unpkg.com/reveal.js//plugin/notes/notes.js"></script>
|
|
|
<script src="https://unpkg.com/reveal.js//plugin/search/search.js"></script>
|
|
|
<script src="https://unpkg.com/reveal.js//plugin/zoom/zoom.js"></script>
|
|
|
|
|
|
<script>
|
|
|
|
|
|
// Full list of configuration options available at:
|
|
|
// https://revealjs.com/config/
|
|
|
Reveal.initialize({
|
|
|
// Display controls in the bottom right corner
|
|
|
controls: true,
|
|
|
|
|
|
// Help the user learn the controls by providing hints, for example by
|
|
|
// bouncing the down arrow when they first encounter a vertical slide
|
|
|
controlsTutorial: true,
|
|
|
|
|
|
// Determines where controls appear, "edges" or "bottom-right"
|
|
|
controlsLayout: 'bottom-right',
|
|
|
|
|
|
// Visibility rule for backwards navigation arrows; "faded", "hidden"
|
|
|
// or "visible"
|
|
|
controlsBackArrows: 'faded',
|
|
|
|
|
|
// Display a presentation progress bar
|
|
|
progress: true,
|
|
|
|
|
|
// Display the page number of the current slide
|
|
|
slideNumber: false,
|
|
|
|
|
|
// 'all', 'print', or 'speaker'
|
|
|
showSlideNumber: 'all',
|
|
|
|
|
|
// Add the current slide number to the URL hash so that reloading the
|
|
|
// page/copying the URL will return you to the same slide
|
|
|
hash: true,
|
|
|
|
|
|
// Start with 1 for the hash rather than 0
|
|
|
hashOneBasedIndex: false,
|
|
|
|
|
|
// Flags if we should monitor the hash and change slides accordingly
|
|
|
respondToHashChanges: true,
|
|
|
|
|
|
// Push each slide change to the browser history
|
|
|
history: false,
|
|
|
|
|
|
// Enable keyboard shortcuts for navigation
|
|
|
keyboard: true,
|
|
|
|
|
|
// Enable the slide overview mode
|
|
|
overview: true,
|
|
|
|
|
|
// Disables the default reveal.js slide layout (scaling and centering)
|
|
|
// so that you can use custom CSS layout
|
|
|
disableLayout: false,
|
|
|
|
|
|
// Vertical centering of slides
|
|
|
center: true,
|
|
|
|
|
|
// Enables touch navigation on devices with touch input
|
|
|
touch: true,
|
|
|
|
|
|
// Loop the presentation
|
|
|
loop: false,
|
|
|
|
|
|
// Change the presentation direction to be RTL
|
|
|
rtl: false,
|
|
|
|
|
|
// see https://revealjs.com/vertical-slides/#navigation-mode
|
|
|
navigationMode: 'default',
|
|
|
|
|
|
// Randomizes the order of slides each time the presentation loads
|
|
|
shuffle: false,
|
|
|
|
|
|
// Turns fragments on and off globally
|
|
|
fragments: true,
|
|
|
|
|
|
// Flags whether to include the current fragment in the URL,
|
|
|
// so that reloading brings you to the same fragment position
|
|
|
fragmentInURL: true,
|
|
|
|
|
|
// Flags if the presentation is running in an embedded mode,
|
|
|
// i.e. contained within a limited portion of the screen
|
|
|
embedded: false,
|
|
|
|
|
|
// Flags if we should show a help overlay when the questionmark
|
|
|
// key is pressed
|
|
|
help: true,
|
|
|
|
|
|
// Flags if it should be possible to pause the presentation (blackout)
|
|
|
pause: true,
|
|
|
|
|
|
// Flags if speaker notes should be visible to all viewers
|
|
|
showNotes: false,
|
|
|
|
|
|
// Global override for autoplaying embedded media (null/true/false)
|
|
|
autoPlayMedia: null,
|
|
|
|
|
|
// Global override for preloading lazy-loaded iframes (null/true/false)
|
|
|
preloadIframes: null,
|
|
|
|
|
|
// Number of milliseconds between automatically proceeding to the
|
|
|
// next slide, disabled when set to 0, this value can be overwritten
|
|
|
// by using a data-autoslide attribute on your slides
|
|
|
autoSlide: 0,
|
|
|
|
|
|
// Stop auto-sliding after user input
|
|
|
autoSlideStoppable: true,
|
|
|
|
|
|
// Use this method for navigation when auto-sliding
|
|
|
autoSlideMethod: null,
|
|
|
|
|
|
// Specify the average time in seconds that you think you will spend
|
|
|
// presenting each slide. This is used to show a pacing timer in the
|
|
|
// speaker view
|
|
|
defaultTiming: null,
|
|
|
|
|
|
// Enable slide navigation via mouse wheel
|
|
|
mouseWheel: false,
|
|
|
|
|
|
// The display mode that will be used to show slides
|
|
|
display: 'block',
|
|
|
|
|
|
// Hide cursor if inactive
|
|
|
hideInactiveCursor: true,
|
|
|
|
|
|
// Time before the cursor is hidden (in ms)
|
|
|
hideCursorTime: 5000,
|
|
|
|
|
|
// Opens links in an iframe preview overlay
|
|
|
previewLinks: false,
|
|
|
|
|
|
// Transition style (none/fade/slide/convex/concave/zoom)
|
|
|
transition: 'slide',
|
|
|
|
|
|
// Transition speed (default/fast/slow)
|
|
|
transitionSpeed: 'default',
|
|
|
|
|
|
// Transition style for full page slide backgrounds
|
|
|
// (none/fade/slide/convex/concave/zoom)
|
|
|
backgroundTransition: 'fade',
|
|
|
|
|
|
// Number of slides away from the current that are visible
|
|
|
viewDistance: 3,
|
|
|
|
|
|
// Number of slides away from the current that are visible on mobile
|
|
|
// devices. It is advisable to set this to a lower number than
|
|
|
// viewDistance in order to save resources.
|
|
|
mobileViewDistance: 2,
|
|
|
|
|
|
// reveal.js plugins
|
|
|
plugins: [
|
|
|
RevealNotes,
|
|
|
RevealSearch,
|
|
|
RevealZoom
|
|
|
]
|
|
|
});
|
|
|
</script>
|
|
|
<script>
|
|
|
Reveal.addEventListener('ready', function(event) {
|
|
|
var licenseIcons = document.querySelector('.license-icons');
|
|
|
var licenseTooltip = document.querySelector('.license-tooltip');
|
|
|
|
|
|
licenseIcons.addEventListener('mouseover', function() {
|
|
|
licenseTooltip.style.display = 'block';
|
|
|
});
|
|
|
|
|
|
licenseIcons.addEventListener('mouseout', function() {
|
|
|
licenseTooltip.style.display = 'none';
|
|
|
});
|
|
|
|
|
|
licenseIcons.addEventListener('click', function(e) {
|
|
|
e.preventDefault();
|
|
|
});
|
|
|
});
|
|
|
</script>
|
|
|
</body>
|
|
|
</html>
|