<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>JohnVonNeumann</title><link href="http://johnvonneumann.com/" rel="alternate"></link><link href="http://johnvonneumann.com/feeds/all.atom.xml" rel="self"></link><id>http://johnvonneumann.com/</id><updated>2020-03-10T00:00:00+11:00</updated><entry><title>My end-to-end Git Workflow</title><link href="http://johnvonneumann.com/end-to-end-git-workflow.html" rel="alternate"></link><published>2020-03-10T00:00:00+11:00</published><updated>2020-03-10T00:00:00+11:00</updated><author><name>JohnVonNeumann</name></author><id>tag:johnvonneumann.com,2020-03-10:/end-to-end-git-workflow.html</id><summary type="html">&lt;p&gt;My git flow, not git-flow.&lt;/p&gt;</summary><content type="html">&lt;p&gt;From master branch, to make sure you have a clean copy of your codebase, first, ensure you're on master:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;branch&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The output should be similar to this, with the "&lt;em&gt;" next to &lt;/em&gt;master*:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;aaa1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;lint&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;makefiles&lt;/span&gt;
    &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;
    &lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;terraform&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;automation&lt;/span&gt;
    &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;yamllint&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ci&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;step&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;If your asterisk is positioned next to a different branch, you can return to the &lt;em&gt;master branch&lt;/em&gt; with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;checkout&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now that you are on &lt;em&gt;master&lt;/em&gt;, you can branch into a feature branch for local development:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;checkout&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_code&lt;/span&gt;&lt;span class="err"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;issue_number&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;short&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You will be prompted with your new branch name, otherwise you can re-run the first step to ensure you're now on the correct branch. Now you can continue your development.&lt;/p&gt;
&lt;p&gt;When you have made an edit to a file, you will need to &lt;em&gt;stage&lt;/em&gt; the change, this indicates to &lt;em&gt;git&lt;/em&gt; that you wish to package it into a &lt;em&gt;patch&lt;/em&gt; and introduce it to the codebase. Firstly though, we can check what changes are available for staging by running:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This will give us output detailing the current state of our local environment, showing a potential combination of &lt;em&gt;tracked&lt;/em&gt; and &lt;em&gt;untracked&lt;/em&gt; files.&lt;/p&gt;
&lt;p&gt;Untracked files are files which have not been &lt;em&gt;checked into&lt;/em&gt; our version control system. For example, if you have just created a new file, and have not &lt;em&gt;committed&lt;/em&gt; that file into the code base.&lt;/p&gt;
&lt;p&gt;Tracked files are files that have been checked into the version control system.&lt;/p&gt;
&lt;p&gt;In this scenario, as we have not added anything, the above command will return:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="k"&gt;On&lt;/span&gt; &lt;span class="n"&gt;branch&lt;/span&gt; &lt;span class="n"&gt;aaa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;branch&lt;/span&gt;
    &lt;span class="k"&gt;nothing&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;working&lt;/span&gt; &lt;span class="n"&gt;tree&lt;/span&gt; &lt;span class="n"&gt;clean&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Lets say we add a file to the repository, we wish to commit this file, first, we perform some work on the file.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;touch&lt;/span&gt; &lt;span class="n"&gt;example_file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;We now verify that the file is in the repository and git is aware of it.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The output of which is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="nv"&gt;On&lt;/span&gt; &lt;span class="nv"&gt;branch&lt;/span&gt; &lt;span class="nv"&gt;aaa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;example&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;branch&lt;/span&gt;
    &lt;span class="nv"&gt;Untracked&lt;/span&gt; &lt;span class="nv"&gt;files&lt;/span&gt;:
    &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;use&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s"&gt;git add &amp;lt;file&amp;gt;...&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="nv"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;what&lt;/span&gt; &lt;span class="nv"&gt;will&lt;/span&gt; &lt;span class="nv"&gt;be&lt;/span&gt; &lt;span class="nv"&gt;committed&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;

    &lt;span class="nv"&gt;example_file&lt;/span&gt;.&lt;span class="nv"&gt;py&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now that we've confirmed git is aware of our file, we can stage it. With the name of your file, run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="n"&gt;example_file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;We can now check whether the file has been staged with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You will receive output similar to this, indicating that the file is now ready to be committed, if this is the first time you have committed a particular file, it will state that it is a &lt;em&gt;new file:&lt;/em&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;Changes&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="k"&gt;committed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;use&lt;/span&gt; &lt;span class="ss"&gt;&amp;quot;git reset HEAD &amp;lt;file&amp;gt;...&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;unstage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You can now commit the change. Committing something is basically to package it into a change, and add it as a piece of work, consider it &lt;em&gt;git&lt;/em&gt;'s primary data unit, repositories are built up of hundreds or thousands of commits, each telling part of a story of a project.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This will spawn a new window in the text editor specified in your git settings, allowing you to leave a message to go along with the commit.&lt;/p&gt;
