<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Project Page</title>
    <description>The latest articles on Forem by Project Page (@projectpage).</description>
    <link>https://forem.com/projectpage</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F1203%2Fa08ebd80-6d03-41ec-9d98-709ab4fcb698.jpg</url>
      <title>Forem: Project Page</title>
      <link>https://forem.com/projectpage</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/projectpage"/>
    <language>en</language>
    <item>
      <title>How to go back to a previous commit in git</title>
      <dc:creator>Kenny Grant</dc:creator>
      <pubDate>Mon, 23 Sep 2019 07:16:19 +0000</pubDate>
      <link>https://forem.com/projectpage/how-to-go-back-to-a-previous-commit-in-git-16o8</link>
      <guid>https://forem.com/projectpage/how-to-go-back-to-a-previous-commit-in-git-16o8</guid>
      <description>&lt;p&gt;Have you ever accidentally committed the wrong files to git, but you hadn't pushed your commit up to origin yet and just want to tidy up? &lt;/p&gt;

&lt;p&gt;All is not lost, it's quite easy to recover from this, though the commands to do so are not very intuitive. Unfortunately git doesn't have an undo command, however you can undo this quite easily using git reset. &lt;/p&gt;

&lt;p&gt;If you want to add some files or edit the commit message, you can use git commit with the amend option:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;commit&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;amend&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will add whatever changes you have queued up to the previous commit (for example you may have seen a typo in your comments for the commit), and it will also let you edit the commit message for the previous commit. &lt;/p&gt;

&lt;p&gt;If you want to get rid of the commit, while keeping the changes to your files, use git reset with HEAD~ to indicate the previous commit or a commit hash to go back to a specific commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;reset&lt;/span&gt; &lt;span class="no"&gt;HEAD&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will perform a reset of the git index (but not the changes themselves). So your files will still be as you had them, but the git index will be reset, and you can start your commit again (making modifications, not adding all the files etc). It's as if your previous commit just didn't happen. &lt;/p&gt;

&lt;p&gt;If you committed changes that you just want to throw away, and you don't want to keep at all, you can also do a hard reset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;reset&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;hard&lt;/span&gt; &lt;span class="no"&gt;HEAD&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Or if you want to get rid of a few commits, the last commit hash you want to keep:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;reset&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;hard&lt;/span&gt; &lt;span class="n"&gt;a1b2c3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But &lt;em&gt;beware, this could delete or change files&lt;/em&gt;, and will reset the state of all the files to the previous commit, so use it with care. Usually you're better doing a soft reset. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Only ever do this if you haven't pushed the commits to origin.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;If you have published the commit, you should instead publish another reverting commit, instead of rewriting history (which can cause other people lots of problems). &lt;/p&gt;

</description>
      <category>git</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to move a commit to another branch in git</title>
      <dc:creator>Kenny Grant</dc:creator>
      <pubDate>Fri, 20 Sep 2019 16:07:47 +0000</pubDate>
      <link>https://forem.com/projectpage/how-to-move-a-commit-to-another-branch-in-git-4lj4</link>
      <guid>https://forem.com/projectpage/how-to-move-a-commit-to-another-branch-in-git-4lj4</guid>
      <description>&lt;p&gt;Here's a little git problem that happened to me today, which used to be quite scary when I was first learning git but is actually easy to remedy as long as you are working locally. &lt;/p&gt;

&lt;p&gt;We've all done it - sometimes you forget you haven't created a branch yet, or worse yet you're on the wrong feature branch, and you start adding some code and make a commit. Then you realise you've committed code to the wrong feature branch or straight to master, and now it's in the wrong place. &lt;/p&gt;

&lt;p&gt;As long as you haven't pushed your changes up to origin, this is very easy to undo. Let's say we have made a commit a1b2c3d on the branch feature-a, and we haven't yet made a feature-b branch. &lt;/p&gt;

