<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Zac Blanco</title>
    <description>zac&apos;s portfolio of professional and academic doings</description>
    <link>/</link>
    <atom:link href="/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Tue, 24 Mar 2026 17:36:54 +0000</pubDate>
    <lastBuildDate>Tue, 24 Mar 2026 17:36:54 +0000</lastBuildDate>
    <generator>Jekyll v4.4.1</generator>
    
      <item>
        <title>Creating a Swap File on a Ramdisk with Ubuntu 20.04</title>
        <description>&lt;p&gt;For some recent work I was looking to negate the latency of storage accesses of
swapping in order to more easily measure the kernel’s swap system overhead
without worrying about the latency of the underlying block device.&lt;/p&gt;

&lt;p&gt;Naively, I initially tried with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mount -t ramfs /mnt/ramdisk&lt;/code&gt; and simply tried
creating a swap file on that mount, but after trying something to the tune of
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;swapon /mnt/ramdisk/swap.img&lt;/code&gt; I was met with an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Operation not
supported&lt;/code&gt;. Some google-fu led me to the answer. &lt;a href=&quot;https://superuser.com/questions/539287/swapon-failed-invalid-argument-on-a-linux-system-with-btrfs-filesystem&quot;&gt;&lt;em&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tmpfs&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ramfs&lt;/code&gt; don’t
support the APIs required to act as a device to read and write a swap image&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, it is possible (at least if you’re on Ubuntu 20.04 Server) to use the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brd&lt;/code&gt; kernel module to create a block device at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/ram0&lt;/code&gt; which can then be
formatted with a filesystem swap file that &lt;em&gt;can&lt;/em&gt; be used as a ramdisk. Here is
the script:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# create the mount point directory&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo mkdir&lt;/span&gt; /mnt/ramdisk
&lt;span class=&quot;c&quot;&gt;# insert kernel module for /dev/ram0 and allocate 2GiB for swapfile&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;modprobe &lt;span class=&quot;nt&quot;&gt;-C&lt;/span&gt; brd.conf brd
&lt;span class=&quot;c&quot;&gt;# Format our ram device&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo dd &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/zero &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/ram0 &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1M &lt;span class=&quot;nv&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;2048
&lt;span class=&quot;c&quot;&gt;# create ext4 filesystem and mount (2GiB)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;mkfs.ext4 &lt;span class=&quot;nt&quot;&gt;-b&lt;/span&gt; 4096 /dev/ram0 536870912
&lt;span class=&quot;c&quot;&gt;# mount the block device&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;mount /dev/ram0 /mnt/ramdisk
&lt;span class=&quot;c&quot;&gt;# create swapfile&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo dd &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/zero &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/mnt/ramdisk/swap.img &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1M &lt;span class=&quot;nv&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;2048
&lt;span class=&quot;c&quot;&gt;# setup permissions and enable the swap file&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo chown &lt;/span&gt;root:root /mnt/ramdisk/swap.img
&lt;span class=&quot;nb&quot;&gt;sudo chmod &lt;/span&gt;600 /mnt/ramdisk/swap.img
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;mkswap /mnt/ramdisk/swap.img
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;swapon /mnt/ramdisk/swap.img
swapon &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And the file for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brd.conf&lt;/code&gt; for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;modprobe&lt;/code&gt; command contains parameters to
ensure the ramdisk is at least 2GiB (the desired size for my swap file):&lt;/p&gt;

&lt;div class=&quot;language-conf highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;brd&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rd_size&lt;/span&gt;=&lt;span class=&quot;m&quot;&gt;2147483648&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;brd&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rd_nr&lt;/span&gt;=&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Frankly, the latency using a ramdisk directly here was pretty disappointing
compared to an NVMe SSD, but I will potentially explore that issue in a later
post.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Tracing 1 functions for &quot;read_pages&quot;... Hit Ctrl-C to end.

     usecs               : count     distribution
         0 -&amp;gt; 1          : 0        |                                        |
         2 -&amp;gt; 3          : 0        |                                        |
         4 -&amp;gt; 7          : 11       |                                        |
         8 -&amp;gt; 15         : 61       |                                        |
        16 -&amp;gt; 31         : 1243     |**                                      |
        32 -&amp;gt; 63         : 8108     |***************                         |
        64 -&amp;gt; 127        : 20933    |****************************************|
       128 -&amp;gt; 255        : 17929    |**********************************      |
       256 -&amp;gt; 511        : 11953    |**********************                  |
       512 -&amp;gt; 1023       : 6        |                                        |
      1024 -&amp;gt; 2047       : 1        |                                        |
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
        <pubDate>Fri, 13 Aug 2021 00:00:00 +0000</pubDate>
        <link>/swap-ramdisk-ubuntu.html</link>
        <guid isPermaLink="true">/swap-ramdisk-ubuntu.html</guid>
        
        
      </item>
    
      <item>
        <title>Migrating Ubuntu 20.04 with LVM Partitioning</title>
        <description>&lt;p&gt;We were running some experiments on a local cluster of machines that were
originally installed and configured using the Ubuntu 20.04 Server live CD. After
brief investigation into some performance issues we found that the operating
system (and rest of the system software) was installed on a spinning drive
with performance less than 1/5 of SSD on the system.&lt;/p&gt;

&lt;p&gt;We didn’t want to re-install the OS and software because there was a lot of
configuration we had to do to the operating system due to some specialized
hardware we were using. So, we decided to opt for a disk migration instead. I
had done some OS migrations years ago, so I figured moving the OS partition for
Ubuntu should be straightforward. I’ll preface the rest of the post saying that
the experience wasn’t &lt;em&gt;unpleasant&lt;/em&gt; but there was little documentation that I
could find on the internet related to newer versions of Ubuntu. Everything
seemed to be for 12.04, 14.04, etc.&lt;/p&gt;

&lt;p&gt;I’m writing this post to hopefully help out some other poor lost souls who might
need to migrate their operating system installs from one disk to another (and
save some time in the process) that were installed with an LVM partitioning
scheme.&lt;/p&gt;