&lt;p&gt;Commit messages should help tell a story, the &lt;em&gt;git log&lt;/em&gt; will live for the length of the solution, and should enable other engineers to understand how the code was written and in some cases, why it was written the way it was. A good git log helps engineers create a better solution, by providing them with valuable context to utilise in their day to day engineering.&lt;/p&gt;
&lt;p&gt;A good structure to use for commit messages is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;{UPDATE, DELETE, CREATE} - A verb to describe at a high level what you are doing in this commit, for example you may be adding an entirely new file, so you may choose to start your message with "CREATE".&lt;/li&gt;
&lt;li&gt;The file name you are impacting - This should be the file name of the file being worked upon, we may be creating the new python file, &lt;em&gt;example_file.py&lt;/em&gt; so we can set this to "example_file.py"&lt;/li&gt;
&lt;li&gt;A dash to separate the header of the message from the description to come.&lt;/li&gt;
&lt;li&gt;A short description to tell the reader from a high level what/why you are doing. For example, "example script for git how-to blog". Ideally, this should be kept to under 78 characters, otherwise it will wrap in the ggit log and be harder for engineers to read.&lt;/li&gt;
&lt;li&gt;Finally, underneath this, we add an extended explanation, after performing a double carriage return, this extended message will not show in the short log, only in the full log, so we can be more elaborate in our explanation of the change here, ultimately we wish to detail why we are performing the change, any interesting context around this change (Were their issues, Is this a workaround for a bug in a vendor software?), be detailed in your message. For example: "In order to explain the example git workflow in the how to guide, I had to create an example file with an add/commit workflow along with a simple way to understand the best way to set out a commit message. This change will illustrate an example that will assist developers craft better commit messages."&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This leaves us with a final commit message of:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="nv"&gt;CREATE&lt;/span&gt; &lt;span class="nv"&gt;example_file&lt;/span&gt;.&lt;span class="nv"&gt;py&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;  &lt;span class="nv"&gt;example&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;git&lt;/span&gt; &lt;span class="nv"&gt;how&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;

    &lt;span class="nv"&gt;In&lt;/span&gt; &lt;span class="nv"&gt;order&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;explain&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;example&lt;/span&gt; &lt;span class="nv"&gt;git&lt;/span&gt; &lt;span class="nv"&gt;workflow&lt;/span&gt; &lt;span class="nv"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;how&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;guide&lt;/span&gt;, &lt;span class="nv"&gt;I&lt;/span&gt;
    &lt;span class="nv"&gt;had&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;create&lt;/span&gt; &lt;span class="nv"&gt;an&lt;/span&gt; &lt;span class="nv"&gt;example&lt;/span&gt; &lt;span class="nv"&gt;file&lt;/span&gt; &lt;span class="nv"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;an&lt;/span&gt; &lt;span class="nv"&gt;add&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;commit&lt;/span&gt; &lt;span class="nv"&gt;workflow&lt;/span&gt; &lt;span class="nv"&gt;along&lt;/span&gt; &lt;span class="nv"&gt;with&lt;/span&gt;
    &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="nv"&gt;simple&lt;/span&gt; &lt;span class="nv"&gt;way&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;understand&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;best&lt;/span&gt; &lt;span class="nv"&gt;way&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;out&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="nv"&gt;commit&lt;/span&gt; &lt;span class="nv"&gt;message&lt;/span&gt;.
    &lt;span class="nv"&gt;This&lt;/span&gt; &lt;span class="nv"&gt;change&lt;/span&gt; &lt;span class="nv"&gt;will&lt;/span&gt; &lt;span class="nv"&gt;illustrate&lt;/span&gt; &lt;span class="nv"&gt;an&lt;/span&gt; &lt;span class="nv"&gt;example&lt;/span&gt; &lt;span class="nv"&gt;that&lt;/span&gt; &lt;span class="nv"&gt;will&lt;/span&gt; &lt;span class="nv"&gt;assist&lt;/span&gt; &lt;span class="nv"&gt;developers&lt;/span&gt;
    &lt;span class="nv"&gt;craft&lt;/span&gt; &lt;span class="nv"&gt;better&lt;/span&gt; &lt;span class="nv"&gt;commit&lt;/span&gt; &lt;span class="nv"&gt;messages&lt;/span&gt;.
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Type in your message, ensuring that you keep your subject line shorter than 50 characters and your body lines shorter than 72 characters otherwise the comments will not line wrap and people reading the git log will have an awkward time reading.&lt;/p&gt;
&lt;p&gt;Now that we have written out our commit, we can save it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;wq&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Our output will look something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    [&lt;span class="nv"&gt;aaa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;example&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;branch&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="nv"&gt;b20c8a&lt;/span&gt;] &lt;span class="nv"&gt;CREATE&lt;/span&gt; &lt;span class="nv"&gt;example_file&lt;/span&gt;.&lt;span class="nv"&gt;py&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;  &lt;span class="nv"&gt;example&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;git&lt;/span&gt; &lt;span class="nv"&gt;how&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;
     &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nv"&gt;file&lt;/span&gt; &lt;span class="nv"&gt;changed&lt;/span&gt;, &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nv"&gt;insertions&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;, &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nv"&gt;deletions&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
     &lt;span class="nv"&gt;create&lt;/span&gt; &lt;span class="nv"&gt;mode&lt;/span&gt; &lt;span class="mi"&gt;100644&lt;/span&gt; &lt;span class="nv"&gt;example_file&lt;/span&gt;.&lt;span class="nv"&gt;py&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;We can now check whether our commit was created with another call to status, if the commit has been created, we will not receive any additional output than we did from our original call to git status at the start of the guide:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;However, if we check the git log, we will see our commit at the HEAD of the chain:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Returning:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="nv"&gt;commit&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="nv"&gt;b20c8aada7ae3c97fed086ab00e86d0312224fe&lt;/span&gt; &lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;HEAD&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;aaa&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;test&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;example&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;Author&lt;/span&gt;: &lt;span class="nv"&gt;JohnVonNeumann&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;louiswillcock&lt;/span&gt;@&lt;span class="nv"&gt;gmail&lt;/span&gt;.&lt;span class="nv"&gt;com&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nv"&gt;Date&lt;/span&gt;:   &lt;span class="nv"&gt;Thu&lt;/span&gt; &lt;span class="nv"&gt;Oct&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;:&lt;span class="mi"&gt;31&lt;/span&gt;:&lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="mi"&gt;2019&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1100&lt;/span&gt;

    &lt;span class="nv"&gt;CREATE&lt;/span&gt; &lt;span class="nv"&gt;example_file&lt;/span&gt;.&lt;span class="nv"&gt;py&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;  &lt;span class="nv"&gt;example&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;git&lt;/span&gt; &lt;span class="nv"&gt;how&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;

    &lt;span class="nv"&gt;In&lt;/span&gt; &lt;span class="nv"&gt;order&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;explain&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;example&lt;/span&gt; &lt;span class="nv"&gt;git&lt;/span&gt; &lt;span class="nv"&gt;workflow&lt;/span&gt; &lt;span class="nv"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;how&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;guide&lt;/span&gt;, &lt;span class="nv"&gt;I&lt;/span&gt;
    &lt;span class="nv"&gt;had&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;create&lt;/span&gt; &lt;span class="nv"&gt;an&lt;/span&gt; &lt;span class="nv"&gt;example&lt;/span&gt; &lt;span class="nv"&gt;file&lt;/span&gt; &lt;span class="nv"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;an&lt;/span&gt; &lt;span class="nv"&gt;add&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;commit&lt;/span&gt; &lt;span class="nv"&gt;workflow&lt;/span&gt; &lt;span class="nv"&gt;along&lt;/span&gt; &lt;span class="nv"&gt;with&lt;/span&gt;
    &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="nv"&gt;simple&lt;/span&gt; &lt;span class="nv"&gt;way&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;understand&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;best&lt;/span&gt; &lt;span class="nv"&gt;way&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;out&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="nv"&gt;commit&lt;/span&gt; &lt;span class="nv"&gt;message&lt;/span&gt;.
    &lt;span class="nv"&gt;This&lt;/span&gt; &lt;span class="nv"&gt;change&lt;/span&gt; &lt;span class="nv"&gt;will&lt;/span&gt; &lt;span class="nv"&gt;illustrate&lt;/span&gt; &lt;span class="nv"&gt;an&lt;/span&gt; &lt;span class="nv"&gt;example&lt;/span&gt; &lt;span class="nv"&gt;that&lt;/span&gt; &lt;span class="nv"&gt;will&lt;/span&gt; &lt;span class="nv"&gt;assist&lt;/span&gt; &lt;span class="nv"&gt;developers&lt;/span&gt;
    &lt;span class="nv"&gt;craft&lt;/span&gt; &lt;span class="nv"&gt;better&lt;/span&gt; &lt;span class="nv"&gt;commit&lt;/span&gt; &lt;span class="nv"&gt;messages&lt;/span&gt;.
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This shows that we have indeed committed our change, the only issue is that it only exists on our local repository, in order to tell our source of truth about it, the remote; we must &lt;em&gt;push&lt;/em&gt; the code.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;push&lt;/span&gt; &lt;span class="n"&gt;origin&lt;/span&gt; &lt;span class="n"&gt;branch&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now that our change is in our remote branch, in order to have this change integrated into the master branch we must issue a &lt;em&gt;merge request&lt;/em&gt; or a &lt;em&gt;pull request&lt;/em&gt; depending on the platform you're currently using to support git.&lt;/p&gt;
&lt;p&gt;This will typically be done via the GUI, so we can navigate to there to issue the merge request, you can search online to find out how to do this.&lt;/p&gt;
&lt;p&gt;By this stage, it will be assumed that you have received the correct number of approvals for your branch and new code, so you can proceed to get the thing merged.&lt;/p&gt;
&lt;p&gt;We position ourselves onto the local branch we are working on, use the processes mentioned up above, in this example we are going to assume that inside the &lt;em&gt;master&lt;/em&gt; branch there are commits that have been merged since we started developing our code, as this will be the trickiest situation to deal with.&lt;/p&gt;
&lt;p&gt;Once you are located on the branch, you can &lt;em&gt;pull&lt;/em&gt; the changes from master into your branch, which will add changes and place them onto your branch, effectively removing the need for dirty merge commits that clog up the git log.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;pull&lt;/span&gt; &lt;span class="c1"&gt;--rebase origin master&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;We can assert that the changes have been pulled into our branch with our handy friend &lt;em&gt;git log&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Finally, now that the changes from remote master are in your local branch, you can push them upto your remote branch, however, as you have pulled in changes from elsewhere and performed a rebase, your remote branch will complain that the tip of your local branch is &lt;em&gt;behind&lt;/em&gt; the remote. This is incorrect, we are ahead, so we need to &lt;em&gt;force&lt;/em&gt; the changes upon the remote.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;push&lt;/span&gt; &lt;span class="n"&gt;origin&lt;/span&gt; &lt;span class="n"&gt;branch&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="c1"&gt;--force-with-lease&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Finally, you can either migrate back to the GUI and use the button to merge the code, or you can do it from your terminal if you have the privileges to merge code.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="k"&gt;fetch&lt;/span&gt; &lt;span class="n"&gt;origin&lt;/span&gt;
    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;checkout&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;
    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;merge&lt;/span&gt; &lt;span class="n"&gt;branch&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
    &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;push&lt;/span&gt; &lt;span class="n"&gt;origin&lt;/span&gt; &lt;span class="n"&gt;master&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</content><category term="engineering"></category><category term="devops"></category><category term="automation"></category><category term="sysadmin"></category><category term="development"></category><category term="git"></category></entry><entry><title>Repository Design</title><link href="http://johnvonneumann.com/repository-design.html" rel="alternate"></link><published>2019-08-04T00:00:00+10:00</published><updated>2019-08-04T00:00:00+10:00</updated><author><name>JohnVonNeumann</name></author><id>tag:johnvonneumann.com,2019-08-04:/repository-design.html</id><summary type="html">&lt;p&gt;Changing the way we think about repository UX.&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Changing the way we think about repository UX.&lt;/h2&gt;
