-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
543 lines (390 loc) · 38.8 KB
/
index.html
File metadata and controls
543 lines (390 loc) · 38.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="UTF-8">
<title>Tutorial-version-control by Hanover-CS</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="stylesheets/normalize.css" media="screen">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen">
<link rel="stylesheet" type="text/css" href="stylesheets/github-light.css" media="screen">
</head>
<body>
<section class="page-header">
<h1 class="project-name">Tutorial-version-control</h1>
<h2 class="project-tagline">Tutorial on using Git and GitHub for version control</h2>
<a href="https://github.com/Hanover-CS/tutorial-version-control" class="btn">View on GitHub</a>
<a href="https://github.com/Hanover-CS/tutorial-version-control/zipball/master" class="btn">Download .zip</a>
<a href="https://github.com/Hanover-CS/tutorial-version-control/tarball/master" class="btn">Download .tar.gz</a>
</section>
<section class="main-content">
<h1>
<a id="version-control-with-git-and-github" class="anchor" href="#version-control-with-git-and-github" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Version Control with Git and GitHub</h1>
<p>Reference links:</p>
<ul>
<li><a href="https://git-scm.com/doc">Official Git documentation</a></li>
<li><a href="https://guides.github.com/">GitHub guides</a></li>
<li><a href="https://help.github.com/categories/managing-your-work-on-github/">Managing your work with GitHub</a></li>
</ul>
<h2>
<a id="table-of-contents" class="anchor" href="#table-of-contents" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Table of contents</h2>
<ul>
<li><a href="#what-version-control-is-and-why-you-should-care">What Version Control is and why you should care</a></li>
<li><a href="#standard-git-operations">Standard Git operations</a></li>
<li><a href="#standard-github-utilities">Standard GitHub utilities</a></li>
<li><a href="#more-advanced-processes">More advanced processes</a></li>
</ul>
<h2>
<a id="what-version-control-is-and-why-you-should-care" class="anchor" href="#what-version-control-is-and-why-you-should-care" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>What Version Control is and why you should care</h2>
<p><strong>Version control</strong> stores a complete history of the codebase, including information about <em>what</em> changed, <em>when</em> and by <em>whom</em>. This has many advantages:</p>
<ul>
<li>Can revert changes that broke something.</li>
<li>Can identify at what point in time something broke and what changes occured at that time. For each line of code you can literally find out when it was introduced and by whom.</li>
<li>Can review someone's changes compared to what the code looked like before those changes.</li>
<li>Can maintain multiple code branches, for example a release/fixes branch, an experimental branch that tries to change something on the server side, another experimental branch that tries to change the UI and so on.</li>
<li>Can have multiple people contribute to the same code without worrying about overwriting each other's work.</li>
<li>Can allow people to offer changes, and choose whether you will incorporate them or not. Makes it easy to review what those changes are.</li>
</ul>
<h2>
<a id="git-github-and-related-concepts" class="anchor" href="#git-github-and-related-concepts" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Git, GitHub and related concepts</h2>
<ul>
<li>
<strong>Git</strong> is a program that works on your computer and maintains a repository of your program's evolution over time. It was initially created by Linus Torvalds, the creator of Linux, in order to host the Linux Kernel.
<ul>
<li>A <strong>repository</strong> is essentially a <em>managed</em> directory on your computer on which git maintains a project. All this information is stored in a hidden subdirectory called ".git".</li>
<li>The fundamental building block of any version control system is a <strong>commit</strong>. It contains:
<ul>
<li>Information about which prior commit it is based off.</li>
<li>A set of changes to the codebase, often called a <strong>diff</strong>.</li>
<li>A timestamp of when these changes where committed.</li>
<li>Author information about who committed these changes.</li>
<li>A brief message written by the author about the commit.</li>
<li>Commits in git are named via md5 hashes. So you'll see commits with names like <code>160d6693edd0fe306de0a703fe97a8b13908d68b</code>, and for almost all purposes you can use the first 5-6 characters from that as an identifier of the commit.</li>
</ul>
</li>
<li>A <strong>branch</strong> is a series of commits, each based off the previous one. It is usually represented by the last commit in the chain, and you can follow the links from it back all the way to the start. The whole repository has in this sense a tree structure, with the leaves representing different branches.</li>
<li>It is very common practice to start a new branch in order to explore some ideas, then discard it or merge it to the main branch as appropriate. Creating a new branch is cheap and easy to do.</li>
<li>Git allows the notion of <strong>remote repositories</strong>, which establish a link between this repository and some repository that lives in another place (typically access via the web). This way you can have a "main repository" that all the individual team members' repositories connect to and update. There are various names for these remote repositories depending on use case, like "origin" or "upstream". We will discuss these further later.</li>
</ul>
</li>
<li>
<strong>GitHub</strong> is one of many websites that offer an ecosystem around git repositories. Many other similar websites have similar features as described here.
<ul>
<li>It gives you a place to remotely store your repositories, and then <strong>clone</strong> them into any machine that needs to use them.</li>
<li>It allows project management via "issues tracker", with <em>issues</em>, <em>milestones</em> and <em>labels</em>.</li>
<li>It facilitates project sharing and contributing to open source projects via <em>forks</em> and <em>pull requests</em>.</li>
<li>It provides a Wiki for project documentation.</li>
<li>It offers a way to automatically create a web page from a branch or folder in your project.</li>
<li>Your GitHub page is effectively a part of your resume, and employers may look at it.</li>
</ul>
</li>
<li>When working with a Git repository, there are three important concepts to keep in mind:
<ul>
<li>The <em>repository</em>, which holds all the different commits and branches of your project. Typically you are looking at a particular commit at any given time, and that is termed the <strong>HEAD</strong>.</li>
<li>The <strong>working directory</strong> is the state of your current directory. Typically you started from a certain commit state at the HEAD of a branch. Then you changed some files, perhaps added some new files. You have not made any commits of these yet. All these constitute your working directory.</li>
<li>The <strong>staging area</strong> or <strong>index</strong> is an intermediate state of your changes. Looking at all the files in your working directory that differ from the HEAD, you can choose which ones or which parts of ones to include into your next commit. You then place those into the index. This step is typically called "staging".</li>
<li>When you create a commit, that commit is based off the staging area and it contains exactly the differences that you staged into the index.</li>
<li>So a typical workflow when working on a particular local issue would be as follows:
<ul>
<li>Switch to an appropriate branch to work on. This turns the entire directory into the state that the head of that branch looks like. The HEAD points to this latest commit in that branch.</li>
<li>Pull the most recent changes from the remote repository.</li>
<li>Make changes to files, add new files etc.</li>
<li>Review these changes, and stage some or all of those stages for commit.</li>
<li>Make a commit. This creates a new commit based off of the commit at the HEAD, and also changes the HEAD to now point to our new commit.</li>
<li>Rinse and repeat</li>
<li>Push the various commits you made back to the remote repository.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>
<a id="standard-git-operations" class="anchor" href="#standard-git-operations" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Standard Git operations</h2>
<p>Git is a command-line tool, to be precise a collection of such tools. We will describe those tools in this section. It is worth noting however, that there are various graphical interfaces that you can use to access most of these same functions. You can find many of those, many free, <a href="https://git-scm.com/downloads">here</a>. <a href="https://www.gitkraken.com/">GitKraken</a> in particular looks quite nice. We start with a brief list of the various "verbs":</p>
<ul>
<li>
<code>init</code> starts a new repository.</li>
<li>
<code>clone</code> clones/copies a repository, typically to create a local copy of it. The intent is to directly contribute to the repository.</li>
<li>
<code>fork</code> copies a repository, with the intent of possibly advancing the project to a new direction. A forked repository does not directly communicate with its "source" repository, while a cloned repository does.</li>
<li>
<code>status</code> shows information about the current status of the repository, index, head and other information.</li>
<li>
<code>add</code> adds changes to files, or even completely new files, to the staging area/index. A precursor to committing.</li>
<li>
<code>remove</code> marks a file to be removed from the repository (and often deleted at the same time). The repository will stop tracking this file.</li>
<li>
<code>diff</code> shows you difference between specified commits of your repository and or the index or working directory. Used to determine what will be committed.</li>
<li>
<code>commit</code> creates a new commit.</li>
<li>
<code>log</code> shows a history of prior commits.</li>
<li>
<code>stash</code> allows you to temporarily "hide" changes you've made, and produce a clean working directory. Often needed when changing branches or performing other directory changes.</li>
<li>
<code>checkout</code> allows you to switch to a new branch or go to a specific commit. This changes what the working directory and index look like.</li>
<li>
<code>reset</code> can clear up the working directory and/or index, and bring them to some specific state.</li>
<li>
<code>push</code> communicates your newly added local commits to a remote repository.</li>
<li>
<code>fetch</code> and <code>pull</code> retrieve commits from a remote repository.</li>
<li>
<code>merge</code> is used to merge a branch's changes into another branch.</li>
<li>
<code>rebase</code> allows restructuring of the commit history and shifting branches so they have a new start location.</li>
<li>
<code>cherry-pick</code> allows you to select a commit from anywhere and apply its effects to your current working directory.</li>
</ul>
<p>Some of these are more advanced. We will now examine them in more detail. This section is broken into parts:</p>
<ul>
<li><a href="#starting-a-repository">Starting a repository</a></li>
<li><a href="#reviewing-repository-state">Reviewing repository state</a></li>
<li><a href="#making-commits">Making Commits</a></li>
<li><a href="#managing-branches">Managing branches</a></li>
<li><a href="#working-with-remotes">Working with remotes</a></li>
</ul>
<h3>
<a id="starting-a-repository" class="anchor" href="#starting-a-repository" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Starting a repository</h3>
<p>There are two main ways to start a repository. You can turn any directory in your computer into a repository via <code>git init</code>:</p>
<div class="highlight highlight-source-shell"><pre>git init</pre></div>
<p>This will turn the current directory into a repository. The other way to start a repository is to <code>git clone</code> an existing repository. For instance the following line will clone the GitHub repository hosting this file into a directory called <code>tutorial-git</code>:</p>
<div class="highlight highlight-source-shell"><pre>git clone https://github.com/Hanover-CS/tutorial-version-control.git tutorial-git</pre></div>
<p>This will download the entire state of the repository into that folder, and also set up remote repository links from our local clone to the GitHub repository. This is typically the easiest way around; create a repository in GitHub first, then clone it to your computer.</p>
<h3>
<a id="reviewing-repository-state" class="anchor" href="#reviewing-repository-state" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Reviewing repository state</h3>
<p>There couple of tools help you with determining your current repository state.</p>
<h4>
<a id="status" class="anchor" href="#status" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Status</h4>
<p>First off is <code>git status</code>.</p>
<div class="highlight highlight-source-shell"><pre>$ git status
On branch gh-pages
Your branch is up-to-date with <span class="pl-s"><span class="pl-pds">'</span>origin/gh-pages<span class="pl-pds">'</span></span>.
Changes to be committed:
(use <span class="pl-s"><span class="pl-pds">"</span>git reset HEAD <file>...<span class="pl-pds">"</span></span> to unstage)
modified: README.md
Changes not staged <span class="pl-k">for</span> commit:
(use <span class="pl-s"><span class="pl-pds">"</span>git add <file>...<span class="pl-pds">"</span></span> to update what will be committed)
(use <span class="pl-s"><span class="pl-pds">"</span>git checkout -- <file>...<span class="pl-pds">"</span></span> to discard changes <span class="pl-k">in</span> working directory)
modified: README.md</pre></div>
<p>This tells us some key information:</p>
<ul>
<li>We are currently working on the gh-pages branch, and HEAD points to the head of the gh-pages branch.</li>
<li>Our branch is related to a branch called <code>gh-pages</code> in the remote repository called <code>origin</code>, and we are currently in sync with it. On some occasions we might be ahead by some commits, meaning we've made some commits that we have not pushed to the remote yet, or the remote might be ahead meaning we have not updated our local repository with that remote information.</li>
<li>Next we have a list of files that have had changes that are <em>staged</em>. When we make a commit, these changes will be committed. In this case it seems we have modified a file, called <code>README.md</code>. git also tells us how we would "unstage" a change.</li>
<li>Next we have a list of files in the working directory that have some changes done to them, but we have not yet committed them. In this case it seems again that the <code>README.md</code> file also has some changes that have not been staged. This is an important option that git offers us: Only some of the changes in that file are scheduled for commit right now, and some others are staying put, waiting a later commit perhaps. You can choose parts of a file to stage.</li>
</ul>
<p>There is also a "short" version of the output:</p>
<div class="highlight highlight-source-shell"><pre>$ git status -s
MM README.md</pre></div>
<p>The first M says that there are changes in this file that are staged, the second says that there are also changes that are not staged yet.</p>
<h4>
<a id="log" class="anchor" href="#log" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Log</h4>
<p><code>git log</code> shows us the history of recent logs. It has lots of options that you can find out by doing <code>git log --help</code> or by <a href="https://git-scm.com/docs/git-log">reading the documentation</a>. A particularly nice option is the "oneline" logs:</p>
<div class="highlight highlight-source-shell"><pre>$ git log --oneline
3fcd19b Create gh-pages branch via GitHub
8e8ec9e Creating git sections
31b4fa1 Create gh-pages branch via GitHub
ad68152 Start on state section
35362d7 Initial Commit</pre></div>
<p>This simply tells us, in chronological order from the most recent to the oldest commit, what the commit's hash is and what the message is.</p>
<p>You can do a lot more with log, like restrict it to only showing commits that changed a particular file:</p>
<div class="highlight highlight-source-shell"><pre>$ git log --oneline -- README.md
8e8ec9e Creating git sections
ad68152 Start on state section
35362d7 Initial Commit</pre></div>
<h4>
<a id="diff" class="anchor" href="#diff" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Diff</h4>
<p><code>git diff</code> allows us to visually see the differences between commits. Its output might look something like this:</p>
<div class="highlight highlight-source-shell"><pre>$ git diff
diff --git a/README.md b/README.md
index 953c5ed..ab7f849 100644
--- a/README.md
+++ b/README.md
@@ -138,6 +138,30 @@ MM README.md
this is the stuff that was <span class="pl-k">in</span> the file before
-this line was there before and is now removed. The minus <span class="pl-k">in</span> front tells us that.
+this is a new line we are adding.
+This too. And the empty line right below. The plus tells us these are new.
+
this line existed before</pre></div>
<p>A lot of this information is not for human consumption, but you can see that it describes what was added and where in the file it was added: All the lines starting with a plus are new, all the ones starting with a minus are removed, and the others were there before. Most graphical program have a nice color-rich way of showing these differences.</p>
<h3>
<a id="making-commits" class="anchor" href="#making-commits" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Making Commits</h3>
<h4>
<a id="add" class="anchor" href="#add" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Add</h4>
<p>You can stage files for commit via <code>git add</code>:</p>
<div class="highlight highlight-source-shell"><pre>$ git add README.md</pre></div>
<p>This line makes all the changes that were in <code>README.md</code> to the staging area, to be committed.</p>
<p>If you want to add all the current changes from all files, you can use a dot to refer to the current directory:</p>
<div class="highlight highlight-source-shell"><pre>$ git add <span class="pl-c1">.</span></pre></div>
<p>Finally if you want to add parts of a file, you can do an <em>interactive add</em>, that brings up a mini interface. You would want to <a href="https://git-scm.com/book/en/v2/Git-Tools-Interactive-Staging">read the documentation</a> on how that works.</p>
<div class="highlight highlight-source-shell"><pre>$ git add -i</pre></div>
<p>Many GUI clients will offer you a way to do that directly. We will be looking at how we can do this with GitKraken in class.</p>
<h4>
<a id="commit" class="anchor" href="#commit" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Commit</h4>
<p>To commit the staged changes, we use <code>git commit</code>:</p>
<div class="highlight highlight-source-shell"><pre>$ git commit -m <span class="pl-s"><span class="pl-pds">"</span>Enter message here<span class="pl-pds">"</span></span></pre></div>
<p>You can also add the staged changes onto the last commit, instead of creating a new one. Very useful if you forgot to include a file:</p>
<div class="highlight highlight-source-shell"><pre>$ git commit --amend</pre></div>
<p>Be advised that this would change the last commit you have made. If you have already pushed/synced that commit to the remote repository, bad things can happen. <em>Never make changes to commits that have been synced to a remote!</em></p>
<h4>
<a id="reset" class="anchor" href="#reset" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Reset</h4>
<p>Resetting allows you to back out of a commit you made that you did not mean to make. It is in general a dangerous operation, and you should only use it if you are sure you know what you are doing. There are three kinds of resets:</p>
<div class="highlight highlight-source-shell"><pre>$ git reset --mixed</pre></div>
<p>This is the "mixed" reset, which is the default. This will "unstage" all files that were staged for commit. It does not change or delete the files, it simply no longer marks them as ready for commit. We say that it changes the <em>index</em>, but it does not change the <em>working directory</em>.</p>
<div class="highlight highlight-source-shell"><pre>$ git reset --soft HEAD~</pre></div>
<p>This is a "soft" reset. It does not change your index or your working directory. Files that were staged remain staged, and files that have changes keep those changes. But it does change the commit that is at the HEAD, to instead point to the commit called <code>HEAD~</code>, which is a notation for the commit before HEAD. Essentially this undoes the last commit. It does not lose the files that that last commit did. It simply puts them back to the "unstaged files" section. It would be as if you had not run <code>git commit</code> yet.</p>
<div class="highlight highlight-source-shell"><pre>$ git reset --hard</pre></div>
<p>This is a destructive step. It will completely remove what is in the index and working directory, and set them both to the HEAD (or another commit if you specify that at the end of the line). You will lose all the changes you have made. On rare occasions, this is the right thing to do. But it should be avoided. It is however useful if you wanted to "rewind" the current branch to a previous commit, because you realized you did not need it. The <a href="https://git-scm.com/docs/git-reset">documentation</a> offers the following example:</p>
<div class="highlight highlight-source-shell"><pre>$ git branch experiment
$ git reset --hard HEAD~3
$ git checkout experiment</pre></div>
<p>So what happens here is that we realized that our last 3 commits should have gone in a new branch, called <code>experiment</code>, instead of our current branch. The first line creates that new branch based off the current commits. The second line resets our current branch to go back 3 commits. The third line then switches us to the <code>experiment</code> branch to continue working on that.</p>
<h3>
<a id="managing-branches" class="anchor" href="#managing-branches" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Managing branches</h3>
<p>There are a number of different operations on branches. A branch is nothing more than a chain of commits, marked by a pointer to the newest commit in the branch. As far as Git is concerned the only information in the branch is its name and that pointer to the newest commit.</p>
<h4>
<a id="creating-a-branch" class="anchor" href="#creating-a-branch" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Creating a branch</h4>
<p>We create a new branch via the <code>git branch</code> command:</p>
<div class="highlight highlight-source-shell"><pre>$ git branch <span class="pl-c1">test</span></pre></div>
<p>This creates a branch based off the current commit, and calls it test. You could then use <code>git checkout</code> to switch to it. We could create a new branch and switch to it all at once with the command:</p>
<div class="highlight highlight-source-shell"><pre>$ git checkout -b <span class="pl-c1">test</span></pre></div>
<p>You can have the branch based off a different commit by specifying it as a next argument.</p>
<h4>
<a id="switching-to-a-branch" class="anchor" href="#switching-to-a-branch" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Switching to a branch</h4>
<p>We use <code>git checkout</code> to switch to a branch:</p>
<div class="highlight highlight-source-shell"><pre>$ git checkout <span class="pl-c1">test</span></pre></div>
<h4>
<a id="viewing-the-different-branches" class="anchor" href="#viewing-the-different-branches" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Viewing the different branches</h4>
<p>We can get information about the existing branches via the <code>-v</code> switch in <code>git branch</code>:</p>
<div class="highlight highlight-source-shell"><pre>$ git branch -v
<span class="pl-k">*</span> gh-pages 45e13b6 [ahead 1] Update readme
master 35362d7 Initial Commit
<span class="pl-c1">test</span> 45e13b6 Update readme</pre></div>
<p>The asterisk marks the current branch. We see the name of the branch, the latest commit in it, the message of that commit, and in brackets the possible relation of the branch with a remote branch.</p>
<p>There is also a <code>-vv</code> option that shows us more about the relation to remote branches, along with the names of those branches.</p>
<div class="highlight highlight-source-shell"><pre>$ git branch -vv
<span class="pl-k">*</span> gh-pages 45e13b6 [origin/gh-pages: ahead 1] Update readme
master 35362d7 [origin/master: gone] Initial Commit
<span class="pl-c1">test</span> 45e13b6 Update readme</pre></div>
<h4>
<a id="deleting-a-branch" class="anchor" href="#deleting-a-branch" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Deleting a branch</h4>
<p>You can delete a branch via the <code>-d</code> switch:</p>
<div class="highlight highlight-source-shell"><pre>$ git branch -d <span class="pl-c1">test</span></pre></div>
<p>This does NOT actually delete any commits, it just removes the pointer to the commit that used to be at the front of the <code>test</code> branch. This may however result in commits being deleted, when git does its self-cleaning, which is a form of garbage collection: Any commits that are not reachable in some form starting from one of the branches are subject to deletion. Deleting a branch may put a number of commits in this situation, if the branch has not been merged into another branch.</p>
<h4>
<a id="merging" class="anchor" href="#merging" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Merging</h4>
<p>There are a number of situations when merging is called for, where you have two branches that have diverged in some way and you want to bring them back together. There are two common situations:</p>
<ul>
<li>A remote repository has been updated by someone else, and in the meantime you have prepared some commits to make. When you fetch the remote changes, you now have two divergent branches, and you need to somehow bring them back in order.</li>
<li>You created a branch to try some things out, and in the meantime also made some needed commits to the main branch. Now your changes in your offshoot branch are completed and you want to merge them into the main branch.</li>
</ul>
<p>This is a complicated situation, with many possible solutions, each with its tradeoff. We will discuss them extensively in the <a href="#more-advanced-processes">advanced sections</a>.</p>
<h3>
<a id="working-with-remotes" class="anchor" href="#working-with-remotes" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Working with remotes</h3>
<p>Working with remote repositories is a key element of Git, which focuses on "distributed version control". Here we discuss these key elements.</p>
<p>A <strong>remote repository</strong> is actually a special part of your repository that contains a copy of another repository. You can fetch information from that other repository, and store them in the "remote repository", which is really like a branch in your local repository. You can then decide how best to merge those changes with the work you have been doing in your local repository.</p>
<h4>
<a id="viewing-the-remotes" class="anchor" href="#viewing-the-remotes" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Viewing the remotes</h4>
<p>You can see the remote repositories you have access to via <code>git remote</code>:</p>
<div class="highlight highlight-source-shell"><pre>$ git remote -v
origin https://github.com/Hanover-CS/tutorial-version-control.git (fetch)
origin https://github.com/Hanover-CS/tutorial-version-control.git (push)</pre></div>
<p>You see here in our case that there is a remote called <code>origin</code>, which points to a GitHub repository. You will notice that there are two different addresses, one for fetching/pulling and one for pushing. While the addresses for those two are typically the same, in certain workflows they are not.</p>
<p>You can also view the <em>branches</em> from the remote that you have decided to work with locally, via something like:</p>
<div class="highlight highlight-source-shell"><pre>$ git remote show origin
<span class="pl-k">*</span> remote origin
Fetch URL: https://github.com/Hanover-CS/tutorial-version-control.git
Push URL: https://github.com/Hanover-CS/tutorial-version-control.git
HEAD branch: gh-pages
Remote branch:
gh-pages tracked
Local branches configured <span class="pl-k">for</span> <span class="pl-s"><span class="pl-pds">'</span>git pull<span class="pl-pds">'</span></span>:
gh-pages merges with remote gh-pages
master merges with remote master
Local ref configured <span class="pl-k">for</span> <span class="pl-s"><span class="pl-pds">'</span>git push<span class="pl-pds">'</span></span>:
gh-pages pushes to gh-pages (fast-forwardable)</pre></div>
<p>This gives us information about which branches are set up to work on <code>git pull</code> and which are set up to work with <code>git push</code>, along with some other information.</p>
<p>The branches can be accessed with something like <code>origin/gh-pages</code> and in many ways behave like normal branches. We can for instance review the work in such a branch with:</p>
<div class="highlight highlight-source-shell"><pre>$ git log origin/gh-pages --oneline</pre></div>
<h4>
<a id="tracking-a-remote-branch" class="anchor" href="#tracking-a-remote-branch" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Tracking a remote branch</h4>
<p>If you want to start tracking a new remote branch, you can do so with:</p>
<div class="highlight highlight-source-shell"><pre>$ git checkout --track origin/newbranchName</pre></div>
<p>This will create a new branch called <code>newbranchName</code> and set it to track the remote branch, so we can easily push and pull.</p>
<h4>
<a id="pushing-and-pulling" class="anchor" href="#pushing-and-pulling" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Pushing and Pulling</h4>
<p>In order to push your commits to the remote branch, you would use <code>git push</code>, with or without specifying the repository (it will use the one that the current branch is tracking if you don't specify) and also optionally specifying a specific branch to push:</p>
<div class="highlight highlight-source-shell"><pre>$ git push origin master</pre></div>
<p>This will only work if the remote branch isn't ahead of the local branch. If someone has pushed some changed to the remote in the meantime, you would be asked to fetch those changes first and incorporate them into your work, before pushing.</p>
<p>In order to bring new changes in, you have to "fetch" the remote branch:</p>
<div class="highlight highlight-source-shell"><pre>$ git fetch origin</pre></div>
<p>This will update the "local" remote branch with any changes from the server, but it would not yet merge these changes into your local branch. In other words, this would update <code>origin/gh-pages</code> but not our <code>gh-pages</code> branch. That would require a further merge. What you want most of the time is a <code>git pull</code>:</p>
<div class="highlight highlight-source-shell"><pre>$ git pull origin</pre></div>
<p>This fetches and then merges. Oftentimes what you want is instead a rebase:</p>
<div class="highlight highlight-source-shell"><pre>$ git pull --rebase</pre></div>
<p>This is particularly useful: Say that you created some commits, and in the meantime someone pushed their changes to the remote repository. Your changes have nothing to do with theirs, so if you had pulled their changes first before creating your commits you would have had a nice linear structure to the commits. But instead you now have two diverging commits. What "rebasing" will do is fetch the remote changes, then "replay" your changes as if they had happened after those remote changes. This way you can maintain the linear structure of the commits. Rebasing is an important technique, and we will discuss it further in the <a href="#more-advanced-processes">advanced sections</a>.</p>
<h2>
<a id="standard-github-utilities" class="anchor" href="#standard-github-utilities" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Standard GitHub utilities</h2>
<p>In GitHub you review commits, and mostly create and discuss issues.</p>
<ul>
<li><a href="#reviewing-code-and-commits-in-github">Reviewing code and commits in GitHub</a></li>
<li><a href="#github-issues">GitHub Issues</a></li>
<li><a href="#github-projects">GitHub Projects</a></li>
</ul>
<p>You should create a GitHub account and treat it as part of your resume. Setting up an account is fairly straightforward and we will not cover it further.</p>
<p>You will also likely need to generate SSH tokens, as described <a href="https://help.github.com/articles/keeping-your-ssh-keys-and-application-access-tokens-safe/">here</a>.</p>
<p>GitHub has <a href="https://help.github.com/categories/managing-your-work-on-github/">extensive documentation</a>. We will only cover some basics here.</p>
<p>When you look at a repository for a project in GitHub, the main page contains the a number of different tabs:</p>
<ul>
<li>The <strong>Code</strong> tab allows us to browse the current state of the repository, as well as review the various commits that have occured so far, and look at the various different branches, where applicable.</li>
<li>The <strong>Issues</strong> tab allows us to create and identify issues that need to be addressed, and to commment and discuss them. Each issue comes with an associated number, and commits can be linked to those issues via an appropriate text in the commit message. Issues can be further organized by the use of <strong>milestones</strong> and <strong>labels</strong>.</li>
<li>
<strong>Pull Requests</strong> are a critical part of collaborative work with GitHub, especially valuable when contributing to open source projects. When you start with someone's repository and take in a certain direction, you can then offer these changes back via a pull request. The author of the original repository can then decide whether to accept these or not, and a discussion can be had.</li>
<li>
<strong>Projects</strong> are a relatively new feature in GitHub. Projects allow you to organize together issues and ad-hoc notes into custom columns, and manage the progress of the overall project that way.</li>
<li>An optional <strong>Wiki</strong> allows the creation of documentation in relation to the application you are developing. In many cases, other means of documentation are preferable.</li>
</ul>
<h3>
<a id="reviewing-code-and-commits-in-github" class="anchor" href="#reviewing-code-and-commits-in-github" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Reviewing code and commits in GitHub</h3>
<p>The Code tab allows you to navigate your codebase. By default it shows what happens in the current branch, but you can change that. There are a number of actions you can take from the Code tab:</p>
<ul>
<li>Navigating to any particular file, you can edit it right there in your web browser, and create a commit that way. It is in general to be avoided, but it is certainly possible.</li>
<li>You can create a new pull request based off the currently viewed branch.</li>
<li>You can browse the various commits, and either see how they differ from the previous state, or browse the entire repository as it was at that point in time.</li>
<li>When viewing a commit's difference from the previous state, you can also interject comments inbetween any lines, or comment on the overall commit, at the bottom of the page.</li>
</ul>
<h3>
<a id="github-issues" class="anchor" href="#github-issues" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>GitHub Issues</h3>
<p>The Issues tab allows us to work with issues and set tasks. To begin with you see a list of open issues, and you can filter and sort the list in various ways, as well as globally operate on multiple issues.</p>
<ul>
<li>Clicking on an individual issue takes you to the issue's page.</li>
<li>An issue has a title and some main text, as well as a longer comment. There can be many "replies" to an issue, creating a discussion.</li>
<li>Commits can be linked to a particular issue by adding something like "ref #24" or "close #24" to the commit message. They will then appear as part of the issue discussion.</li>
<li>In the comment section for an issue you can use <a href="https://guides.github.com/features/mastering-markdown/">GitHub-flavored Markdown</a>, a simple and powerful text-based format style.</li>
<li>You can also create "task lists" that you can check off as you make progress on the issue.</li>
<li>Issues can be assigned one or more "labels" (bug, enhancement, or your own custom labels).</li>
<li>Issues can be assigned to a "milestone". Milestones simply collect tasks together and can have set deadlines for completion.</li>
<li>Issues can be assigned to a specific developer.</li>
<li>Issues can refer to other issues in the comments section.</li>
<li>You can catch another developer's attention by including something like <code>@skiadas</code> in a message. They will typically receive an email about it.</li>
</ul>
<h3>
<a id="github-projects" class="anchor" href="#github-projects" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>GitHub Projects</h3>
<p>TODO</p>
<h2>
<a id="more-advanced-processes" class="anchor" href="#more-advanced-processes" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>More advanced processes</h2>
<ul>
<li>Forks and pull requests</li>
<li>Rewriting history via rebase</li>
</ul>
<p>TODO</p>
<footer class="site-footer">
<span class="site-footer-owner"><a href="https://github.com/Hanover-CS/tutorial-version-control">Tutorial-version-control</a> is maintained by <a href="https://github.com/Hanover-CS">Hanover-CS</a>.</span>
<span class="site-footer-credits">This page was generated by <a href="https://pages.github.com">GitHub Pages</a> using the <a href="https://github.com/jasonlong/cayman-theme">Cayman theme</a> by <a href="https://twitter.com/jasonlong">Jason Long</a>.</span>
</footer>
</section>
</body>
</html>