&lt;p&gt;So first of all we want to get our commit onto the right branch, so let's take a note of the hash want to move, and start at master:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;git checkout master
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Optionally (if we don't have the branch yet) we make a new branch feature-b to put it on and check it out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;git checkout -b feature-b
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then make sure you are on the right branch feature-b (may not be necessary if you just created it), and cherry pick this commit into that branch to add just that commit to feature-b:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;git checkout feature-b
git cherry-pick a1b2c3d
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And finally let's reset feature-a branch back to the previous commit hash (say z1b2c3d). Using git reset --hard will remove all the commit referencing the changes, and all the changes themselves, from feature-a branch, while leaving that commit on feature-b:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;git checkout feature-a
git reset --hard z1b2c3d
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can do this with multiple commits too, just cherry pick several, then reset back to the last commit you want to keep. The process is the same if you have committed to local master by mistake - just cherry-pick to a branch, then reset master. &lt;/p&gt;

&lt;p&gt;Only ever do this if you haven't pushed the commits to origin. &lt;/p&gt;

</description>
      <category>git</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Just for func</title>
      <dc:creator>Kenny Grant</dc:creator>
      <pubDate>Thu, 19 Sep 2019 20:42:40 +0000</pubDate>
      <link>https://forem.com/projectpage/just-for-func-541j</link>
      <guid>https://forem.com/projectpage/just-for-func-541j</guid>
      <description>&lt;p&gt;If you missed the first episode of this series about Learning Go, you should start at the beginning (see the link above).&lt;/p&gt;

&lt;p&gt;Today we're going to have fun with functions. First though, I must apologise for stealing the title of today's lesson from renowned gopher &lt;a href="https://twitter.com/francesc"&gt;Francesc Campoy&lt;/a&gt;, who made a a really fun series of podcasts called &lt;a href="https://www.youtube.com/channel/UC_BzFbxG2za3bp5NRRRXJSw"&gt;Just for Func&lt;/a&gt; - once you're a little further along with Go, you should watch them all for another perspective on the language. &lt;/p&gt;

&lt;p&gt;As well as looking at go functions today, we'll learn three new keywords:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;const&lt;/em&gt; - a value that doesn't change&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;var&lt;/em&gt; - a value that may change&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;return&lt;/em&gt; - leave a function and give the caller some output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've used another language in the C family you'll probably be familiar with all of these. Let's start where we left off, with function main, but we'll try adding another function which we can call from main. We declare functions with the func keyword which we saw last time, and declare constants with const and variables with var (though often in Go this isn't necessary, as you'll see later). &lt;/p&gt;

&lt;p&gt;We're going to define a function to find the position of a number in pi:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// piPosition finds the first location of a given number in pi&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;piPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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



&lt;p&gt;This uses func to declare a function called piPosition (note the camel case, that's what we use in Go), which takes a number of type int (integer), and returns an integer representing the index of this number in pi.&lt;/p&gt;

&lt;p&gt;The full code is below or &lt;a href="https://play.golang.org/p/h82XuiWFaJL"&gt;here&lt;/a&gt; - we declare a constant for pi (note there is no type assigned, this is implied) - you can read more about the reasons for allowing this on the go blog about &lt;a href="https://blog.golang.org/constants"&gt;constants&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;We then declare an integer number, add one to it, skip past some commented out code (which is there to show you what you &lt;em&gt;can't&lt;/em&gt; do - try uncommenting it and see what happens), and call the function piPosition. piPosition is an odd and rather useless little function which finds the index, but it'll show us how functions work in Go and how to use return. Inside piPosition, we convert both pi and number (53 in this case) to strings, and find the index of the number within pi (you can find most numbers within pi if you look long enough). &lt;/p&gt;

&lt;p&gt;There's one interesting problem here though - if you choose to use the specifier %f within printf (to convert pi to a float), you'll get no result for 53, because pi will be truncated to the size of number that would fit into a float type. This tells us something interesting - the pi constant declaration turns it into something other than float.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Package main compares strings&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="c"&gt;// These are the packages imported by this program&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"strings"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// A constant cannot be changed during program execution&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;pi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;3.141592653589793238462643383279502884&lt;/span&gt;

&lt;span class="c"&gt;// the entry point for the program&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c"&gt;// A variable stores a value that may change&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;52&lt;/span&gt;

    &lt;span class="c"&gt;// We can change number, but not pi&lt;/span&gt;
    &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;

    &lt;span class="c"&gt;// This is a compile error, try uncommenting to see&lt;/span&gt;
    &lt;span class="c"&gt;// go is a compiled language and will not allow you to&lt;/span&gt;
    &lt;span class="c"&gt;// compile a program which does a Bad Thing like this&lt;/span&gt;
    &lt;span class="c"&gt;// pi = 52&lt;/span&gt;

    &lt;span class="c"&gt;// We also can't assign a string to a number, try this to see &lt;/span&gt;
    &lt;span class="c"&gt;// number = "string"&lt;/span&gt;

    &lt;span class="c"&gt;// Let's call the function piPosition &lt;/span&gt;
    &lt;span class="c"&gt;// and assign its return value to index&lt;/span&gt;
    &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;piPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Print something with a format - see Printf for more details.&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The number %d is at position %d in pi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// piPosition finds the index in pi &lt;/span&gt;
&lt;span class="c"&gt;// (as a string) of a given number&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;piPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// We're going to cheat and use strings&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// A quick search in the standard library docs &lt;/span&gt;
    &lt;span class="c"&gt;// turns up this function to find the index in a string&lt;/span&gt;
    &lt;span class="c"&gt;// let's return this as an answer from the function, &lt;/span&gt;
    &lt;span class="c"&gt;// using the return keyword&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note when we call piPosition, we assign the result to a variable without using var, or even a type. This is how you can implicitly create new variables in Go, and it's handy so you'll see this a lot. The variable type is set by the return type of the function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;    &lt;span class="c"&gt;// Let's call the function piPosition &lt;/span&gt;
    &lt;span class="c"&gt;// and assign its return value to index&lt;/span&gt;
    &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;piPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can try out today's code here &lt;a href="https://play.golang.org/p/h82XuiWFaJL"&gt;https://play.golang.org/p/h82XuiWFaJL&lt;/a&gt; - note the clever URL created as a hash (a unique string which maps to only this content). This is the sort of clever thing you'll learn to do later in the course, in order to impress your friends and confound your enemies. &lt;/p&gt;

&lt;p&gt;Yes, I'm using &lt;a href="https://golang.org/pkg/fmt"&gt;fmt&lt;/a&gt; to convert numbers to strings, and comparing numbers as strings, experienced go programmers don't @ me :)  You can also use the &lt;a href="https://golang.org/pkg/strconv"&gt;strconv&lt;/a&gt; package in the standard library for this, but I would like to keep things simple. If you work out why the %f specifier &lt;a href="https://play.golang.org/p/UEQ1BnARlqi"&gt;won't work&lt;/a&gt;, and what type pi ends up being, post it in the comments below - floating point numbers are notoriously tricky.&lt;/p&gt;

&lt;p&gt;So to recap, we've covered these 6 keywords so far: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;package&lt;/em&gt; - a folder containing go files&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;import&lt;/em&gt; - a way of importing go packages including the &lt;a href="https://golang.org/pkg/#stdlib"&gt;standard library&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;func&lt;/em&gt; - this stands for &lt;a href="https://en.wikipedia.org/wiki/Function_(mathematics)"&gt;function&lt;/a&gt;, a set of instructions for transforming data&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;const&lt;/em&gt; - a value that doesn't change&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;var&lt;/em&gt; - a value that may change&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;return&lt;/em&gt; - leave a function and give the caller some output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Only 19 to go before you're an expert! In the next lesson we'll learn how to set up a web server in a few lines of code using the excellent Go standard library, and a few more keywords too, and we'll be on the way to making &lt;del&gt;the next twitter&lt;/del&gt; something at 53words.com. &lt;/p&gt;

&lt;p&gt;If you haven't already, you should &lt;a href="https://golang.org/dl/"&gt;download go&lt;/a&gt; and get set up locally with your editor - you can use this hello world exercise to test it out on your computer. I recommend VS Code as an editor on a Mac, but there are many other editors and most have go support. There are lots of &lt;a href="https://www.google.com/search?q=how+do+I+install+golang"&gt;instructions&lt;/a&gt; on the web for installation, I won't go into it here. &lt;/p&gt;

</description>
      <category>go</category>
      <category>tutorial</category>
      <category>gofunc</category>
    </item>
    <item>
      <title>Let's build something and learn go at the same time</title>
      <dc:creator>Kenny Grant</dc:creator>
      <pubDate>Wed, 18 Sep 2019 21:41:31 +0000</pubDate>
      <link>https://forem.com/projectpage/let-s-build-something-and-learn-go-at-the-same-time-31hh</link>
      <guid>https://forem.com/projectpage/let-s-build-something-and-learn-go-at-the-same-time-31hh</guid>
      <description>&lt;p&gt;Hi, I'm Kenny, and I write Go code for a living and run &lt;a href="https://golangnews.com"&gt;golangnews.com&lt;/a&gt;, a news website for Go programmers, as a hobby. I've been using Go for a while and thought I'd write some tutorials to show other people how awesome it is. &lt;/p&gt;

&lt;p&gt;Follow along to learn go and build something awesome while you do it. &lt;/p&gt;

&lt;p&gt;This course is an introduction to the &lt;a href="https://dev.toGo%20programming%20language"&gt;Go programming language&lt;/a&gt; from Google. I'll try not to assume too much knowledge - even if you haven't done much programming before, it should be approachable with a little effort, so please ask questions in the comments below if you're unsure on any points, or think things haven't been explained well. I'm going to try a post every few days over the next few months, and by the end you should be proficient in Go and have a server up for yourself, so follow along if you'd like to learn the language in bite-size chunks.&lt;/p&gt;

&lt;p&gt;Why would you want to learn Go? Go is ideal for writing internet servers - it powers many internet services we take for granted; it's used by companies as varied as Youtube, Monzo, Ironio, SendGrid, GitLab and Digital Ocean.&lt;/p&gt;

&lt;p&gt;To keep us motivated, we're going to build something real - let's build a better twitter while we learn go (ignoring scaling concerns for now, we'll just keep it simple - one program, one server). I'm going to put it here: &lt;a href="http://53words.com"&gt;53words.com&lt;/a&gt;. We'll get that server up and running in just a few lessons.&lt;/p&gt;

&lt;p&gt;There is nothing at this domain at present, at the end of the course we'll have a better twitter (with fewer adverts, nazis and dank memes), it may also involve the number 53 somehow. So let's go! &lt;/p&gt;

&lt;p&gt;First, we need to learn Go. It has just 25 &lt;a href="https://golang.org/ref/spec#Keywords"&gt;keywords&lt;/a&gt;, which are a good place to start. Here are our first three keywords:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;package&lt;/em&gt; - this is the basic &lt;a href="https://golang.org/ref/spec#Packages"&gt;unit of code&lt;/a&gt; in go, you can think of it as synonymous with folder - a folder on your computer is a package in go&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;import&lt;/em&gt; - this lets you import packages/folders of code from elsewhere, including the &lt;a href="https://golang.org/pkg/#stdlib"&gt;standard library&lt;/a&gt; of code provided by the Go authors. &lt;/li&gt;
&lt;li&gt;
&lt;em&gt;func&lt;/em&gt; - this stands for &lt;a href="https://en.wikipedia.org/wiki/Function_(mathematics)"&gt;function&lt;/a&gt;, a set of instructions for transforming data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So packages/folders contain files which contain functions which transform data.  &lt;/p&gt;

&lt;p&gt;You don't have to install anything yet, to get started, we'll use &lt;a href="https://play.golang.org/p/jKrWXZvT3B4"&gt;play.golang.org&lt;/a&gt; - this is an interactive go website that lets you execute go programs from your browser. If you open that link, you'll find this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Package main is the entry point of your program&lt;/span&gt;
&lt;span class="c"&gt;// the first and only function in your program called by the operating system&lt;/span&gt;
&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="c"&gt;// import lets you import lots of packages&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c"&gt;// fmt is a package for reading and writing stuff (mostly text)&lt;/span&gt;
    &lt;span class="c"&gt;// you can use it to print things out (as below)&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// func then a name defines a function&lt;/span&gt;
&lt;span class="c"&gt;// main is the first and only function called from outside&lt;/span&gt;
&lt;span class="c"&gt;// after that, you're on your own&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c"&gt;// fmt.Println writes the things you give it to standard output&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"World"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The quote marks above define strings (human words), we'll go into types and the different built in types in Go in the next tutorial. Let's try making a change here - add your name in quotes and print it out instead of "World", then press Run at the top to see the result below. &lt;/p&gt;

&lt;p&gt;Back yet? Great. If you printed your name, let's try something else, add the number 53 and the text "words" at the end of the Println function and see what you get, so something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"World"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Kenny"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;53&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Words"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You'll find that &lt;a href="https://golang.org/pkg/fmt/#Println"&gt;Println&lt;/a&gt; prints most things you throw at it (even numbers or other types of thing), because it does some tricks to format every thing in the right way. &lt;/p&gt;

&lt;p&gt;Any questions? Let me know in the comments below. You can run the final code for this lesson at &lt;a href="https://play.golang.org/p/8NrBnO0s1M5"&gt;play.golang.org&lt;/a&gt; without leaving your browser. &lt;/p&gt;

</description>
      <category>go</category>
      <category>tutorial</category>
      <category>gofunc</category>
    </item>
    <item>
      <title>A short history of the Stripe Status Page</title>
      <dc:creator>Kenny Grant</dc:creator>
      <pubDate>Tue, 17 Sep 2019 07:31:07 +0000</pubDate>
      <link>https://forem.com/projectpage/a-short-history-of-the-stripe-status-page-4cnl</link>
      <guid>https://forem.com/projectpage/a-short-history-of-the-stripe-status-page-4cnl</guid>
      <description>&lt;p&gt;When Stripe was founded in 2018, stripe.com featured just one sentence – Payment processing for developers, and a single link. Stripe have grown from this simple page to a valuation of billions and a reputation for cutting edge design – using radically simple design and software to help customers navigate complex payment flows.&lt;/p&gt;

&lt;p&gt;The stripe status page is a great example of design in the service of clear communication, which delivers exactly what the reader needs and nothing more. Today we're going to look at the elements they chose to include on their status page, and why it works so well.&lt;/p&gt;

&lt;h1&gt;
  
  
  The first status page at Stripe
&lt;/h1&gt;

&lt;p&gt;The first stripe status page at status.stripe.com was created in 2012 by Amber Feng, then an engineer in her first few weeks at Stripe – she now heads Financial Infrastructure at the billion dollar company. &lt;/p&gt;

&lt;p&gt;The first page was not responsive (responsive web design not being a mainstream idea at the time), but otherwise was very similar in content and style to the page we see today. It has a global indicator at top, and then a list of services with historical uptime below, and at the bottom a feed from the twitter account which was used to tweet out status updates in the event of an outage. From the post: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We built color-coded charts that show 90-day availability in Stripe’s three core services: the site, the API, and Stripe.js. We also show the raw uptime figures, calculated over the same three-month period. To calculate the figures, we use Pingdom to monitor each service, effectively performing a complete API request in the case of the API."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The original page: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pkDjz5Ay--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/c58it05uv1g9qk5d0yfa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pkDjz5Ay--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/c58it05uv1g9qk5d0yfa.jpg" alt="Stripe Status"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Pingdom for status checks
&lt;/h1&gt;

&lt;p&gt;This first page was updated via checks from pingdom – an interesting case of avoiding building out a separate checker service when an external one was available which was good enough – this let them build the first status page quickly and see if it was something they wanted to invest more time in later. It was a small company of around 10 people and this was her first task:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"When I first joined Stripe, we were tiny – I interviewed with everyone at the company! Without the lure or credibility of Stripe’s reputation or brand, what really attracted me to the company was the team." – Amber Feng&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Contrast with AWS
&lt;/h1&gt;

&lt;p&gt;The Amazon AWS status page provides a good counterpoint to the stripe status page. It is manually updated, non-responsive (so hard to read on phones), and hugely complex. There is no overall status and no grouping of services in a logical order, just an interminable list of services and regions. It's so long that I couldn't even take a representative screenshot, and at the top of the page is a wall of text that nobody visiting it wants to read. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KqHSfdDK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fn64ayucg3472q1uia4h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KqHSfdDK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/fn64ayucg3472q1uia4h.jpg" alt="AWS Status"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The new status page
&lt;/h1&gt;

&lt;p&gt;Stripe started with the smallest thing that could possibly work, and a very simple page, and it has served them well to this day. Their latest status page looks very like the original, what is most remarkable is how little has changed since the original design, which is a testament to its thoughtful simplicity:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LRIiDETr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/mbgvygux3a63p2x2ejlg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LRIiDETr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/mbgvygux3a63p2x2ejlg.jpg" alt="Stripe 2019"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The design is so good that competing services have been heavily inspired by it. Statuspage.io, founded in 2012, offers a very similar view, clearly inspired by the stripe design to break down status by service and show the historical uptime as green or red bars summarising status per day.&lt;/p&gt;

&lt;p&gt;You can read a longer article with more detail and images in the full &lt;a href="https://projectpage.app/case-studies/status/stripe-status"&gt;case study&lt;/a&gt; over at Project Page, or read more on &lt;a href="https://twitter.com/projpage/status/1173851829899354117"&gt;twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>startup</category>
      <category>stripe</category>
      <category>statuspage</category>
    </item>
    <item>
      <title>How to use git branches</title>
      <dc:creator>Kenny Grant</dc:creator>
      <pubDate>Mon, 16 Sep 2019 21:06:57 +0000</pubDate>
      <link>https://forem.com/projectpage/how-to-use-git-branches-3641</link>
      <guid>https://forem.com/projectpage/how-to-use-git-branches-3641</guid>
      <description>&lt;p&gt;There are lots of possible workflows for git, but the simplest one is in my experience also the most effective, and works from small teams to very large ones at Google and Facebook. This is sometimes known as trunk based development and I'll explain how it works below. &lt;/p&gt;

&lt;h1&gt;
  
  
  Trunk based development
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;There is one main branch - usually called master.&lt;/li&gt;
&lt;li&gt;This is always green on tests and never broken. &lt;/li&gt;
&lt;li&gt;All new changes are based off master&lt;/li&gt;
&lt;li&gt;There are no separate merge commits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Master/Head can be used as the base for all new changes, and is regularly updated as changes are released by developers. All developers have commit access, and the social contract is such that master is never broken. It can be used as a working release and for internal testing or development, and all new work is based off master. There may be release branches (used for back-porting bug fixes for example), and locally devs use feature branches for changes.&lt;/p&gt;

&lt;p&gt;All new changes are based off master, and are usually done in a feature branch, though if small they may be worked on directly. When the change has been tested locally and is ready to go, it is rebased off master (optionally with some commits squashed and tidied up), it is then merged into master, resulting in a simple linear history on master of all work done, with tags to denote different releases. As a result, the master branch looks like this (example taken from the go language project at Google): &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bH4JORSI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/bguf8d6gta31qu0zqem3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bH4JORSI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/bguf8d6gta31qu0zqem3.png" alt="Go Repo Master"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are no merge commits, and no long-lived branches (apart from optional release branches, which exist to back-port bug fixes).&lt;/p&gt;

&lt;p&gt;So the process for developing and committing code is: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pull latest origin/master &lt;/li&gt;
&lt;li&gt;Rebase feature branch off master&lt;/li&gt;
&lt;li&gt;Make changes to feature branch&lt;/li&gt;
&lt;li&gt;Run tests on feature&lt;/li&gt;
&lt;li&gt;When ready, share for code review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The developer may go through several cycles of this process as the code goes through code review. The process for final merging is: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pull latest origin/master &lt;/li&gt;
&lt;li&gt;Rebase feature off master, squashing if required&lt;/li&gt;
&lt;li&gt;Run tests&lt;/li&gt;
&lt;li&gt;Merge into origin/master &lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Release Branches
&lt;/h1&gt;

&lt;p&gt;Release branches on the go project for example, look like this: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9PzyJ-OF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9jospkcaydp212j4h08z.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9PzyJ-OF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9jospkcaydp212j4h08z.jpg" alt="Go Release Branch"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A branch off master at the time of the original release, which holds any new commits specific to that release. These can then be used for bug fix releases to that older code if required (typically on larger projects). Most smaller projects won't have to bother with this and can just get away with tagging releases. &lt;/p&gt;

&lt;h1&gt;
  
  
  Alternatives
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Feature Branches
&lt;/h3&gt;

&lt;p&gt;Feature branches can actually be used with trunk based development as well, and often are locally while working on changes, but this style of using git has one important difference - it requires merge commits for merging feature branches in. &lt;/p&gt;

&lt;p&gt;Some people like this because it gives a clear indication of when a branch has been checked in, and can make it easier to revert all changes from a branch. &lt;/p&gt;

&lt;p&gt;I prefer to drop the historical artefacts which are branches and branch names and instead let commit comments speak for themselves in the history. &lt;/p&gt;

&lt;p&gt;It means the repository can end up looking like a particularly kafkaesque subway map: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2hAbdm6E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9dwnd5dm1pq9bt17dqyj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2hAbdm6E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9dwnd5dm1pq9bt17dqyj.png" alt="Feature Branches"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Gitflow
&lt;/h3&gt;

&lt;p&gt;Another alternative is sometimes known as git flow - this suits a style of development where work continues on development versions of software over weeks or months, which are then after a long time merged onto master as releases. It is not very well suited if you want to practice continuous delivery and release small features frequently. It can be summarised by the following graphic: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Bdef9if5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/3x55vv7dviuhjnwg7ffr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Bdef9if5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/3x55vv7dviuhjnwg7ffr.jpg" alt="Git Flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which tells you everything you need to know about gitflow. Image from nvie.com. &lt;/p&gt;

&lt;h3&gt;
  
  
  Github workflow
&lt;/h3&gt;

&lt;p&gt;Github has introduced an interesting take on using git which requires users to clone (fork) repos, make all their changes, and then submit a pull request back to the original repo. &lt;/p&gt;

&lt;p&gt;This does allow developers who have no access to the original repo to work on the code, and submit suggested changes, hence its popularity with open source projects and on github. The downsides are that it may mean changes are worked on in isolation without discussion with the original maintainer, then submitted as a large dump all at once.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I think if you have full control over your development process, it is simpler and more productive to use the trunk based development model, as it lets you release frequently and keep master up to date at all times, and results in a clean git history which is easy to read, and is free of artefacts from the development process. This system works well at the scale of Google as well as for small teams.&lt;/p&gt;

&lt;p&gt;You can find out more about how Google use git in this &lt;a href="https://cacm.acm.org/magazines/2016/7/204032-why-google-stores-billions-of-lines-of-code-in-a-single-repository/fulltext"&gt;article&lt;/a&gt;, or by contributing to one of their open source projects like the &lt;a href="https://golang.org/"&gt;Go Language&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>git</category>
    </item>
  </channel>
</rss>