&lt;h3 id=&quot;setup&quot;&gt;Setup&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;OS initially installed on a 1TiB drive (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/sdb&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;Unpartitioned/formatted 512GiB SSD (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/sda&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;Ubuntu 20.04 installer used with all default settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Ubuntu OS installer creates 3 partitions when installing the OS to a single
disk and when the LVM partition install is used&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/sd*1&lt;/code&gt; –&amp;gt; mounts to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/boot/efi&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/sd*2&lt;/code&gt; –&amp;gt; mounts to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/boot&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/sd*3&lt;/code&gt; –&amp;gt; mounts to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The goal is to completely move the boot and data partitions from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/sdb&lt;/code&gt; to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/sda&lt;/code&gt;&lt;/strong&gt; and then finally be able to boot with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/sdb&lt;/code&gt; completely wiped
and formatted.&lt;/p&gt;

&lt;h3 id=&quot;instructions&quot;&gt;Instructions&lt;/h3&gt;

&lt;p&gt;I used the &lt;a href=&quot;https://gparted.org/livecd.php&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gparted&lt;/code&gt;&lt;/a&gt; live CD image to boot
into the OS. Once booted with gparted:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Make sure all partitions on the target drive (SSD) are removed and the disk
is entirely blank&lt;/li&gt;
  &lt;li&gt;use gparted to clone the partions mapped to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/boot&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/boot/efi&lt;/code&gt; to
their respective locations. In other words copy+paste &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/sdb1&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/sda1&lt;/code&gt;
and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/sdb2&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/sda2&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Shrink the lvm partition so that it can fit on the new disk
    &lt;ul&gt;
      &lt;li&gt;right click the LVM partition -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deactivate&lt;/code&gt;. Then, shrink the partition so
that it can fit on the new drive, assuming that your target drive has enough
free space.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These boot partitions and resizing should be quick. Next, we need to move the
main data partition. Unfortunately, Gparted doesn’t support the copy+paste of
LVM-based partitions, so we need to use the command-line. I followed some
&lt;a href=&quot;https://askubuntu.com/questions/161279/how-do-i-move-my-lvm-250-gb-root-partition-to-a-new-120gb-hard-disk&quot;&gt;instructions from
askubuntu&lt;/a&gt;
in order to create a new LVM partition and move the data to the SSD.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# We need to create a new partition on the new SSD&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Create the new partition in the shell with &quot;n&quot; using the defaults.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# &quot;w&quot; to write&lt;/span&gt;
fdisk /dev/sdNEW

&lt;span class=&quot;c&quot;&gt;# Once the new partition is created, add it to the logical volume,&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# move the data, and remove the old one. &quot;ubuntu-vg&quot; is the volume&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# group name that the installer gave to the LVM volume&lt;/span&gt;
pvcreate /dev/sdNEW3
vgextend ubuntu-vg /dev/sdNEW3
pvmove /dev/sdOLD3
vgreduce ubuntu-vg /dev/sdOLD3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally, use gparted to remove the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;boot&lt;/code&gt; flag from the partition on the old
drive and add the boot flag to the copy of that partition on the new drive.
After all these steps you can reboot without the gparted live CD.&lt;/p&gt;

&lt;p&gt;At this point, the OS should be able to reboot into the OS successfully. However
we never deleted or reconfigured the boot process, so if you run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lsblk&lt;/code&gt; I saw
that the HDD &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/boot&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/boot/efi&lt;/code&gt; partitions were still mounted.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;lsblk
&lt;span class=&quot;go&quot;&gt;NAME                      MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                         8:0    0 447.1G  0 disk
├─sda1                      8:1    0   512M  0 part
├─sda2                      8:2    0     1G  0 part
└─sda3                      8:3    0 445.6G  0 part
  └─ubuntu--vg-ubuntu--lv 253:0    0   200G  0 lvm  /
sdb                         8:16   0 931.5G  0 disk
├─sdb1                      8:1    0   512M  0 part /boot/efi
├─sdb2                      8:2    0     1G  0 part /boot
└─sdb3                      8:3    0 445.6G  0 part
sdb                         8:16   0 931.5G  0 disk
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To fix this, unmount and delete the partitions, then mount the new partitions
(they should contain the same data) and then run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;grub-install&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;update-grub&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;umount /boot/efi
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;umount /boot
&lt;span class=&quot;c&quot;&gt;# remove the partitions with &quot;d&quot; and finally a &quot;w&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;fdisk /dev/sdOLD

&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;mount /dev/sdNEW2 /boot
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;mount /dev/sdNEW1 /boot/efi
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;grub-install
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;update-grub
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After running all these steps and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reboot&lt;/code&gt;, our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lsblk&lt;/code&gt; shows the correct
output, and a free HDD that we can format again use to store more data.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;lsblk
&lt;span class=&quot;go&quot;&gt;NAME                      MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                         8:0    0 447.1G  0 disk
├─sda1                      8:1    0   512M  0 part /boot/efi
├─sda2                      8:2    0     1G  0 part /boot
└─sda3                      8:3    0 445.6G  0 part
  └─ubuntu--vg-ubuntu--lv 253:0    0   200G  0 lvm  /
sdb                         8:16   0 931.5G  0 disk
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

</description>
        <pubDate>Sun, 06 Jun 2021 00:00:00 +0000</pubDate>
        <link>/blog/migrating-ubuntu-lvm-partioning/</link>
        <guid isPermaLink="true">/blog/migrating-ubuntu-lvm-partioning/</guid>
        
        
      </item>
    
      <item>
        <title>Two Years of Reflection</title>
        <description>&lt;p&gt;One of the things I learned about during my time as a learning assistant at
Rutgers University assisting in classes and teaching in classes is the term
&lt;em&gt;metacognition&lt;/em&gt;. A page on Vanderbilt University’s website describes
metacognition as&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;the processes used to plan, monitor, and assess one’s understanding and
performance&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot; role=&quot;doc-noteref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This was one of the crucial ideas that we were taught to consider and understand
when guiding our peers through the vast web of knowledge in each class. From
what I remember being told, those students who succeeded in classes were usually
better at &lt;em&gt;thinking about their thinking&lt;/em&gt;. Or, in a sense, reflecting on what
they’ve learned, and how to integrate it into their current understanding of the
their respective subjects. By engaging in metacognition students can help
improve recall, fix misconceptions, and improve the speed at which they can
solve problems in the specific domain. It also helps identify strengths and
weaknesses in the subject matter which can drive the areas a student may study
or practice.&lt;/p&gt;

&lt;p&gt;Having just recently finished two years in the workforce, and about to enter a
PhD program where I will most likely be conducting a whole &lt;em&gt;lot&lt;/em&gt; of learning, I
think now is a good time to begin to reflect on what has been accomplished over
the last few years. It is also where I could look back on where I could have
made better judgement and improved on the products that I delivered. Also, I
want to reflect on my time in my company as a whole, and where I think the
company made missteps and where it earned my respect. Hopefully, trying to
acknowledge these parts will enable me to find areas where I can improve as an
engineer as well as help me identify organizations and aspects of which that I
should look for when seeking work in the future; skills that I’m sure will be
integral in helping me reach the end of this degree program and beyond.&lt;/p&gt;

&lt;p&gt;For the rest of this post, I’m going to highlight some of the areas I feel that
I struggle with, and then research and write about things I can do to improve
myself in those areas, along with some plans of action that I can take&lt;/p&gt;

&lt;h3 id=&quot;design-and-deliverables&quot;&gt;Design and Deliverables&lt;/h3&gt;

&lt;p&gt;One area where I struggled before, and still struggle is clearly communicating
technical design verbally to others. I tend to rely heavily on depictions and
diagrams to get my points across to others. I find that during explanations, I
find myself moving from one point to another somewhat erratically.
Unfortunately, I felt that there wasn’t many opportunities to improve on this
over the last few years as there were only a few projects that required a
thorough design which needed to be communicated and approved before
implementing.&lt;/p&gt;

&lt;p&gt;Personally, I feel it’s okay to lean on diagrams to help explain technical
concepts, but in the future I need to find a better way to make sure my
explanations logically flow from one point to the next, using the diagram more
as a guide, rather than leaning &lt;em&gt;on&lt;/em&gt; it to do the explaining. This is one skill
that surely applies across a multitude of areas such as technical interviews,
research presentations, and engineer.&lt;/p&gt;

&lt;p&gt;Searching around the internet, I found a few places where some say that
diagrams (or whiteboards) are fine for communicating technical information&lt;sup id=&quot;fnref:2&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot; role=&quot;doc-noteref&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.
I think whiteboards and meetings are fine for conveying architecture and
communication - but I feel they are best used for fleshing out early ideas when
collaborating with co-workers. Final designs should be able to be described in
technical documentation that can be accessed and read by others with less
context, and not require someone else present to explain points in the document.
Apparently, there is a standard - IEEE 1471&lt;sup id=&quot;fnref:3&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot; role=&quot;doc-noteref&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; which describes how to
communicate and document software architecture. Reading further on the IEEE
website, this document has actually been superseded by IEEE 42010-2011&lt;sup id=&quot;fnref:4&quot;&gt;&lt;a href=&quot;#fn:4&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot; role=&quot;doc-noteref&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. Both
documents I’m sure provide valuable guidelines for communicating system
architectures, so I will be sure to read them to hopefully apply them
to my practice.&lt;/p&gt;

&lt;h3 id=&quot;project-management&quot;&gt;Project Management&lt;/h3&gt;

&lt;p&gt;After experiencing the last few years, I think its crucial that companies,
especially startups, justify the work they are doing by having a clear GTM
(go-to market) strategy&lt;sup id=&quot;fnref:gtm&quot;&gt;&lt;a href=&quot;#fn:gtm&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot; role=&quot;doc-noteref&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; for their products. Having a clear strategy not
only helps make it clear to the investors of a company how the product will
succeed, but also the employees as well. Small startup companies are inherently
risky - every employee of the company is usually putting something down on the
line and will want to know how their work contributes to the company’s success.&lt;/p&gt;

&lt;p&gt;To some extent, you should always listen your direct manager’s directions. They
should be able to justify why or how the work you are doing fits in to the
bigger picture. If the company has a clear GTM strategy, then your manager
should be able to give you a straightforward answer to what company goals your
work is contributing to. If they aren’t able to do that, then there’s probably
an issue with your manager, or the company. I think personally, I could have
done a better job asking the right question as to where some of my work would
fit in and how it would be used by customers.&lt;/p&gt;

&lt;p&gt;Now, for small tasks (1-4 days of time) I would argue that it’s probably not
&lt;em&gt;as&lt;/em&gt; necessary to understand the motivation behind each task. However, if you
know you’re going to be involved on a project for an extended period of time (1
-3 months or more), then I think you should be able to hold your manager
accountable for being able to explain where the project fits into the bigger
picture. If they aren’t able to do so, then maybe it is time to start
re-evaluating your current position, team, or even company. Management should
at minimum be able to justify their decisions for the direction and assignment
of projects.&lt;/p&gt;

&lt;p&gt;To be clear, startups pivot for a vast number of reasons, and sometimes the
management might not have the clearest picture about what the next steps are for
the company. However, if the company tries to hide the fact that it is
struggling, or feeds lies about progress, then I think that’s a clear warning
sign when things are bad. If your manager(s) are at least honest about what is
happening, then you should be able to trust in them to do the right thing. In
the future, I’m going to try to do a better job asking the right questions about
my assignments, as well as team direction.&lt;/p&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;

&lt;p&gt;There are surely a multitude of other areas that I could have performed better
in. The two that discussed today are things that stuck out starkly to me a
couple of times over the last few years. I want to be able to make permanent
improvements to my ability to work in an industry setting that will help me
improve as an engineer and as an employee. Singling out and writing about them
along with giving myself concrete actions to take to improve I &lt;em&gt;hope&lt;/em&gt; will
improve my prospects for the future.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://cft.vanderbilt.edu/guides-sub-pages/metacognition/&quot;&gt;https://cft.vanderbilt.edu/guides-sub-pages/metacognition/&lt;/a&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://softwareengineering.stackexchange.com/a/263825&quot;&gt;https://softwareengineering.stackexchange.com/a/263825&lt;/a&gt; &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://softwareengineering.stackexchange.com/a/263825&quot;&gt;https://softwareengineering.stackexchange.com/a/263825&lt;/a&gt; &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:4&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://standards.ieee.org/standard/42010-2011.html&quot;&gt;https://standards.ieee.org/standard/42010-2011.html&lt;/a&gt; &lt;a href=&quot;#fnref:4&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:gtm&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://blog.hubspot.com/sales/gtm-strategy&quot;&gt;https://blog.hubspot.com/sales/gtm-strategy&lt;/a&gt; &lt;a href=&quot;#fnref:gtm&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Wed, 30 Sep 2020 00:00:00 +0000</pubDate>
        <link>/blog/two-years-of-reflection/</link>
        <guid isPermaLink="true">/blog/two-years-of-reflection/</guid>
        
        
      </item>
    
      <item>
        <title>JVM Pauses - It&apos;s more than GC</title>
        <description>&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#background&quot; id=&quot;markdown-toc-background&quot;&gt;Background&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#safepoint-operations&quot; id=&quot;markdown-toc-safepoint-operations&quot;&gt;Safepoint Operations&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#analyzing-safepoint-pauses&quot; id=&quot;markdown-toc-analyzing-safepoint-pauses&quot;&gt;Analyzing Safepoint Pauses&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#conclusion&quot; id=&quot;markdown-toc-conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#notes&quot; id=&quot;markdown-toc-notes&quot;&gt;Notes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;background&quot;&gt;Background&lt;/h3&gt;

&lt;p&gt;Everyone knows and loves the good-ol’ JVM
&lt;a href=&quot;https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html&quot;&gt;GC&lt;/a&gt;
pause. &lt;a href=&quot;https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/cms.html&quot;&gt;New GC
algorithms&lt;/a&gt;
have been
&lt;a href=&quot;https://www.oracle.com/technetwork/tutorials/tutorials-1876574.html&quot;&gt;introduced&lt;/a&gt;
to &lt;a href=&quot;https://wiki.openjdk.java.net/display/zgc/Main&quot;&gt;improve GC
latencies&lt;/a&gt; or &lt;a href=&quot;https://wiki.openjdk.java.net/display/shenandoah/Main&quot;&gt;prevent
the need&lt;/a&gt; to &lt;a href=&quot;https://www.azul.com/resources/azul-technology/azul-c4-garbage-collector/&quot;&gt;pause
altogether&lt;/a&gt;.
However, that’s not the end of the story for JVM pauses. Unfortunately,
there are a variety of other housekeeping tasks within the JVM that
can force it to stop executing user code&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot; role=&quot;doc-noteref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;h3 id=&quot;safepoint-operations&quot;&gt;Safepoint Operations&lt;/h3&gt;

&lt;p&gt;First, it is important to understand the concept of a &lt;em&gt;safepoint&lt;/em&gt; within
the JVM. A &lt;em&gt;safepoint&lt;/em&gt; is a point in program execution where the state
of the program is known and can be examined. Things like registers,
memory, etc. For the JVM to completely pause and run tasks (such
as GC), &lt;strong&gt;all threads&lt;/strong&gt; must come to a safepoint.&lt;/p&gt;

&lt;p&gt;For example, to retrieve a stack trace on a thread we must come to a
safepoint. This also means tools like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jstack&lt;/code&gt; require that all threads
of the program be able to reach a safepoint.&lt;/p&gt;

&lt;p&gt;To be more precise about what exactly a safepoint is, we refer to the
&lt;a href=&quot;https://openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html&quot;&gt;HotSpot Glossary&lt;/a&gt;
which defines a &lt;em&gt;safepoint&lt;/em&gt; as:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A point during program execution at which all GC roots are known and
all heap object contents are consistent. From a global point of view,
all threads must block at a safepoint before the GC can run. (As a
special case, threads running JNI code can continue to run, because
they use only handles. During a safepoint they must block instead of
loading the contents of the handle.) From a local point of view, a
safepoint is a distinguished point in a block of code where the
executing thread may block for the GC. Most call sites qualify as
safepoints. There are strong invariants which hold true at every
safepoint, which may be disregarded at non-safepoints. Both compiled
Java code and C/C++ code be optimized between safepoints, but less so
across safepoints. The JIT compiler emits a GC map at each safepoint.
C/C++ code in the VM uses stylized macro-based conventions (e.g.,
TRAPS) to mark potential safepoints.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While GC is one of the most common safepoint operations, there are many
VM operations&lt;sup id=&quot;fnref:2&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot; role=&quot;doc-noteref&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; that are run while threads are at safepoints. Some may
be invoked externally by connecting to the HotSpot JVM (i.e. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jstack&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jcmd&lt;/code&gt;) while others are internal to the JVM operation (monitor
deflation, code deoptimization). A list of common operations is below.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;User Invoked:
    &lt;ul&gt;
      &lt;li&gt;Deadlock detection&lt;/li&gt;
      &lt;li&gt;JVMTI&lt;/li&gt;
      &lt;li&gt;Thread Dumps&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Run at regular intervals (see &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-XX:GuaranteedSafepointInterval&lt;/code&gt;&lt;sup id=&quot;fnref:opt_ref&quot;&gt;&lt;a href=&quot;#fn:opt_ref&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot; role=&quot;doc-noteref&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;)
    &lt;ul&gt;
      &lt;li&gt;Monitor Deflation&lt;/li&gt;
      &lt;li&gt;Inline Cache Cleaning&lt;/li&gt;
      &lt;li&gt;Invocation Counter Delay&lt;/li&gt;
      &lt;li&gt;Compiled Code Marking&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Other:
    &lt;ul&gt;
      &lt;li&gt;Revoking &lt;a href=&quot;https://blogs.oracle.com/dave/biased-locking-in-hotspot&quot;&gt;Biased Locks&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;Compiled method Deoptimization&lt;/li&gt;
      &lt;li&gt;GC&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All these operations force the JVM to come to a safepoint in order to
run some kind of VM operation. Now we can decompose a safepoint
operation times into two categories.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/jvm-pause/pause-time-diagram.png&quot; alt=&quot;JVM pause time diagram&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Time taken from initiating the safepoint request until all threads
reach a safepoint&lt;/li&gt;
  &lt;li&gt;Time taken to perform safepoint operation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can view this behavior in a JVM by adding the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-XX:+PrintGCApplicationStoppedTime&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-XX:+PrintGCDetails&lt;/code&gt;&lt;sup id=&quot;fnref:more_gc_flags&quot;&gt;&lt;a href=&quot;#fn:more_gc_flags&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot; role=&quot;doc-noteref&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; flags.
This will print messages to the GC logs that look like:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Total time for which application threads were stopped: 0.0572646 seconds, Stopping threads took: 0.0000088 seconds
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;em&gt;0.0572646 seconds&lt;/em&gt; is the sum total time that threads may have been
stopped for. This includes the blue and red sections above. The
&lt;em&gt;0.0000088 seconds&lt;/em&gt; is the time spent in the blue section, where it took
that much time to stop all threads at a safepoint. Even though the JVM
flag is named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-XX:+PrintGCApplicationStoppedTime&lt;/code&gt;&lt;sup id=&quot;fnref:3&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot; role=&quot;doc-noteref&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; it actually logs
all JVM pauses, not just GC.&lt;/p&gt;

&lt;p&gt;So, if applications are not responding, it may be because&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The JVM is trying to reach a safepoint and most threads have already stopped except
maybe one or two, or&lt;/li&gt;
  &lt;li&gt;The JVM has reached a safepoint and is running some internal operations. May it be GC, lock bias revocation, cache line
invalidation, etc.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The issue is that we need to figure out exactly what is triggering the
pause in the first place if anything, and then investigate which part of
the pause is taking a long time; the time to get to the safepoint
(TTSP), or the time spent performing the VM operation.&lt;/p&gt;

&lt;p&gt;To do that more logging is required. The flags that need to be added to
the JVM are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-XX:+PrintSafepointStatistics
-XX:PrintSafepointStatisticsCount=1&lt;/code&gt;. Adding these two arguments will
print to stdout or the configured log file every time a safepoint
operation occurs. As of JDK 8 the log output consists of two lines and
looks like the following (times are in ms):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  vmop [threads: total initially_running wait_to_block] [time: spin block sync cleanup vmop] page_trap_count
155623.484: RevokeBias [ 1595 0 0 ] [ 0 0 127 7 0 ]  0  
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://plumbr.io/blog/performance-blog/logging-stop-the-world-pauses-in-jvm&quot;&gt;Breaking&lt;/a&gt;
down the output:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;155623.484&lt;/strong&gt;: The time in seconds since the JVM started&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;RevokeBias (vmop)&lt;/strong&gt;: The VM operation running during this
safepoint.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;1595 (total)&lt;/strong&gt;: The total number of threads in the VM when the
safepoint was requested&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;0 (initially running)&lt;/strong&gt;: The number of threads running at the
beginning of the safepoint operation&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;0 (wait to block)&lt;/strong&gt;: The number of threads blocked when the VM
began the operation execution&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;0 (spin)&lt;/strong&gt;: The time spent spinning waiting for threads to reach a
safepoint&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;0 (block)&lt;/strong&gt;: The time spent waiting for threads to block for the
safepoint&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;127 (sync)&lt;/strong&gt;: The total time spent synchronizing the threads for
the safepoint. This is a combination of spin + block + “other
activity”. This value is what I regard as the  “time to safepoint” or
TTSP. In the GC logs, the TTSP or “Time stopping threads” typically
only includes the spin + block times based on my analysis.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;7 (cleanup)&lt;/strong&gt;: Time spent on internal VM cleanup activities&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;0 (vmop)&lt;/strong&gt;: The time spent on the actual safepoint operation
(RevokeBias). This can be any safepoint operation.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;0 (page_trap_count)&lt;/strong&gt;: Page trap count&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s important to reiterate that the spin, block, and sync times
represent portions of the TTSP. So, if TTSP is large it can mean that
one thread might be attempting to finish its work, while the rest of the
JVM threads are paused waiting for it to reach a safepoint. This is why
the total pause time of a JVM must be considered TTSP + cleanup + vmop.&lt;/p&gt;

&lt;p&gt;With this information we can handily take any JVM logs and figure out
which operations were running. It’s critical to consider both the
safepoint logs and GC logs. Otherwise it’s possible to miss information
about TTSP mentioned above.&lt;/p&gt;

&lt;h3 id=&quot;analyzing-safepoint-pauses&quot;&gt;Analyzing Safepoint Pauses&lt;/h3&gt;

&lt;p&gt;Now that we know all about safepoints and how to get their statistics,
we need to know what can prevent Java threads from coming to a
safepoint. Some of those causes are&lt;sup id=&quot;fnref:1:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot; role=&quot;doc-noteref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Large object initialization
    &lt;ul&gt;
      &lt;li&gt;i.e. initializing a 10GB array. (Single threaded, zeroing the array)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Array copying&lt;/li&gt;
  &lt;li&gt;JNI Handle Allocation&lt;/li&gt;
  &lt;li&gt;JNI Critical Regions&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://psy-lob-saw.blogspot.com/2015/12/safepoints.html&quot;&gt;Counted Loops&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;NIO Mapped Byte Buffers
    &lt;ul&gt;
      &lt;li&gt;Memory mapped portion of a file&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Usually, if a program is taking a long time to reach a safepoint there
is a systemic issue in the code where it performs one or more of the
operations above for extended periods of time without allowing the JVM
to come to a safepoint.&lt;/p&gt;

&lt;p&gt;Fortunately, there are even more options that can be added to the JVM in
order to enable logging when it takes a longer than expected time to
reach a safepoint&lt;sup id=&quot;fnref:4&quot;&gt;&lt;a href=&quot;#fn:4&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot; role=&quot;doc-noteref&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;-XX:+SafepointTimeout -XX:SafepointTimeoutDelay=&amp;lt;timeout in ms&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;These two options print to the VM log / stdout all threads which have
failed to reach a safepoint after the specified time period. This can
help developers troubleshoot which threads might be causing extended
pauses of the JVM and whether the root cause is the VM operation or the
TTSP.&lt;/p&gt;

&lt;p&gt;Next, we’ll do a real analysis on an example of a large TTSP and what
the JVM and GC logs will look like. The data below was collected from a
long running java server application.&lt;/p&gt;

&lt;p&gt;Take the following graph of a GC log from the “Time Application Threads
were Stopped” and the “Time Stopping Application Threads”:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/jvm-pause/gc_log_analysis.png&quot; alt=&quot;GC Pause Times Over 3-day period&quot; title=&quot;GC Log&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The graph above plots the GC log of a worker. It shows a few spikes with
a max of ~24 seconds of pause time reported by the JVM. For each spike
most of the thread pause time was actually spent stopping the threads,
not performing the operations! Notice the correlation of spikes in
“Threads waiting to stop” vs “Threads stopped time”. It’s clear
something is amiss.&lt;/p&gt;

&lt;p&gt;Now, let’s take a look at the safepoint statistics plotted on the same
timeline. Each statistic is represented individually on its own graph.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/jvm-pause/safepoint_log_analysis.png&quot; alt=&quot;Safepoint Logs over a 3-day period&quot; title=&quot;Safepoint Statistics&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This graph shows the times for each safepoint statistic. Remember the
sync time is generally equal to the TTSP (spin + block + “other”), but
compare the y-axis scale versus the graph above.&lt;/p&gt;

&lt;p&gt;This graph shows spikes correlated at the exact same times as some of
the GC pauses on the graph above, and even more frequently than as
reported by the GC log output. Additionally, the GC pause times reported
peaked at a measly 24s. The values for this graph (under the “sync”
operation) show spikes of over 200000ms, or nearly 5
minutes. Notice that the graph for “Op Time” (vmop) has a scale of only
500ms meaning many of the actual VM operations were short-lived.&lt;/p&gt;

&lt;p&gt;These graphs show that the “Time Stopping Application Threads” reported
in GC logs should not always be trusted. The safepoint statistics are
more fine grained, but provide more information about how the
application behaves. The reason we didn’t catch issues in the
application initially is because the GC log wasn’t providing the full
picture on how long the application was actually stopped for. The log
only reported ~24 seconds while in reality it was many minutes of time;
unacceptable for any application which is expected to serve data in
large quantities and low latencies.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Hopefully with this knowledge in-hand it will be easier to detect,
identify, and respond promptly when an application begins to fail due to
a JVM pause. The most helpful JVM flags to gather info are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-XX:+PrintGCApplicationStoppedTime&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-XX:+PrintGCDetails&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-XX:+PrintSafepointStatistics&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-XX:PrintSafepointStatisticsCount=1&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-XX:+SafepointTimeout&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-XX:SafepointTimeoutDelay=&amp;lt;ms before timeout log is printed&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By analyzing the GC log and safepoint statistics together it is much
easier to get a holistic view of how the JVM performs with respect to
pause times. Usually, this information is enough to identify a cause or
point in the right direction of a culprit.&lt;/p&gt;

&lt;h2 id=&quot;notes&quot;&gt;Notes&lt;/h2&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;There is a &lt;a href=&quot;https://www.youtube.com/watch?v=Y39kllzX1P8&quot;&gt;highly informative
 talk&lt;/a&gt; given by an Azul
 (previously Oracle JDK) engineer explaining the reasons,
 besides GC,  that can pause the JVM. Much of the information in
 this post comes from that video. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt; &lt;a href=&quot;#fnref:1:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/runtime/vm_operations.hpp#l41&quot;&gt;All Possible VM Operations in JDK
 8&lt;/a&gt; &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:opt_ref&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;http://jvm-options.tech.xebia.fr/#&quot;&gt;This reference
application&lt;/a&gt; containing all JVM
options is &lt;em&gt;very&lt;/em&gt; useful &lt;a href=&quot;#fnref:opt_ref&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:more_gc_flags&quot;&gt;
      &lt;p&gt;There is an additional flag which can may be of use:
            &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-XX:+PrintGCApplicationConcurrentTime&lt;/code&gt;. &lt;a href=&quot;#fnref:more_gc_flags&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot;&gt;
      &lt;p&gt;There is another flag: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-XX:+PrintGCApplicationConcurrentTime&lt;/code&gt;
 that will print the opposite; The time the application spends
 running between pauses, every time a pause occurs. &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:4&quot;&gt;
      &lt;p&gt;These guys really thought ahead didn’t they? There’s also a
 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-XX:+TraceSafepointCleanupTime&lt;/code&gt; which gives more detail about time
 spent on cleanup operations during the safepoint. &lt;a href=&quot;#fnref:4&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Thu, 28 May 2020 00:00:00 +0000</pubDate>
        <link>/blog/jvm-safepoint-pauses/</link>
        <guid isPermaLink="true">/blog/jvm-safepoint-pauses/</guid>
        
        
      </item>
    
      <item>
        <title>Ad-Hoc Networks and Static ARP entries on Raspberry Pi&apos;s</title>
        <description>&lt;p&gt;Part of our research this year involves creating and using ad-hoc networks on a linux-based operating system (Raspbian based on Debian Jessie).&lt;/p&gt;

&lt;p&gt;The hardware we’re working with:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;5x Raspberry Pi 2 Model B+&lt;/li&gt;
  &lt;li&gt;2x Raspberry Pi 3&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unfortunately ad-hoc network support and implementation seems to be lacking. We’ve run across a couple networking issues that we were able to resolve with some simple hacks to the system which allowed our network to function properly.&lt;/p&gt;

&lt;h2 id=&quot;ad-hoc-network-support-and-drivers&quot;&gt;Ad Hoc Network Support and Drivers&lt;/h2&gt;

&lt;p&gt;The Raspberry Pi 3 has a wireless chip which is built into the board. The chip uses a broadcom driver called &lt;a href=&quot;https://wiki.debian.org/brcmfmac&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;brcmfmac&lt;/code&gt;&lt;/a&gt;. This driver seems to properly implement support for Ad hoc networks - so our Pi 3’s gave us no trouble.&lt;/p&gt;

&lt;p&gt;It was really the Pi 2’s which we had trouble with. We were using some wireless adapters which utilize a realtek chip and driver in linux. Specifically the driver these chips were using was the &lt;a href=&quot;http://www.realtek.com.tw/products/productsView.aspx?Langid=1&amp;amp;PFid=48&amp;amp;Level=5&amp;amp;Conn=4&amp;amp;ProdID=277&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rtl8192cu&lt;/code&gt;&lt;/a&gt;. Unfortunately these stock drivers do not properly support ad hoc networks.&lt;/p&gt;

&lt;p&gt;The issue seems to lie somewhere with ARP resolution. Basically the driver doesn’t know how to properly go from IP-address to the hardware address on the next layer down. This prevents pretty much all communication on the network. Incoming and outgoing.&lt;/p&gt;

&lt;p&gt;The issue is resolved by adding a static ARP entries using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arp&lt;/code&gt; command. We can make these entries persist between reboots (but not changes in interface state changes).&lt;/p&gt;

&lt;p&gt;Every node in the network has the following interfaces file with a different static IP.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;auto eth0
allow-hotplug eth0
iface eth0 inet manual

auto wlan0
allow-hotplug wlan0
iface wlan0 inet static
    address 192.168.2.xxx # xxx is a statically assigned number from 0 to 255 for each node
    netmask 255.255.255.0
    wireless-channel 1
    wireless-essid RPiwireless
    wireless-mode ad-hoc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In our case each node has an IP address ranging from 192.168.2.177 to 192.168.2.190&lt;/p&gt;

&lt;h3 id=&quot;arp-table&quot;&gt;ARP Table&lt;/h3&gt;

&lt;p&gt;Every interface has its own hardware address that is needed for the low-level communication protocols. If the devices can’t resolve the hardware address they will not be able to communicate. That’s the issue we’re fix with our ARP entries.&lt;/p&gt;

&lt;p&gt;If you run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ifconfig&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ip addr&lt;/code&gt; you can see the HWAddr for each interface.&lt;/p&gt;

&lt;p&gt;Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arp -an&lt;/code&gt; to see your current arp table.&lt;/p&gt;

&lt;p&gt;Turns out you can actually provide the system with some static entries in the ARP table and the network using the following command:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;arp -i _ifname_ -s IP_addr HW_addr
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or you can add entries to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/ethers&lt;/code&gt; file&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;IP_addr1 HW_addr1
IP_addr2 HW_addr2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then run&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo arp -f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arp -f&lt;/code&gt; will populate the table using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/ethers&lt;/code&gt; file by default.&lt;/p&gt;

&lt;p&gt;Example&lt;/p&gt;

&lt;p&gt;Suppose we are on a node A with IP address 192.168.2.190 with HWaddr &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3c:ae:3d:cd:02:b4&lt;/code&gt;. Node B has IP address 192.168.2.200 with HWaddr &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3c:ae:3d:cd:43:8d&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then on Node A we run&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;arp -i wlan0 -s 192.168.2.200 3c:ae:3d:cd:43:8d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then if you run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arp -an&lt;/code&gt; you will see&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;? (192.168.2.200) at 3c:ae:3d:cd:43:8d [ether] PERM on wlan0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then on Node B we run&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;arp -i wlan0 -s 192.168.2.190 3c:ae:3d:cd:02:b4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then if you run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arp -an&lt;/code&gt; you will see&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;? (192.168.2.190) at 3c:ae:3d:cd:02:b4 [ether] PERM on wlan0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once both nodes have their table populated then try to do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ping 192.168.2.190&lt;/code&gt; from node B or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ping 192.168.2.200&lt;/code&gt; from node A and the pings should now be returning with reasonable latencies.&lt;/p&gt;

&lt;h3 id=&quot;more-persistent-entries&quot;&gt;(More) Persistent Entries&lt;/h3&gt;

&lt;p&gt;The issue now become when we had a large network these tables needed to ALWAYS be populated or else communication would fail. The ARP entries do NOT persist after reboot or networking service restarts.&lt;/p&gt;

&lt;p&gt;The easiest way to make entries persist (at least through reboots) is to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/rc.local&lt;/code&gt; file which is a script run at every boot. This allows us to add the entries into the table every time we boot. If the entries get erased or we need to change the interface configuration this means we just have to reboot. On a console-only raspberry pi this process only takes about 15 seconds so we settled for it.&lt;/p&gt;

&lt;p&gt;We chose to add all of our entries to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/ethers&lt;/code&gt; file so we didn’t need to continuously type the commands. Once the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ethers&lt;/code&gt; file was prepared we then edits &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rc.local&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo nano /etc/rc.local&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Just before the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exit 0&lt;/code&gt; line we added &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arp -f&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;arp -f

exit 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Great! Save the file and reboot (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo reboot -h now&lt;/code&gt;). Then after rebooting and logging in type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arp -an&lt;/code&gt; and all of the entries should be present.&lt;/p&gt;

&lt;p&gt;This allowed us to get the ad hoc networks working using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rtl8192cu&lt;/code&gt; driver on linux.&lt;/p&gt;
</description>
        <pubDate>Fri, 17 Mar 2017 00:00:00 +0000</pubDate>
        <link>/blog/research/ad-hoc-arp-entries/</link>
        <guid isPermaLink="true">/blog/research/ad-hoc-arp-entries/</guid>
        
        
      </item>
    
      <item>
        <title>A Beginner&apos;s Guide to Git and Version Control</title>
        <description>&lt;p&gt;&lt;img src=&quot;/assets/images/version-control/Git-logo.svg.png&quot; alt=&quot;Git Logo&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;audience&quot;&gt;Audience&lt;/h2&gt;

&lt;p&gt;This guide hopefully will be useful to students and others who have never used or heard of version control and are interested in using it or incorporating it into their own projects. By the end of this guide readers should have a general idea of how to get started using version control systems and begin to effectively use hosted Git services like GitHub.&lt;/p&gt;

&lt;h2 id=&quot;topics&quot;&gt;Topics&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#what-is-vc&quot;&gt;What is Version Control?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#why-vc&quot;&gt;Why Version Control?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#popular-vc-programs&quot;&gt;Popular Version Control Programs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#a-short-history-of-git&quot;&gt;A Short History of Git&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#intro-to-git&quot;&gt;Introduction to Git&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#installation&quot;&gt;Installation&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#repositories&quot;&gt;Repositories&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#commits&quot;&gt;Commits&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#branches&quot;&gt;Branches&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#checkout&quot;&gt;Checkout&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#merging&quot;&gt;Merging&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#clone-and-pull&quot;&gt;Cloning/Pulling&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#push&quot;&gt;Pushing&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#typical-workflow&quot;&gt;Typical Workflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;-what-is-version-control&quot;&gt;&lt;a id=&quot;what-is-vc&quot;&gt;&lt;/a&gt; What is Version Control?&lt;/h2&gt;

&lt;p&gt;From the Google dictionary&lt;sup&gt;&lt;a href=&quot;#1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;ver·sion con·trol&lt;/strong&gt;, &lt;em&gt;noun&lt;/em&gt; - computing &lt;br /&gt; the task of keeping a software system consisting of many versions and configurations well organized.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Basically by version control is a way that we can keep track of the changes that occur to a software project. Generally it is used for software and related tech, but you could use version control for anything such as writing a paper, an article, or even for a school project. Basically it just gives users a way to make sure that they don’t lose work on an important project. It also allows them preserve the history of anything that they’ve worked on.&lt;/p&gt;

&lt;h2 id=&quot;-why-use-version-control&quot;&gt;&lt;a id=&quot;why-vc&quot;&gt;&lt;/a&gt; Why Use Version Control?&lt;/h2&gt;

&lt;p&gt;There are various reasons that version control is useful. But one of the main, almost obvious, reasons is to be able to keep track of the changes that occur to a project in order to identify rogue behavior and prevent a loss of work.&lt;/p&gt;

&lt;p&gt;There are several other reasons listed here on this &lt;a href=&quot;http://stackoverflow.com/questions/1408450/why-should-i-use-version-control&quot;&gt;Stack Overflow Article&lt;/a&gt;&lt;sup&gt;&lt;a href=&quot;#2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h2 id=&quot;-popular-version-control-programs&quot;&gt;&lt;a id=&quot;popular-vc-programs&quot;&gt;&lt;/a&gt; Popular Version Control Programs&lt;/h2&gt;

&lt;p&gt;Below is a list of popular version control systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: This is not a full list of all version control systems. There many others but I have chosen to highlight some of the more popular ones.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://git-scm.org&quot;&gt;Git&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://subversion.apache.org&quot;&gt;Apache Subversion&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://bazaar.canonical.com/en/&quot;&gt;Bazaar&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.mercurial-scm.org/&quot;&gt;Mercurial&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Git&lt;/strong&gt; - An open source version control system originally designed and developed by the famous Linux Kernel developer, Linus Torvalds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apache Subversion&lt;/strong&gt; - A version control system originally developed by &lt;a href=&quot;http://www.collab.net/&quot;&gt;CollabNet&lt;/a&gt;, but donated to the Apache Software Foundation where it has been top level project since 2010&lt;sup&gt;&lt;a href=&quot;#3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bazaar&lt;/strong&gt; - A version control system which is a part of the GNU project and sponsored by Canonical, the company behind Ubuntu.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mercurial&lt;/strong&gt; - A free open source versioning system with a GNU GPLv2 License. It is implemented with Python and has been since around 2005.&lt;/p&gt;

&lt;h2 id=&quot;-a-short-history-of-git&quot;&gt;&lt;a id=&quot;a-short-history-of-git&quot;&gt;&lt;/a&gt; A Short History of Git&lt;/h2&gt;

&lt;p&gt;Git is one of the most widely used, if not &lt;em&gt;the&lt;/em&gt; most widely used version control system in existence today. Git is a project which was started by Linus Torvalds, the man behind the Linux Kernel. He originally created the project so he could manage contributions to his wildly popular open source operating system kernel.&lt;sup&gt;&lt;a href=&quot;#4&quot;&gt;[4]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;The purpose of git was to be better than the current VCS solutions available at the time. The Linux community had learned its lessons from using other systems while going through development. Torvalds and the community wanted something more reliable and robust than what they had used before. So they based this project “git” around a few main principles&lt;sup&gt;&lt;a href=&quot;#4&quot;&gt;[4]&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Speed&lt;/li&gt;
  &lt;li&gt;Simplicity (Compared to other systems)&lt;/li&gt;
  &lt;li&gt;Support for non-linear and branching development.&lt;/li&gt;
  &lt;li&gt;Completely Distributed&lt;/li&gt;
  &lt;li&gt;Ability to scale with large projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these principles in mind, git was born into existence. Since then it has become a fierce force in the market for version control systems. Companies have been built around it, services have been created, and hundreds of thousands of projects are now hosted online thanks to Git and companies like GitHub.&lt;/p&gt;

&lt;h2 id=&quot;-intro-to-git&quot;&gt;&lt;a id=&quot;intro-to-git&quot;&gt;&lt;/a&gt; Intro To Git&lt;/h2&gt;

&lt;p&gt;In this section we’re going to take a deep dive into git and its features. We’ll do a quick installation guide and then dive into the basic gits concepts.&lt;/p&gt;

&lt;p&gt;From now on, assume that anything like the below block is meant to be run in the command line, such as the bash shell.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;I&apos;m a bash command&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;-git-installation&quot;&gt;&lt;a id=&quot;installation&quot;&gt;&lt;/a&gt; Git Installation&lt;/h3&gt;

&lt;p&gt;Most unix systems will already come with Git installed. However, if not you can run the following commands:&lt;/p&gt;

&lt;p&gt;For Ubuntu/Debian based systems:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;CentOS:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;yum &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Mac OS X/MacOS:&lt;/p&gt;

&lt;p&gt;First you’ll need to &lt;a href=&quot;http://brew.sh&quot;&gt;install homebrew&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;brew &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Windows:&lt;/p&gt;

&lt;p&gt;If you’re on a windows based system you can install git via the &lt;a href=&quot;https://git-scm.org&quot;&gt;git website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://git-scm.com/download/win&quot;&gt;Download Location&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After installing git on windows you should have access to a program called “Git Bash” which will give access to a git command line.&lt;/p&gt;

&lt;p&gt;Git itself is a program on the command line, but it has what we’ll call &lt;strong&gt;subcommands&lt;/strong&gt;. Each subcommand servers its own purpose. Below is a list of the subcommands we’ll be covering and using.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git init&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git status&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git add&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git commit&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git clone&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git pull&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git diff&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git merge&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git checkout&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git branch&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don’t worry too much about what each one means. We’ll go into detail below.&lt;/p&gt;

&lt;h3 id=&quot;-repositories&quot;&gt;&lt;a id=&quot;repositories&quot;&gt;&lt;/a&gt; Repositories&lt;/h3&gt;

&lt;p&gt;So now that we’ve installed git you should keep your command line open. We’ll work off the command line. I’m going to assume you have basic skills in navigating the Unix command line and in creating directories with commands like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mkdir&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;touch&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;echo&lt;/code&gt;, etc..&lt;/p&gt;

&lt;p&gt;Now first let’s go over some of the basic concepts behind git.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Every ‘project’ in git is typically called a &lt;strong&gt;repository&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;A &lt;strong&gt;repository&lt;/strong&gt; is basically a project, or set of code, files, etc. that we want to keep track of and version.&lt;/li&gt;
  &lt;li&gt;Everything that resides within a repository will be tracked by git.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So basically think of a repository as a kind of “special” directory within your file system. Everything within the directory is what will be versioned.&lt;/p&gt;

&lt;p&gt;In order to create a repository we need to run the following command:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git init &amp;lt;REPOSITORY_NAME_HERE&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Alternatively if you want to initialize a repository in the current directory you can simply run&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git init 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What this does is create a special directory within your repository directory called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.git&lt;/code&gt;. This directory keeps track of your repository objects and a bunch of other metadata that is useful for kep track of files.&lt;/p&gt;

&lt;h3 id=&quot;-git-commit&quot;&gt;&lt;a id=&quot;commits&quot;&gt;&lt;/a&gt; Git Commit&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Commits&lt;/strong&gt; define the basic unit of change in a project.&lt;/p&gt;

&lt;p&gt;Every commit defines a set of changes to the repository. You can think of it as a kinda of “&lt;em&gt;delta&lt;/em&gt;”. It basically tells us what changes should be played on top of a repository to go from one commit to the next.&lt;/p&gt;

&lt;p&gt;So if you haven’t already made a repository, create one by running the following commands:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git init hello-git
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;hello-git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So now that we’ve created that we can run this command called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git status&lt;/code&gt;. It will tell us which files might have been changed, or if any new files were added to the repository.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You will probably get an output like the following.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;On branch master

Initial commit

nothing to commit (create/copy files and use &quot;git add&quot; to track)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So the command tells us exactly what’s going on in our repository and what changes may have been made, Note the last instruction “..use “git add” to track”&lt;/p&gt;

&lt;p&gt;So let’s create a new file and add it to our repository.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Hello, World!&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; hello.txt
git status
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Your output should be something like&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;On branch master

Initial commit

Untracked files:
  (use &quot;git add &amp;lt;file&amp;gt;...&quot; to include in what will be committed)

        hello.txt

nothing added to commit but untracked files present (use &quot;git add&quot; to track)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s add our file so that it is &lt;strong&gt;tracked&lt;/strong&gt;. Basically a file being &lt;strong&gt;tracked&lt;/strong&gt; means it’s a file within the repository that should have any changes to it tracked by version control.&lt;/p&gt;

&lt;p&gt;But why wouldn’t you want to track every file? There’s a couple of reasons why you might not want to.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Tracking uneccesary file can make your repository larger than it needs
    &lt;ul&gt;
      &lt;li&gt;This can lead to longer cloning times and lots of useless information&lt;/li&gt;
      &lt;li&gt;Typically you only want to track the files that are 100% necessary to run/compile your code&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Sometimes you want to temporarily use data files in the repository which aren’t necessarily part of the code base.&lt;/li&gt;
  &lt;li&gt;Compiled code should not be tracked.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So now let’s add hello.txt to our tracked files and check the status.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git add hello.txt
git status
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We should then have something like&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;On branch master

Initial commit

Changes to be committed:
  (use &quot;git rm --cached &amp;lt;file&amp;gt;...&quot; to unstage)

        new file:   hello.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Great! So now if we make a commit this file will be tracked.&lt;/p&gt;

&lt;p&gt;Let’s make our first commit. Remember that a &lt;strong&gt;commit&lt;/strong&gt; defines a basic unit of change in a repository. This means that this commit will define the unit of change going from an empty repository to one with a text file named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hello.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;One important note about commits is adding a useful commit message. Code isn’t always readable. And trying to make sense of code after commits can be difficult. Comments in code help, but typically they’re a little too specific.&lt;/p&gt;

&lt;p&gt;A commit message should be short, maybe 30-50 characters which describe the changes that you’re making to a repository. A commit title should be relatively short, but the body of a commit message can be much longer. For now on the command line we’re only going to deal with short commit titles. But one of the most important things about git and tracking changes is having &lt;em&gt;short&lt;/em&gt;, &lt;strong&gt;descriptive&lt;/strong&gt; titles for every commit. Ideally these titles should be completely human readable and easily understandable.&lt;/p&gt;

&lt;p&gt;The most well-engineered pieces of software will typically have great commit messages. I suggest looking at commit messages from commits on the Linux Kernel or from git development itself&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/torvalds/linux/commit/f1a9622037cd370460fd06bb7e28d0f01ceb8ef1&quot;&gt;Sample Linux Kernel Commit&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/git/git/commit/9ed0d8d6e6de7737fe9a658446318b86e57c6fad&quot;&gt;Sample Git Commit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git commit -m &apos;My first git commit: Add hello.txt&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Output should be similar to&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[master (root-commit) f21a1ab] My first git commit: Add hello.txt
warning: LF will be replaced by CRLF in hello.txt.
The file will have its original line endings in your working directory.
1 file changed, 1 insertion(+)
create mode 100644 hello.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Awesome! We’ve now created our repository, added a file, and now we’ve even started tracking changes. From now on, any lines added to the file will result in changes when running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git status&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Try to add some more files on your own or maybe some code too. Don’t forget to write good commit messages! We’ll be moving on to more advanced topics soon. Do your best to play around and use what you’ve learned so far to get comfortable with git and the command line.&lt;/p&gt;

&lt;h3 id=&quot;--git-branches&quot;&gt;&lt;a id=&quot;branches&quot;&gt; &lt;/a&gt; Git Branches&lt;/h3&gt;

&lt;p&gt;So aside from basic units of change, like &lt;strong&gt;commits&lt;/strong&gt;, one of the other fundamental ideas behind version control (for git at least) is the ability to create what we call &lt;strong&gt;branches&lt;/strong&gt; in a repository.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What is a branch?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One of the easiest ways to think of this is that every project has a main code-line, or master &lt;strong&gt;branch&lt;/strong&gt; (sometimes called the &lt;strong&gt;trunk&lt;/strong&gt;). That is the place where every feature gets added. Then using that main code line, you have the ability to create these branches which stem completely from the main code line. It’s like they’re their own mini-repository. They have all of the code and all of the history from the main code line, but the changes end up being detached from the master branch.&lt;/p&gt;

&lt;p&gt;So then why do we have branches?&lt;/p&gt;

&lt;p&gt;Basically branches are a way for individuals to break up pieces of work on a project in a way that they don’t affect the main branch, but can still are able to track the work done on a particular set of files or features without affecting the main code line until the work on the branch is completed. Then finally you want the code from the branch to be merged back into the master branch. The reasoning behind this is that you don’t want broken code or bad features to be merged into the main code line for a project. But you still want to use all of the features of the version control as you work on a specific feature for the project. This way when that feature is completed, it can be tested for errors to make sure that the code is stable before being merged to master.&lt;/p&gt;

&lt;p&gt;So let’s try to create a branch.&lt;/p&gt;

&lt;p&gt;Go into that repository we just made named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hello-git&lt;/code&gt; and run&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git branch my-special-branch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;If you run git status you should notice a line&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  on branch master
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now run&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git branch -v
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You should now see the new branch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my-special-branch&lt;/code&gt;. Next, we’ll show you how to do what is called a &lt;strong&gt;checkout&lt;/strong&gt; of a branch&lt;/p&gt;

&lt;h3 id=&quot;-git-checkout&quot;&gt;&lt;a id=&quot;checkout&quot;&gt;&lt;/a&gt; Git Checkout&lt;/h3&gt;

&lt;p&gt;So at this point we’ve made a new repository named “hello-git” and we’ve also made a new branch alongside master called “my-special-branch”. The issue now is that we made the branch, but we actually can’t make changes on the branch until we do what is called a “checkout” which makes our repository switch over to the copy of the code which the branch uses.&lt;/p&gt;

&lt;p&gt;So let’s run&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git checkout my-special-branch
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Look a special change!!&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; hello.txt
git status
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After running those three commands your git status should be something like&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;On branch my-special-branch
Changes not staged for commit:
  (use &quot;git add &amp;lt;file&amp;gt;...&quot; to update what will be committed)
  (use &quot;git checkout -- &amp;lt;file&amp;gt;...&quot; to discard changes in working directory)

        modified:   hello.txt

no changes added to commit (use &quot;git add&quot; and/or &quot;git commit -a&quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice that to commit any changes we still need to add the file to the staging area. But notice that after the checkout we have the line &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;On branch my-special-branch&lt;/code&gt; meaning our changes are being made to the “my-special-branch”.&lt;/p&gt;

&lt;p&gt;So let’s add the file and make a commit&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git add &lt;span class=&quot;nt&quot;&gt;-A&lt;/span&gt;
git commit &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Adding new special line to hello.txt file&quot;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# Make sure you have a really clear commit message!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Great! We have our changes committed to the second branch.&lt;/p&gt;

&lt;p&gt;Try running&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git checkout master
git status
&lt;span class=&quot;nb&quot;&gt;cat &lt;/span&gt;hello.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you run these commands you should notice that your changes from the my-special-branch didn’t actually carry over to the master branch yet. That’s due to the fact that the code in a separate branch from master is kept separate until you explicity tell git that you want the changes merged into the other branch. That’s what we’ll be going over next in git merge.&lt;/p&gt;

&lt;p&gt;This should at least give you the basics on how to create a branch in git, how to checkout and then make changes, without affecting the rest of the repository. Remember most good project want to keep the commit history on the main code line somewhat clean, but still use the powerful features of version control to save work and keep intermediate versions. That’s what branching is good for. We’ll go over typical git workflows once we learn about merging&lt;/p&gt;

&lt;h3 id=&quot;--git-merge&quot;&gt;&lt;a id=&quot;merging&quot;&gt; &lt;/a&gt; Git merge&lt;/h3&gt;

&lt;p&gt;So at this point our repository has two separate branches, a &lt;strong&gt;master&lt;/strong&gt; and &lt;strong&gt;my-special-branch&lt;/strong&gt;. My special branch has a new change that we want on the master branch. How do we do that? We do it with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git merge&lt;/code&gt; Git merge does exactly what it sounds like. It merges two branches. But to clarify, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git merge&lt;/code&gt; is more like a one-way merge than a two-way merge.&lt;/p&gt;

&lt;p&gt;So what git &lt;strong&gt;doesn’t&lt;/strong&gt; do:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Take two different branches (one of which was branched from an earlier point in time), merge them into a single one and automatically discard the old ones and just leave the new one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What git merge actually does:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Looks at the specified branch, and the current branch. It will look at the history of the branch you’re currently on and find how many commits ago the branch was made.&lt;/li&gt;
  &lt;li&gt;Then it will “replay” the commits (all of the changes) from the other branch onto your current branch and create a new commit on the current branch with a message (if specified).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So in short, it kind of “adds” the history of one branch onto another, thus merging the changes into the new branch with a commit.&lt;/p&gt;

&lt;p&gt;Let’s try it now:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git checkout master
git merge my-special-branch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Voila!&lt;/em&gt; We’ve now officially merged the branch into master.&lt;/p&gt;

&lt;p&gt;You can see the changes by getting the content of the file from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cat&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat hello.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;-cloning-and-pulling&quot;&gt;&lt;a id=&quot;clone-and-pull&quot;&gt;&lt;/a&gt; Cloning and Pulling&lt;/h3&gt;

&lt;p&gt;So one of the ideas around git is that it is &lt;em&gt;designed&lt;/em&gt; to be decentralized. A decentralized system prevents bottlenecks or downtime when cloning code. Not only that but it also means you can grab a copy from the code over the network from anyone’s repository that is available.&lt;/p&gt;

&lt;p&gt;There is no “master” that is &lt;em&gt;required&lt;/em&gt; to always have the latest version of code, and that’s one of the beauties of git. Any copy of the repository which doesn’t exist on the local machine is called a &lt;strong&gt;remote&lt;/strong&gt;. Remotes can be added or removed to a repository and they allow you to push and pull bits of code too and from your repository to other repositories based on the remote configuration.&lt;/p&gt;

&lt;p&gt;So lets jump in to actually grabbing code from another repository:&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;clone&lt;/code&gt; subcommand will attempt to access a hosted repository based on a specified URL. You can use HTTP, HTTPS, or Git protocols.&lt;/p&gt;

&lt;p&gt;Let’s try clone a repository from GitHub.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://github.com/git/hello-world.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Another option:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone git://github.com/git/hello-world.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notice the difference between the protocols &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git://&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note however according to the &lt;a href=&quot;https://git-scm.com/book/ch4-1.html&quot;&gt;git docs&lt;/a&gt; that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git://&lt;/code&gt; protocol is not typically only used for cloning or pulling. It also does not provide any form of authentication.&lt;/p&gt;

&lt;p&gt;Either way, you should get something like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Cloning into &apos;hello-world&apos;...
remote: Counting objects: 158, done.
remote: Total 158 (delta 0), reused 0 (delta 0), pack-reused 158
Receiving objects: 100% (158/158), 17.78 KiB | 0 bytes/s, done.
Resolving deltas: 100% (47/47), done.
Checking connectivity... done.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ls&lt;/code&gt; you should now see a new directory named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hello-world&lt;/code&gt;. This is the directory of the freshly cloned repository. Typically a clone is only performed once. It is for the first time you need to get a repository onto your computer.&lt;/p&gt;

&lt;p&gt;When you clone the repository you automatically get this thing called a &lt;strong&gt;remote&lt;/strong&gt; added to the git metadata. The &lt;strong&gt;remote&lt;/strong&gt; is the &lt;em&gt;origin&lt;/em&gt; location that the repository came from. This will default to  whatever url was used to clone. You can add more remotes by using the command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git remote add&lt;/code&gt;.  Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git remote -h&lt;/code&gt; to see all of the options. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git remote -v&lt;/code&gt; will show all of the push and fetch URLs for each remote.&lt;/p&gt;

&lt;p&gt;One thing that similar to cloning is called &lt;strong&gt;pulling&lt;/strong&gt; using the command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git pull&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Pull is &lt;em&gt;kind of&lt;/em&gt; similar to clone, except for a pull, you need to already be within a repository.&lt;/p&gt;

&lt;p&gt;If you run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git pull -h&lt;/code&gt; you’ll get a help text for the commands.&lt;/p&gt;

&lt;p&gt;The two most common pulls you’ll use are probably&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git pull [remote_name/branchname]&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git pull&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These two commands basically look for any new commits or updates that were on the remote repository, and attempt to replay them on top of your own repository in order to reflect any changes that have been made to the code, making a commit in the process. It’s similar to git merge, except for remote repositories.&lt;/p&gt;

&lt;p&gt;It’s also common to use the  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--rebase&lt;/code&gt; option which runs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git rebase&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git merge&lt;/code&gt;. I suggest looking up the &lt;a href=&quot;https://git-scm.com/docs/git-rebase&quot;&gt;documentation for rebase&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;-git-push&quot;&gt;&lt;a id=&quot;push&quot;&gt;&lt;/a&gt; Git push&lt;/h3&gt;

&lt;p&gt;When working with repositories that may not be located on your machine locally, you’ll need a way to be able to get those remote repositories to reflect the changes you’ve made to your local computer. You’re able to do that with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push&lt;/code&gt; will basically take the current branch you’re working on and push it to your default (or specified remote) and it’s the basic way to make sure any of your changes are replayed into your remote repository to reflect the work that you’ve done.&lt;/p&gt;

&lt;p&gt;It’s relatively simple. Typically you’ll use it if you have remote repositories where you have push access (privileges to change code). Once you get started cloning your own repositories from GitHub you’ll see exactly how to&lt;/p&gt;

&lt;h2 id=&quot;-typical-git-workflow&quot;&gt;&lt;a id=&quot;typical-workflow&quot;&gt;&lt;/a&gt; Typical Git Workflow&lt;/h2&gt;

&lt;p&gt;Below is a basic workflow that you might find:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://myremote/myrepository.git
cd myrepository
git checkout -b feature-123 # creates a new branch
# edit/compile/test
git commit -a -s
# edit/compile/test
git commit -a -s
# You&apos;re finally happy with your changes, merge into new branch
git checkout master
# Make sure we have any new changes from master 
git pull --rebase
git merge feature-123 -m &quot;[Issue-123] - Add special feature&quot;
# Reflect the update in the remote.
git push 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;And that’s it! It’s not too hard to start using. The real challenge is using a tool like git &lt;em&gt;well&lt;/em&gt;. Good use of version control should make rollbacks and upgrades easy as well as differentiating the the software at various points in time. Bad version control could be just as bad and more time consuming as no version control at all! Make sure to do some more reading to brush up on the advanced features and some of the options that you can add to commands which can make git even more powerful&lt;/p&gt;

&lt;p&gt;I &lt;strong&gt;highly highly&lt;/strong&gt; recommend &lt;a href=&quot;https://git-scm.com/docs/&quot;&gt;reading the git documentation&lt;/a&gt; to get a better idea of what some of these commands do. This guide is intended for serious beginners who want to “just get started” without learning much of the technical details. But alas,  there is a high chance you’ll need to know more in the future. The documentation on git is very thorough and I suggest reading through it to gain a better understanding of the functions of git.&lt;/p&gt;

&lt;p&gt;That’s all folks!&lt;/p&gt;

&lt;h4 id=&quot;references&quot;&gt;References&lt;/h4&gt;

&lt;p&gt;&lt;a id=&quot;1&quot; href=&quot;https://www.google.com/search?q=define+version+control&quot;&gt;[1]:&lt;/a&gt; Google Definition of Version Control&lt;br /&gt;
&lt;a id=&quot;2&quot; href=&quot;http://stackoverflow.com/questions/1408450/why-should-i-use-version-control&quot;&gt;[2]:&lt;/a&gt; Reasons to Use Version Control from StackOverflow&lt;br /&gt;
&lt;a id=&quot;3&quot; href=&quot;https://en.wikipedia.org/wiki/Apache_Subversion#History&quot;&gt;[3]:&lt;/a&gt; History of Apache Subversion from Wikipedia&lt;br /&gt;
&lt;a id=&quot;4&quot; href=&quot;https://git-scm.com/book/en/v2/Getting-Started-A-Short-History-of-Git&quot;&gt;[4]:&lt;/a&gt; History of Git&lt;br /&gt;&lt;/p&gt;

</description>
        <pubDate>Sun, 16 Oct 2016 00:00:00 +0000</pubDate>
        <link>/blog/tips/intro-to-git/</link>
        <guid isPermaLink="true">/blog/tips/intro-to-git/</guid>
        
        
      </item>
    
      <item>
        <title>How to Create Your Own Website with GitHub and Jekyll</title>
        <description>&lt;p&gt;This post will serve as a guide on how to create your own website (for free!) using &lt;a href=&quot;pages.github.com&quot;&gt;GitHub Pages&lt;/a&gt; and &lt;a href=&quot;jekyllrb.com&quot;&gt;Jekyll&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;outline&quot;&gt;Outline&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#pre-requisites&quot;&gt;Pre-Requisites&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#the-website-repo&quot;&gt;The Website Repository&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#jekyll-intialization&quot;&gt;Initializing the Jekyll Website&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#basic-customization&quot;&gt;Basic Site Customization &lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#styling-your-site&quot;&gt;Styling your Site (Coming Soon!)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a name=&quot;pre-requisites&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;pre-requisites&quot;&gt;Pre-Requisites&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/join&quot;&gt;Create a GitHub account&lt;/a&gt; if you haven’t already made one.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://desktop.github.com/&quot;&gt;The GitHub Desktop Client&lt;/a&gt; downloaded and installed.
    &lt;ul&gt;
      &lt;li&gt;Make sure that you sign in to your github account with the desktop client.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.google.com/search?q=install+ruby&quot;&gt;Install Ruby&lt;/a&gt; and &lt;a href=&quot;http://jekyllrb.com/docs/installation/&quot;&gt;Jekyll&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a name=&quot;the-website-repo&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;step-1---the-website-repository&quot;&gt;Step 1 - The Website Repository&lt;/h2&gt;

&lt;p&gt;Once you’ve created your GitHub account you’ll need to create a repository which matches the following name:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;username&lt;/em&gt;.github.io&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You should replace &lt;em&gt;username&lt;/em&gt; with your own github username.&lt;/p&gt;

&lt;h4 id=&quot;example&quot;&gt;Example&lt;/h4&gt;

&lt;p&gt;My GitHub username is “zacblanco”. Thus, my repository name is “zacblanco.github.io”&lt;/p&gt;

&lt;p&gt;To create the new repository head to your user account page on GitHub and click the &lt;strong&gt;New&lt;/strong&gt; button under the repositories tab.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/full-website-guide/new-repo.PNG&quot; alt=&quot;New Repo Button&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;jekyll-initialization&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;step-2---initializing-the-jekyll-website&quot;&gt;Step 2 - Initializing the Jekyll Website&lt;/h2&gt;

&lt;p&gt;Once you’ve created the GitHub repository, you’re going to need to clone it onto your own computer. Make sure that you know where the GitHub desktop client is going to clone your repository on your computer.&lt;/p&gt;

&lt;p&gt;You can find this by going to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;Settings &amp;gt; Options &amp;gt; Clone Path&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make note of this location as you’ll need it soon.&lt;/p&gt;

&lt;p&gt;Now open up the GitHub desktop client and clone your newly created repository&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/full-website-guide/clone-repo.PNG&quot; alt=&quot;New Repo Button&quot; /&gt;&lt;/p&gt;

&lt;p&gt;After finishing the clone it should now appear in your desktop client.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/full-website-guide/repo-in-client.PNG&quot; alt=&quot;repo-in-client&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Once you see it in the sidebar, you’ll need to open up a terminal or command prompt window (depending on whether you’re using OS X/Linux or Windows).&lt;/p&gt;

&lt;p&gt;Once you’ve opened you’re terminal window you should &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd&lt;/code&gt; (change directory) into your clone path that you found earlier using the following command:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd /path/to/cloned/repos
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;After executing the command we can then initialize a jekyll site in your repository. Run the following command:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jekyll new username.github.io
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Just remember to replace &lt;strong&gt;username&lt;/strong&gt; with your GitHub account name.&lt;/p&gt;

&lt;p&gt;Congrats! The site should now be initialized.&lt;/p&gt;

&lt;p&gt;Once you’ve intialized the site open up the GitHub desktop client. You should see a list of changes similar to the following:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/full-website-guide/commit-initialization.PNG&quot; alt=&quot;repo-in-client&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You should then do the following things:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Write a short, descriptive commit message&lt;/li&gt;
  &lt;li&gt;Click &lt;strong&gt;Commit to master&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Click &lt;strong&gt;Publish&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each part is circled in red on the image above.&lt;/p&gt;

&lt;p&gt;Awesome! Once you’ve clicked &lt;strong&gt;Publish&lt;/strong&gt; the site is actually live!&lt;/p&gt;

&lt;p&gt;You should be able to see your site at &lt;strong&gt;https://&lt;em&gt;username&lt;/em&gt;.github.io&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you aren’t able to access your site and/or receive a 404 error, you should try the following steps to resolve your issues:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Head into your repository directory
    &lt;ul&gt;
      &lt;li&gt;Do this by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd username.github.io&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Run the command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jekyll build&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If any error messages appear, try to see if you can resolve them using some google-fu (although I would hope no errors arise when simply intializing the repository).&lt;/p&gt;

&lt;p&gt;Once you can access your site via &lt;strong&gt;https://&lt;em&gt;username&lt;/em&gt;.github.io&lt;/strong&gt; you can head to the next step.&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;basic-customization&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;step-3---basic-customization&quot;&gt;Step 3 - Basic Customization&lt;/h2&gt;

&lt;p&gt;Now that our Jekyll site is online we’re going to need to do some customization. This will help you run your site more smoothly and test your site before you push changes to the internet.&lt;/p&gt;

&lt;p&gt;First, you should find a file in the repository titled &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.gitignore&lt;/code&gt; (Create this file if it doesn’t exist).&lt;/p&gt;

&lt;p&gt;Next, add the following line to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.gitignore&lt;/code&gt; file:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_site/*&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Adding this line will prevent you from pushing any local site builds to your repository. This generally helps to minimize clutter.&lt;/p&gt;

&lt;p&gt;Next you should open the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_config.yml&lt;/code&gt; file. You can open this file with any text editor you like. Change the fields to match what you want your site to be about.&lt;/p&gt;

&lt;p&gt;I recommend at minimum changing the following fields to reflect your site:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;title&lt;/li&gt;
  &lt;li&gt;email&lt;/li&gt;
  &lt;li&gt;description&lt;/li&gt;
  &lt;li&gt;url&lt;/li&gt;
  &lt;li&gt;twitter username&lt;/li&gt;
  &lt;li&gt;github username&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; - If you are missing any of the fields, simply just leave them blank. Once you customize your site layout more you can remove them from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_config.yml&lt;/code&gt; file if you wish.&lt;/p&gt;

&lt;p&gt;Once you’ve done that we’re going to test how well the site changes with the configuration changes.&lt;/p&gt;

&lt;p&gt;Use your terminal and navigate into your &lt;strong&gt;username.github.io&lt;/strong&gt; directory and run the following command:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;jekyll serve
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Jekyll will now try to build your site and serve it locally. You can access it (only on your computer) with the address &lt;a href=&quot;http://127.0.0.1:4000&quot;&gt;http://127.0.0.1:4000&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/full-website-guide/example-customization.PNG&quot; alt=&quot;Site Customization Example&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The last thing you should do here is look in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_posts&lt;/code&gt; folder and delete the pre-generated posts that are in there. However, do make note of the metadata which is at the top of the file. You’ll need something similar to it later.&lt;/p&gt;

&lt;p&gt;I also &lt;a href=&quot;https://help.github.com/categories/customizing-github-pages/&quot;&gt;highly recommend GitHub’s guide to customizing your pages site&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this point it’s imperative that you familiarize yourself with Jekyll’s features and documentation as well as GitHub pages’ features as well. Below is a curated list of links to some of what I believe to be the most important information about Jekyll.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://jekyllrb.com/docs/home/&quot;&gt;What is Jekyll&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://jekyllrb.com/docs/usage/&quot;&gt;Basic Jekyll Usage&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://jekyllrb.com/docs/structure/&quot;&gt;Jekyll Site Structure&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://jekyllrb.com/docs/configuration/&quot;&gt;Jekyll Configuration&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://jekyllrb.com/docs/frontmatter/&quot;&gt;Post Frontmatter&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://jekyllrb.com/docs/pages/&quot;&gt;Creating Additional Pages&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://jekyllrb.com/docs/variables/&quot;&gt;Jekyll Variables&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://jekyllrb.com/docs/themes/&quot;&gt;Themes with Jekyll&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://jekyllrb.com/docs/troubleshooting/&quot;&gt;Troubleshooting Jekyll&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After giving the above links a quick skim you should be up to speed on everything jekyll and can get to customizing your site in the next step!&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;styling-your-site&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;styling-your-site-coming-soon&quot;&gt;Styling Your Site (Coming Soon!)&lt;/h2&gt;

</description>
        <pubDate>Fri, 13 May 2016 00:00:00 +0000</pubDate>
        <link>/blog/jekyll/create-your-own-website-with-github/</link>
        <guid isPermaLink="true">/blog/jekyll/create-your-own-website-with-github/</guid>
        
        
      </item>
    
      <item>
        <title>Social Psychology Exam 3 Guide</title>
        <description>&lt;hr /&gt;

&lt;p&gt;This guide has moved!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/education/social-psychology/notes-3/&quot;&gt;Click here to go to the new page&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 29 Nov 2015 00:00:00 +0000</pubDate>
        <link>/blog/social-psychology/exam-guide-three/</link>
        <guid isPermaLink="true">/blog/social-psychology/exam-guide-three/</guid>
        
        
      </item>
    
      <item>
        <title>Computer Science Jokes</title>
        <description>&lt;p&gt;Sometimes the stress of school really just gets to you. Don’t forget to laugh every once in a while. Here’s a list of jokes I’ve collected over some time.&lt;/p&gt;

&lt;h2 id=&quot;non-decimal-number-systems&quot;&gt;Non-Decimal Number Systems&lt;/h2&gt;

&lt;p&gt;Well, I couldn’t really leave these out…&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;There are only 10 types of people in the world: those who understand binary, and those who don’t.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;There are 10 types of people in the world: those who know binary, those who don’t, and those who didn’t expect this joke to be in base 3.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;unix-scripting&quot;&gt;Unix Scripting&lt;/h2&gt;

&lt;p&gt;I like to live on the edge:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[ $[ $RANDOM % 6] == 0 ] &amp;amp;&amp;amp; rm -rf /* || echo Click&lt;/code&gt;&lt;br /&gt;
credit: StackOverflow user &lt;strong&gt;mxc&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;hardware&quot;&gt;Hardware&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Q&lt;/strong&gt;: How many programmers does it take to change a lightbulb&lt;br /&gt;
&lt;strong&gt;A&lt;/strong&gt;: None, that’s a hardware problem!&lt;br /&gt;
credit: StackOverflow User &lt;strong&gt;Steven A. Lowe&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;networking&quot;&gt;Networking&lt;/h2&gt;

&lt;p&gt;I would tell you a joke about UDP, but you might not get it…&lt;br /&gt;
credit: reddit user &lt;strong&gt;/u/Portaljacker&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;object-oriented-programming&quot;&gt;Object Oriented Programming&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Q&lt;/strong&gt;: “Whats the object-oriented way to become wealthy?”&lt;br /&gt;
&lt;strong&gt;A&lt;/strong&gt;: Inheritance&lt;br /&gt;
credit to StackOverflow user &lt;strong&gt;spelchec&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer&lt;/em&gt;: These are not mine, and I may have modified them slightly. I have credited jokes from where I have found them on the interwebs :)&lt;/p&gt;

</description>
        <pubDate>Fri, 06 Nov 2015 00:00:00 +0000</pubDate>
        <link>/blog/computer-science-jokes/</link>
        <guid isPermaLink="true">/blog/computer-science-jokes/</guid>
        
        
      </item>
    
      <item>
        <title>Social Psychology Exam 2 Guide</title>
        <description>&lt;p&gt;This page has moved to the education section!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/education/social-psychology/notes-2/&quot;&gt;Click here to go to the new page&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 01 Nov 2015 00:00:00 +0000</pubDate>
        <link>/blog/social-psychology/exam-2/</link>
        <guid isPermaLink="true">/blog/social-psychology/exam-2/</guid>
        
        
      </item>
    
  </channel>
</rss>