&lt;p&gt;Since I started working in software, and more specifically, "DevOps", I have had to work with a smorgasbord of irregular repositories. They have varied in every way you can imagine, much of the time with relative impunity.&lt;/p&gt;
&lt;p&gt;No one likes working with repositories like this. They are dirty and downright depressing in some instances, to move from a "clean" repository with good quality CI/CD, automation and quality control, into an old and crusty repository, without these things, feels wrong. I will make the generalisation that when people work in one of these "forsaken" repositories, they tend to work to a much lower level of quality than they might usually, because the state of the repository, does not inspire the need to work to a high level of quality. This is a problem.&lt;/p&gt;
&lt;h3&gt;Broken Windows Theory&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;The broken windows theory is a criminological theory that states that visible signs of crime, anti-social behaviour, and civil disorder create an urban environment that encourages further crime and disorder, including serious crimes. The theory suggests that policing methods that target minor crimes such as vandalism, public drinking, and fare evasion help to create an atmosphere of order and lawfulness, thereby preventing more serious crimes.&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I believe that the broken windows theory exists within software. I believe that human operators; software engineers, will instinctively checkout of good quality work if the environment they are working in has "visible signs of crime, anti-social behaviour, and civil disorder". It's a fairly understandable reaction.&lt;/p&gt;
&lt;p&gt;The reasons for such "lawlessness" are enumerate, timelines, resources, laziness and general bad work, lack of knowledge/ignorance to better ways of doing work, lack of good quality tooling, etc. There are a host of bogeyman that can be used to blame this situation on.&lt;/p&gt;
&lt;h3&gt;Programming has had a definition of "good" for a while now&lt;/h3&gt;
&lt;p&gt;There is so much content out there surrounding general software engineering and what constitutes good quality code that in many ways, we have developed a natural sense for what can be considered good quality. We "walk" into a codebase, and can see the hallmarks of greatness, and conversely, the hallmarks of a dumpster fire. This is endemic, it occurs without us considering it, we look at a codebase and say "this is garbage", we have developed a keen sense for garbagism and what its ugly little offspring look like. This is good.&lt;/p&gt;
&lt;p&gt;Programming actually has a number of frameworks to support good quality code creation, and these frameworks are the logical backing that provides us our quick reflex "garbage identification". Extreme Programming, 12 Factor Application Design, Clean Code. All great examples of the work that has been put into creating good quality, well backed theory, to support the creation of good quality software engineering output.&lt;/p&gt;
&lt;h3&gt;So where is ours?&lt;/h3&gt;
&lt;p&gt;Despite programmers (I mean this in the traditional Operations-Development sense) having had this structure and overall definition of "good work" for a relatively large amount of time, the DevOps space in many ways seems to struggle with the idea of taking some of this and relaying it into our own space.&lt;/p&gt;
&lt;p&gt;We still struggle to (from my experience) standardise what a "good repository" should look like, with deltas in implementation occurring across organisations everywhere. This problem is only amplified with the shift to SaaS based git hosting, where new repositories cost nothing to create and more organisations move to multi-repository set-ups.&lt;/p&gt;
&lt;p&gt;Personally, I am tired of having to enter a repository and add a gitignore with the basic ignores, add a CI file that'll largely look the same within the same language ecosystem, and I'm definitely tired of having to keep either a mental check-list of repository actions or consult a README file, then copy pasta the directives across, hoping they work.&lt;/p&gt;
&lt;h3&gt;Enter "Repository Design"&lt;/h3&gt;
&lt;p&gt;My thoughts around how to fix this issue have started to fall under my own mental banner of "Repository Design", which I use as a way of thinking about what the best practice for a repository should be and how we as developers can go about designing good quality repositories.&lt;/p&gt;
&lt;p&gt;I personally believe that the repository should be viewed in many ways as a product, a shippable that is self contained and can be quantified in terms of its quality. As we encounter a heavier push towards automation/infrastructure as code, it is important to highlight the delivery mechanism for this code, and having a publicly understood "API" for a repository, should help push us towards better automation. I also believe that repository automation is an area ripe for improvement, with massive gains to be achieved through simple adjustments in repository work flows.&lt;/p&gt;
&lt;p&gt;An important distinction of Repository Design is the focus on the overall User Experience of a repository.&lt;/p&gt;
&lt;h3&gt;How easily can a repository be used?&lt;/h3&gt;
&lt;p&gt;In many cases where large scale automation is done well, many people shy away from using the end product to its fullest potential what can be extremely complicated automation if they feel they either don't understand it or do not possess the skills to fix fuck ups if they occur. In many ways, a defining feature of good quality automation is that it is typically low maintenance once it is in place. You've already automated the task, so in many cases, the automation may sit chugging along for months, sometimes years, untouched, before human eyes gaze over it again. In my experience, the easiest way to detract value and usage from your otherwise perfect automation solutions is to not pay close enough attention to the very real human operators that will be using it.&lt;/p&gt;
&lt;p&gt;As a simple example of the type of high level goals of Repository Design consider your local development environment:&lt;/p&gt;
&lt;p&gt;It is most likely a 16GB+ machine, with plenty of free compute and zero network latency (to yourself), yet we consistently push all menial linting tasks off your local environment and onto a remote CI/CD server. How much time is lost in the process of creating the commits, sending them to your git hosting provider, having the build picked up, initialisation of a build agent, then it fails because you used a tab instead of a space.&lt;/p&gt;
&lt;p&gt;Repository Design does not seek to remove CI/CD or anything of the kind, it simply seeks to allow developers to use the resources they have, properly, to enable better workflows for everyone involved. We wish to keep all the tasks that can be done locally, within the current CI/CD process, but also bring what we can internal, to quicken the feedback loops of development.&lt;/p&gt;
&lt;h3&gt;No need for new tooling&lt;/h3&gt;
&lt;p&gt;The best thing about this situation is that in a large amount of situations, we have no real need for newer tooling.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Repository Action/API Automation - Makefiles&lt;/li&gt;
&lt;li&gt;Automated Code Edit Automation - Githooks&lt;/li&gt;
&lt;li&gt;Stable, repeatable linting - Docker with Linters&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This list is to continue being fleshed out, but for the time being I'll leave this where it is.&lt;/p&gt;
&lt;p&gt;Older tooling, re-purposed with additional wrapping can provide great solutions to existing, boring problems, that for the most part are theoretically solved, but not in an automated fashion.&lt;/p&gt;
&lt;p&gt;In some cases, it's not even that you need complicated automation, but a tool that generated simple basic default gitignore files would be a godsend, how many times have you gone into a repository littered with garbage like &lt;code&gt;.DS_Store&lt;/code&gt; files, that a coworker hasn't put in the &lt;code&gt;.gitignore&lt;/code&gt; but have now been committed into the repository? I know I've fixed this numerous times. And the main issue with this?&lt;/p&gt;
&lt;p&gt;It's fucking boring.&lt;/p&gt;
&lt;p&gt;No one likes doing stuff like this, but if you are an engineer with high standards, eventually, with enough time spent in one repository, these bugs will get under your skin and you'll want to fix them.&lt;/p&gt;
&lt;p&gt;So you do fix it. And the world is good. Then you go to another repository...&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I'll be putting together some ideas/tooling around this in the months to come, I think these issues have bounced around inside my head long enough now that I've finally decided to automate these garbage tasks so I can focus on personally higher value work, this is what automation is about, moving humans towards higher value work.&lt;/p&gt;
&lt;p&gt;I've been building a simple tool I'm calling &lt;code&gt;pstart&lt;/code&gt;, and will have a simple "beta" release available soon when I have around 3 of the core features delivered. It's a simple tool that will allow for contextual repository management, regardless of the stage of life the repository currently exists in. I hope for it to be a way for automation folks (and everyone else) to take back some of their jobs, and usher in a more sensible way of thinking about repositories. As usual, it'll be opinionated, but it will also be Open Source. So feel free to make a pull. It's unit tested and all that, so I intend for it to be a good quality production.&lt;/p&gt;
&lt;p&gt;Keep an eye on my Github at: https://github.com/JohnVonNeumann&lt;/p&gt;
&lt;p&gt;Cheers for reading.&lt;/p&gt;</content><category term="sysadmin"></category><category term="automation"></category><category term="devops"></category><category term="engineering"></category></entry></feed>