{"id":350,"date":"2015-04-17T13:46:26","date_gmt":"2015-04-17T13:46:26","guid":{"rendered":"http:\/\/drsfenner.org\/blog\/?p=350"},"modified":"2015-04-17T13:46:44","modified_gmt":"2015-04-17T13:46:44","slug":"yagd-yet-another-git-demo-2","status":"publish","type":"post","link":"https:\/\/drsfenner.org\/blog\/2015\/04\/yagd-yet-another-git-demo-2\/","title":{"rendered":"(YAGD) Yet Another Git Demo"},"content":{"rendered":"<p><br \/>\n\n\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>There are many, many git tutorials out there. http:\/\/rogerdudler.github.io\/git-guide\/ is pretty cool and gives a nice overview. However, it doesn't quite set you up to <em>play around<\/em> with the commands. Here is a completely self-contained walk-through that doesn't require any networking to experiment with a reasonable git setup. <!--more--><\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>Let's work through a simple scenario where two friends (Mark and Barb) want to hack on some code together. Since they are both jet-setting around the country and typically working from laptops, they decide to setup a central repository for their code base. (<em>Note: These days, you can do that on github in about 45 seconds.<\/em>) We're going to simulate the three computers (Barb's laptop, Mark's laptop, and the central repository server) on one physical computer. There's no fundamental difference from using physically remote machines: you'd had to setup the networking support (typically using ssh\/sshd) and authentication (public\/private keys) and you'd specify the remote machine when executing commands.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>Without further ado (about nothing), let's create a pseudo-laptop and create an initial (empty) code base:<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">%<\/span> mkdir marks_code <span class=\"co\"># I just spun up a new computer -- didn&#39;t you see it?<\/span>\n<span class=\"kw\">%<\/span> cd marks_code    <span class=\"co\"># and logged on<\/span>\n<span class=\"kw\">%<\/span> git init .       <span class=\"co\"># create a git repo here; currently empty<\/span>\n<span class=\"kw\">Initialized<\/span> empty Git repository in \/Users\/mfenner\/gitdemo\/marks_code\/.git\/<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>Now, since we know we want to use git, we can use git to create an initial repository that isn't keeping track of anything (yet). We do this with the <code>git init<\/code> command. Incidentally, to get help on this command (on Unix-y systems), type <code>man git-init<\/code>. <code>git<\/code> is structured as &quot;one big program&quot; with lots of sub-commands (<code>git init<\/code>, <code>git log<\/code>, <code>git diff<\/code>, etc.), but the man pages (help documentation) are made for each command. You specify it as <code>git-&lt;cmd&gt;<\/code> for whatever command <code>cmd<\/code> you want to investigate.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>Ok, let's populate the code base.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">%<\/span> cat <span class=\"kw\">&gt;<\/span> test.py\n<span class=\"kw\">print<\/span> <span class=\"st\">&quot;Hello World!&quot;<\/span><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>And we can commit that file into the repository. Currently, the file exists on the hard drive, but the reposiotry knows nothing about it. Let's tell the repository it exists (by <code>adding<\/code> it). First, we can take a look at what <code>git<\/code> knows about with <code>git status<\/code>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">%<\/span> git status\n<span class=\"kw\">On<\/span> branch master\n\n<span class=\"kw\">Initial<\/span> commit\n\n<span class=\"kw\">Untracked<\/span> files:\n  <span class=\"kw\">(use<\/span> <span class=\"st\">&quot;git add &lt;file&gt;...&quot;<\/span> to include in what will be committed<span class=\"kw\">)<\/span>\n\n    <span class=\"kw\">test.py<\/span>\n\n<span class=\"kw\">nothing<\/span> added to commit but untracked files present (use <span class=\"st\">&quot;git add&quot;<\/span> to track)<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>Notice how helpful git is. It tells you that you can use <code>git add<\/code> to add a file. Let's do it:<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">%<\/span> git add test.py\n<span class=\"kw\">%<\/span> git status        <span class=\"co\"># git will also tell you how to &quot;unadd&quot; test.py<\/span><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>At this point, we've told git that we care about this file, but we have actually committed the file into the repository\/history. Here goes:<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">%<\/span> git commit -m <span class=\"st\">&quot;Added hello world functionality&quot;<\/span><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>I used <code>-m<\/code> to specify the commit message (a note about what the reason for this current commit). If you don't put something in there, git will dump you into an editor and let you type a message in. Now would be a great time to try out: <code>git log<\/code>, <code>git show<\/code>, and <code>git blame<\/code>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>Fair enough. Now we could have Barb do a magic git command <code>git clone &lt;path\/to&gt;\/marks_code<\/code> and she would get a (standalone) copy of the repository. There are two issues with this approach:<\/p>\n<ul>\n<li>We would have to do some &quot;magic&quot; to let <em>me<\/em> request changes from her, because she cloned me without my involvement. She could send me changes, but I couldn't drive that process. This isn't a show stopper: you'll see a command in a second that would let us do a bi-directional hook up of our repos (phew, that sounds steamy).<\/li>\n<li>A bigger issue is that neither of us is working on a server\/workstation computer. That is, we aren't working from a fixed location. And, our machines will randomly blip on and off the Internet as we do some work, take a flight, go to sleep, etc. When our computers go &quot;dark&quot; the other person literally can't send or request updates.<\/li>\n<\/ul>\n<p>To resolve these issues, we'll use a &quot;central repository&quot; that we both communicate with. This also gives us an offsite backup for free, if you are using github or the equivalent. Note, my mockup demo here is not offsite (I sincerely hope I didn't have to tell you that)!<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">%<\/span> cd ..           <span class=\"co\"># go up one level (out of marks_code)<\/span>\n<span class=\"kw\">%<\/span> mkdir central   <span class=\"co\"># create a server<\/span>\n<span class=\"kw\">%<\/span> cd central      <span class=\"co\"># and login  (ha, easy!)<\/span>\n<span class=\"kw\">%<\/span> git init --bare <span class=\"co\"># create a special type of repository<\/span>\n                  <span class=\"co\"># that won&#39;t be used by anyone locally<\/span><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>Now, let's feed the new central repository. First, let's see who Mark's repo is setup to communicate with:<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">%<\/span> cd ..\/marks_code    <span class=\"co\"># go back to mark&#39;s laptop<\/span>\n<span class=\"kw\">%<\/span> git remote -v       <span class=\"co\"># who are my remote connections (currently none!)<\/span><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>I'm not connected to anyone else (sad face). Let's hook me up to the central repo for both pushing and pulling -- that is, sending and receiving updates to the repo.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">%<\/span> git remote add origin \/Users\/mfenner\/gitdemo\/central   <span class=\"co\"># link the repos<\/span>\n<span class=\"kw\">%<\/span> git push --set-upstream origin master                  <span class=\"co\"># link the master branches<\/span>\n                                                         <span class=\"co\"># (and send my repo as an update)<\/span><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>Now, we can tell Barb about the &quot;central server&quot; and she can make her own copy of it.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">%<\/span> cd ..\n<span class=\"kw\">%<\/span> mkdir barbs_code <span class=\"kw\">&amp;&amp;<\/span> <span class=\"kw\">cd<\/span> barbs_code\n<span class=\"kw\">%<\/span> git clone \/Users\/mfenner\/gitdemo\/central\n<span class=\"co\"># cloning creates the tailing directory name and puts the repo in it<\/span>\n<span class=\"kw\">%<\/span> cd central\n<span class=\"kw\">%<\/span> git log --oneline<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>Very often, when you are adding new stuff, you do it in a &quot;branch&quot;. Why?<\/p>\n<ul>\n<li>It helps keep new\/different code isolated.<\/li>\n<li>It let's you keep <code>master<\/code> as a (hopefully) 100% working version of the code.<\/li>\n<li>It makes a record of when and how new features were added to the code.<\/li>\n<\/ul>\n<p>Enough talk, let's fight. Here, we're working as Barb.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">%<\/span> git branch               <span class=\"co\"># view current branches<\/span>\n<span class=\"kw\">%<\/span> git branch add-function  <span class=\"co\"># create a new branch called ... and activate it<\/span>\n<span class=\"kw\">%<\/span> git branch\n\n<span class=\"co\"># update test.py and testmod.py<\/span>\n<span class=\"kw\">%<\/span> cat <span class=\"kw\">&gt;<\/span> testmod.py\n<span class=\"kw\">def<\/span> foo(x,y)<span class=\"kw\">:<\/span>\n    <span class=\"kw\">return<\/span> x + y\n<span class=\"kw\">%<\/span> more test.py\n<span class=\"kw\">from<\/span> testmod import foo\n\n<span class=\"kw\">%<\/span> print <span class=\"st\">&quot;Hello World!&quot;<\/span>\n<span class=\"kw\">%<\/span> print foo(3,5)\n\n<span class=\"co\"># Now, get those changes stored away!<\/span>\n<span class=\"kw\">%<\/span> git add testmod.py\n<span class=\"kw\">%<\/span> git commit -a       <span class=\"co\"># -a does &quot;auto-add stuff git knows about&quot;<\/span>\n\n<span class=\"co\"># Now, switch back to the boring, old master<\/span>\n<span class=\"kw\">%<\/span> git branch master\n<span class=\"kw\">%<\/span> ls   <span class=\"co\"># why is testmod.pyc around?  <\/span>\n     <span class=\"co\"># it is &quot;just&quot; a file on the disk, git doesn&#39;t know about it<\/span>\n\n<span class=\"co\"># merge our new functionality (after testing, of course!)<\/span>\n<span class=\"kw\">%<\/span> git merge add-function    <span class=\"co\"># merge named branch onto current branch<\/span>\n<span class=\"kw\">%<\/span> git status                <span class=\"co\"># barb&#39;s gotten ahead of the remote master<\/span>\n<span class=\"kw\">%<\/span> git push\n\n<span class=\"co\"># Barb can also clean up the (no longer needed) development branch<\/span>\n<span class=\"kw\">%<\/span> git branch -d add-function<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>So, I (Mark) have been sleeping (!) and I wake up and want to start coding. Before I do anything else, I see if the repo has been updated -- I try to grab any work that Barb did overnight. Easy as pie:<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">%<\/span> git pull<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>I was asleep and I'm still a bit groggy. I haven't had my coffee yet and disaster strikes:<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">%<\/span> echo <span class=\"st\">&quot;amanaplanacanalpanama&quot;<\/span> <span class=\"kw\">&gt;<\/span> test.py  <span class=\"co\"># NUKED my file!  ACK!<\/span>\n\n<span class=\"co\"># GIT!  CAN YOU HELP ME!?!<\/span>\n<span class=\"kw\">%<\/span> git status\n<span class=\"kw\">On<\/span> branch master\n<span class=\"kw\">Your<\/span> branch is up-to-date with <span class=\"st\">&#39;origin\/master&#39;<\/span>.\n\n<span class=\"kw\">Changes<\/span> not staged for commit:\n  <span class=\"kw\">(use<\/span> <span class=\"st\">&quot;git add &lt;file&gt;...&quot;<\/span> to update what will be committed<span class=\"kw\">)<\/span>\n  <span class=\"kw\">(use<\/span> <span class=\"st\">&quot;git checkout -- &lt;file&gt;...&quot;<\/span> to discard changes in working directory<span class=\"kw\">)<\/span>\n\n    <span class=\"kw\">modified<\/span>:   test.py\n\n<span class=\"kw\">no<\/span> changes added to commit (use <span class=\"st\">&quot;git add&quot;<\/span> and\/or <span class=\"st\">&quot;git commit -a&quot;<\/span>)<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>Look at the line with <code>git checkout -- &lt;file&gt;<\/code>. I can use that to save me from myself:<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">git<\/span> checkout -- test.py\n<span class=\"co\"># PHEW!<\/span><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>Last, but not least, say I want to look at an older version of the code (before Barb got involved)<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<pre class=\"sourceCode bash\"><code class=\"sourceCode bash\"><span class=\"kw\">git<\/span> log --oneline\n<span class=\"kw\">git<\/span> checkout <span class=\"kw\">&lt;<\/span>aCommitID<span class=\"kw\">&gt;<\/span>    <span class=\"co\"># enter a hex id like 54eccfc <\/span>\n                            <span class=\"co\"># (just the first few digits are enough)<\/span>\n\n<span class=\"kw\">git<\/span> checkout master         <span class=\"co\"># click our heels to get home<\/span><\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<p>Note, we didn't do <code>git checkout HEAD<\/code> (which is usually legal) because we were in zombie land (a &quot;detached HEAD state&quot;. This means that if we wanted to do new work (on this old commit, sort of like going back in time and starting again), we would have to create a new branch and work off of it (which git told us when we did the checkout of the older commit id).<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"cell border-box-sizing text_cell rendered\">\n<div class=\"prompt input_prompt\">\n<\/div>\n<div class=\"inner_cell\">\n<div class=\"text_cell_render border-box-sizing rendered_html\">\n<h3>\nAdditional Resources\n<\/h3>\n<p>You can grab a <a href=\"http:\/\/drsfenner.org\/public\/notebooks\/QuickGit.ipynb\">copy of this notebook<\/a>.<\/p>\n<p>Even better, you can <a href=\"http:\/\/nbviewer.ipython.org\/url\/drsfenner.org\/public\/notebooks\/QuickGit.ipynb\">view it using nbviewer<\/a>.<\/p>\n<h3>\nLicense\n<\/h3>\n<p>Unless otherwise noted, the contents of this notebook are under the following license. The code in the notebook should be considered part of the text (i. e., licensed and treated as as follows).<\/p>\n<p><a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-nc-sa\/4.0\/\"><img alt=\"Creative Commons License\" style=\"border-width:0\" src=\"https:\/\/i.creat\nivecommons.org\/l\/by-nc-sa\/4.0\/88x31.png\" \/><\/a><br \/><span xmlns:dct=\"http:\/\/purl.org\/dc\/terms\/\" property=\"dct:title\">DrsFenner.org Blog And Notebooks<\/s\npan> by <a xmlns:cc=\"http:\/\/creativecommons.org\/ns#\" href=\"drsfenner.org\" property=\"cc:attributionName\" rel=\"cc:attributionURL\">Mark and Barbara Fenner<\/a> is licensed under a <a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-nc-sa\/4.0\/\">Creative Commons Attribution-NonCommercial-ShareAlike 4. 0 International License<\/a>.<br \/>Permissions beyond the scope of this license may be available at <a xmlns:cc=\"http:\/\/creativecommons.org\/ns#\" href=\"drs\nfenner.org\/blog\/about-and-contacts\" rel=\"cc:morePermissions\">drsfenner.org\/blog\/about-and-contacts<\/a>.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are many, many git tutorials out there. http:\/\/rogerdudler.github.io\/git-guide\/ is pretty cool and gives a nice overview. However, it doesn&#8217;t quite set you up to play around with the commands. Here is a completely self-contained walk-through that doesn&#8217;t require any networking to experiment with a reasonable git setup.<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,15],"tags":[],"class_list":["post-350","post","type-post","status-publish","format-standard","hentry","category-mrdr","category-tools"],"_links":{"self":[{"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/posts\/350","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/comments?post=350"}],"version-history":[{"count":1,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/posts\/350\/revisions"}],"predecessor-version":[{"id":351,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/posts\/350\/revisions\/351"}],"wp:attachment":[{"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/media?parent=350"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/categories?post=350"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/drsfenner.org\/blog\/wp-json\/wp\/v2\/tags?post=350"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}