{"id":427,"date":"2021-09-19T12:57:39","date_gmt":"2021-09-19T20:57:39","guid":{"rendered":"http:\/\/spacefold.com\/colin\/morethanfour\/?p=427"},"modified":"2021-09-19T13:34:00","modified_gmt":"2021-09-19T21:34:00","slug":"learning-git-3-remotes","status":"publish","type":"post","link":"https:\/\/spacefold.com\/colin\/morethanfour\/2021\/09\/19\/learning-git-3-remotes\/","title":{"rendered":"Learning Git &#8211; 3: Remotes"},"content":{"rendered":"\n<p>(Previously: <a href=\"https:\/\/spacefold.com\/colin\/morethanfour\/2021\/09\/19\/learning-git-2-branching\/\">Part 2: Branching<\/a>)<\/p>\n\n\n\n<p>Having Git providing a source control repository for local development is great, but there&#8217;s more. Git repositories can also reference other <strong>remote<\/strong> repositories out on the network. The network might be our corporate LAN, or perhaps the Internet.<\/p>\n\n\n\n<p>Remote references allow us to get changes made by other developers. They also allow us to share our changes with other developers.<\/p>\n\n\n\n<p>Two popular repository vendors are GitHub and Atlassian BitBucket. Either of them will allow us set up our own public or private git repositories for free.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Some conceptual stuff<\/h3>\n\n\n\n<p>What can we do with remote references?<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>We can <strong>fetch<\/strong> the latest change history from the remote repository;<\/li><li>We can reference the state of remote branches called <strong>remote-tracking branches<\/strong>, e.g. &#8220;alias\/name&#8221;, or &#8220;origin\/master&#8221;;<\/li><li>We can create a local <strong>tracking branch<\/strong> that replicates the contents of a remote branch;<\/li><li>We can <strong>merge<\/strong> the changes into our local <strong>tracking branch<\/strong>;<\/li><li>We can make local source code edits in a tracking branch; and <strong>push<\/strong> the committed changes to the remote repository.<\/li><\/ul>\n\n\n\n<p>I found the terminology of &#8220;remote-tracking branches&#8221; versus &#8220;tracking branches&#8221; confusing at first. Let&#8217;s re-iterate:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>A <strong>branch<\/strong> is a pointer to a specific commit in the change history;<\/li><li>A <strong>remote-tracking branch<\/strong> represents the current state of a remote branch (updated automatically when connected to the server)<\/li><li>A <strong>tracking branch<\/strong> is a local branch checked out from a remote branch (or &#8220;upstream branch&#8221;).<\/li><\/ul>\n\n\n\n<p>I&#8217;m going to move my local repository into a remote, shareable version, and then pretend to be a second developer collaborating on the project from a different machine.<\/p>\n\n\n\n<p>I&#8217;m going to do it step-by-step, with no shortcuts.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating a remote repository on GitHub<\/h3>\n\n\n\n<p>I&#8217;ve already created a GitHub account, so I log in and create a new empty repository called <strong>cow-tipper<\/strong>.<\/p>\n\n\n\n<p><strong><em>CAUTION<\/em><\/strong>: GitHub prompts us to initialize the repository with README, .gitignore, and license files. Don&#8217;t be tempted to do this! We require the repository to be empty in order to upload our local repository history into it. Leave the checkboxes un-ticked.<\/p>\n\n\n\n<p>Another thing to note is that GitHub <a rel=\"noreferrer noopener\" href=\"https:\/\/www.zdnet.com\/article\/github-to-replace-master-with-main-starting-next-month\/\" target=\"_blank\">uses a default branch name of &#8220;main&#8221;<\/a> instead of the traditional &#8220;master&#8221;. We could have changed it back at the time of repository creation, but let&#8217;s leave it as-is for now.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Remote URLs and Protocols<\/h4>\n\n\n\n<p>Git repository can store a remote<strong> URL<\/strong> that represents a remote repository. Usually, the URL will use one of two common network protocols: HTTPS or SSH. Either works well but each has its own quirks of user authentication.<\/p>\n\n\n\n<p>GitHub is helpful and allows us to select which protocol we want to use, showing us the appropriate URL, along with some commands for uploading a local repo:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>SSH: git@github.com:buster-kitten\/cow-tipper.git<\/li><li>HTTPS: https:\/\/github.com\/buster-kitten\/cow-tipper.git<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Connecting our repository to the remote one<\/h3>\n\n\n\n<p>Here&#8217;s what we need to do:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Add a remote reference to the new empty GitHub repository in our local repository;<\/li><li>Redefine the default branch name (&#8220;master&#8221;) so that it matches the remote one (&#8220;main&#8221;);<\/li><li>Initialize the remote repository with our local repos&#8217; change history<\/li><\/ul>\n\n\n\n<p>Let&#8217;s double-check where we are:<\/p>\n\n\n\n<pre>$ cd ~\/Projects\/cow_tipper \n$ git switch master \n$ git status<\/pre> \n<pre class=\"console-output\">On branch master nothing to commit, working tree clean<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Add remote reference<\/h4>\n\n\n\n<p>Let&#8217;s add a reference named &#8220;skippy&#8221; to our remote repository to our local one, using the <strong>git remote<\/strong> command:<\/p>\n\n\n\n<pre>$ cd ~\/Projects\/cow_tipper\n$ git remote add skippy git@github.com:buster-kitten\/cow-tipper.git<\/pre>\n\n\n\n<p>Most of the time in literature you&#8217;ll see remote references use the name &#8220;origin&#8221;, but I want to underline the fact that &#8220;origin&#8221; is not a magic word, it is just a label, and could be anything. Ours is &#8220;skippy&#8221;.<\/p>\n\n\n\n<p>We can see what remote references our local repository knows about:<\/p>\n\n\n\n<pre>$ git remote --verbose<\/pre> \n<pre class=\"console-output\">skippy git@github.com:buster-kitten\/cow-tipper.git (fetch) \nskippy git@github.com:buster-kitten\/cow-tipper.git (push)<\/pre>\n\n\n\n<p>&#8230;but that&#8217;s not important right now.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Synchronize the default branch name<\/h4>\n\n\n\n<p>Now we rename the local repository&#8217;s default branch from &#8220;master&#8221; to &#8220;main&#8221;:<\/p>\n\n\n\n<pre>$ git branch --move master main\n$ git status <\/pre>\n<pre class=\"console-output\">On branch main\nnothing to commit, working tree clean<\/pre>\n\n\n\n<p>Two observations:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>It is not required that the local branch name match the tracked remote branch name, but I think you&#8217;ll agree that it is a good idea to reduce confusion.<\/li><li>If we had created our local repository to use &#8220;main&#8221; as the name of the default branch, this rename step would not have been necessary, obviously.<\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Make it a remote-tracking branch (attempt  1)<\/h4>\n\n\n\n<pre>$ git branch --set-upstream-to skippy\/main<\/pre>\n<pre class=\"console-output\">error: the requested upstream branch 'skippy\/main' does not exist\nhint: \nhint: If you are planning on basing your work on an upstream\nhint: branch that already exists at the remote, you may need to\nhint: run \"git fetch\" to retrieve it.\nhint: \nhint: If you are planning to push out a new local branch that\nhint: will track its remote counterpart, you may want to use\nhint: \"git push -u\" to set the upstream config as you push.<\/pre>\n\n\n\n<p>My first instinct was &#8220;oh, of course skippy\/main doesn&#8217;t exist &#8211; we don&#8217;t have any remote-tracking branches until we fetch from the server&#8221;.<\/p>\n\n\n\n<p>This is true, but not appropriate in our situation: there&#8217;s no actual history to fetch from our brand-new empty remote repository. It has no commit history, no branches. We could perform a Fetch, but it wouldn&#8217;t help.<\/p>\n\n\n\n<p>Let&#8217;s try it anyway:<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Attempting to fetch the remote repository commit history<\/h4>\n\n\n\n<p>A <strong>fetch<\/strong> operation will need to authenticate against the remote server, which doesn&#8217;t know who we are. We&#8217;ll get a &#8220;Permission denied (publickey)&#8221; error. We need to authenticate ourselves over SSH by creating a public+private key pair and uploading our public key to the server.<\/p>\n\n\n\n<p>For more detail on authentication with remote repositories, <br>see <a href=\"https:\/\/spacefold.com\/colin\/morethanfour\/2021\/09\/19\/learning-git-appendix-c-petra-rabbits-authentication-palooza\/\">Appendix C: Petra Rabbit&#8217;s Authentication-palooza<\/a>.<\/p>\n\n\n\n<p>Having set up my RSA key pair and uploaded my public key to GitHub, I&#8217;ll try the fetch:<\/p>\n\n\n\n<pre>$ git fetch skippy<\/pre>\n\n\n\n<p>That took a few seconds before displaying the prompt, so I think this means it worked. No error, anyway. Now let&#8217;s try setting up the remote-tracking branch again:<\/p>\n\n\n\n<pre>$ git branch --set-upstream-to skippy\/main<\/pre>\n<pre class=\"console-output\">error: the requested upstream branch 'skippy\/main' does not exist<\/pre>\n\n\n\n<p>Well, I said fetching wouldn&#8217;t help. The second hint that Git echoes to the console is more relevant:<\/p>\n\n\n\n<pre class=\"console-output\">hint: If you are planning to push out a new local branch that\nhint: will track its remote counterpart, you may want to use\nhint: \"git push -u\" to set the upstream config as you push.<\/pre>\n\n\n\n<p>Okay. Because no branches exist in our target empty repository, we have to push from our local repo in order to create them remotely.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Push to create the remote branch<\/h4>\n\n\n\n<p>This is a one-time thing: we <strong>push<\/strong> our work to the empty remote repository:<\/p>\n\n\n\n<pre>$ git push skippy main:main<\/pre>\n\n\n\n<p>Further reading on this, see: <a href=\"https:\/\/stackoverflow.com\/questions\/1519006\/how-do-you-create-a-remote-git-branch\/1519032#1519032\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/stackoverflow.com\/questions\/1519006\/how-do-you-create-a-remote-git-branch\/1519032#1519032<\/a><\/p>\n\n\n\n<p>If you&#8217;re following along, but omitted the attempt to fetch, then you might still get the &#8220;permission denied (publickey)&#8221; error at this point. Ensure your public key is uploaded to your GitHub account.<\/p>\n\n\n\n<pre>$ git push skippy main:main<\/pre>\n<pre class=\"console-output\">Enumerating objects: 44, done.\nCounting objects: 100% (44\/44), done.\nDelta compression using up to 8 threads\nCompressing objects: 100% (41\/41), done.\nWriting objects: 100% (44\/44), 4.53 KiB | 928.00 KiB\/s, done.\nTotal 44 (delta 8), reused 0 (delta 0)\nremote: Resolving deltas: 100% (8\/8), done.\nTo github.com:buster-kitten\/cow-tipper.git\n * [new branch]      main -&gt; main<\/pre>\n\n\n\n<p>At this point, we can go to the GitHub site and select our cow-tipper repository and see that there are now two files, a branch &#8220;main&#8221;, and 15 commits. Nice! We&#8217;ve successfully uploaded our local repository into a remote one.<\/p>\n\n\n\n<p>Let&#8217;s recap:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>we have a remote called &#8220;skippy&#8221;<\/li><li>Our &#8220;master&#8221; branch was renamed &#8220;main&#8221; and is now a tracking branch<\/li><li>It tracks the remote-tracking branch &#8220;skippy\/main&#8221;<\/li><li>All our locally-created source code change history is available on the remote repository on GitHub, available for cloning.<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Remote Workflow<\/h3>\n\n\n\n<p>Now that our repository is replicated on the remote server, it is available to other developers. I&#8217;ve sent out invites using the tools available on GitHub.com, and I&#8217;m pretty sure there&#8217;s been some activity.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Fetch<\/h4>\n\n\n\n<p>Now that we&#8217;re working with changes from other developers, we need to refresh our local remote-tracking branches with any new changes they may have saved to the server.<\/p>\n\n\n\n<p>The <strong>fetch<\/strong> command retrieves from the remote repository all the source file changes that we don&#8217;t already have in our local repo:<\/p>\n\n\n\n<pre>$ git fetch skippy<\/pre>\n<pre class=\"console-output\">remote: Enumerating objects: 10, done.\nremote: Counting objects: 100% (10\/10), done.\nremote: Compressing objects: 100% (4\/4), done.\nremote: Total 7 (delta 3), reused 7 (delta 3), pack-reused 0\nUnpacking objects: 100% (7\/7), 777 bytes | 388.00 KiB\/s, done.\nFrom github.com:buster-kitten\/cow-tipper\n   84b9985..5e9ae78  main       -&gt; skippy\/main<\/pre>\n\n\n\n<p><strong>Fetch<\/strong> downloads the changes into our remote-tracking branch. Our &#8220;main&#8221; branch is unchanged at this point:<\/p>\n\n\n\n<pre>$ git log --pretty=\"format:%h %ce %ci %d %n        %s\" -1 <\/pre>\n<pre class=\"console-output\">84b9985 buster@spacefold.com 2021-09-07 15:40:32 -0700  (HEAD -&gt; main) \n        Merge branch 'secundo'<\/pre>\n\n\n\n<p>Yeah, that&#8217;s right &#8211; the last code change I made was to merge in my &#8220;secundo&#8221; branch. However we can ask git to show the log for the remote-tracking branch:<\/p>\n\n\n\n<pre>$ git log --pretty=\"format:%h %ce %ci %d %n        %s\" -3 skippy\/main<\/pre>\n<pre class=\"console-output\">5e9ae78 zach@litterbox.com 2021-09-11 20:25:34 -0700  (skippy\/main) \n        Zach The Cat was here and added some code\n48e6c91 petra@mcgregor_garden.co.uk 2021-09-11 17:54:59 -0700  \n        Additional description about stuff to do\n84b9985 buster@spacefold.com 2021-09-07 15:40:32 -0700  (HEAD -&gt; main) \n        Merge branch 'secundo'<\/pre>\n\n\n\n<p>We see Zach and Petra have been busy, and committed a couple of changes.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Merge<\/h4>\n\n\n\n<p>Let&#8217;s merge their changes into our local branch:<\/p>\n\n\n\n<pre>$ git merge skippy\/main<\/pre>\n<pre class=\"console-output\">Updating 84b9985..5e9ae78\nFast-forward\n README.md     | 3 ++-\n cow_tipper.py | 2 ++\n 2 files changed, 4 insertions(+), 1 deletion(-)<\/pre>\n\n\n\n<p>No conflicts, that&#8217;s good. Now our local source files on our file system (in our &#8220;main&#8221; branch) are up-to-date with the latest changes from the remote repo.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">The Next Day&#8230;<\/h4>\n\n\n\n<p>This morning I&#8217;ve made some changes to the code: I moved a function into a separate module. I&#8217;ve tested my code change, and I&#8217;m ready to commit.<\/p>\n\n\n\n<p>But I suspect there may be some changes from my offshore developer. I&#8217;ll <strong>fetch<\/strong> and check the remote <strong>log<\/strong>:<\/p>\n\n\n\n<pre>$ git fetch skippy \n[..] \n$ git log --pretty=\"format:%h %ce %ci %d %n %s\" -2 skippy\/main<\/pre> \n<pre class=\"console-output\">cee496c petra@mcgregor_garden.co.uk 2021-09-13 17:00:39 -0700 (skippy\/main)\n        Testing negative tax rates \n5e9ae78 zach@litterbox.com 2021-09-11 20:25:34 -0700 \n        Zach The Cat was here and added some code<\/pre>\n\n\n\n<p>Yup, Petra added a test. What should we do now? Should I:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>commit<\/strong> my changes locally<\/li><li><strong>merge<\/strong> from remote and deal with potential conflicts<\/li><\/ul>\n\n\n\n<p>Or:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>stash<\/strong> my current working tree<\/li><li><strong>merge<\/strong> from remote<\/li><li>un-<strong>stash<\/strong> and <strong>commit<\/strong> (and deal with potential conflicts)<\/li><\/ul>\n\n\n\n<p><em><strong>Aside<\/strong><\/em>: I haven&#8217;t talked about <strong>stashing<\/strong> in this tutorial yet, and it is already epic in size. So go here if you&#8217;re curious: <br>See <a href=\"https:\/\/git-scm.com\/book\/en\/v2\/Git-Tools-Stashing-and-Cleaning\">https:\/\/git-scm.com\/book\/en\/v2\/Git-Tools-Stashing-and-Cleaning<\/a>.)<\/p>\n\n\n\n<p>What&#8217;s best? I&#8217;m not sure. I&#8217;m going to go with strategy A:<\/p>\n\n\n\n<pre>$ git add *\n$ git commit -m \"moving function to library module\"\n$ git log --pretty=\"format:%h %ce %ci %d %n        %s\" -1 <\/pre>\n<pre class=\"console-output\">3e60b54 buster@spacefold.com 2021-09-15 17:14:39 -0700  (HEAD -&gt; main) \n        moving function to library module<\/pre>\n\n\n\n<p>No errors, and all our work is safe in commit &#8220;3e60b54&#8221; in branch &#8220;main&#8221;.<\/p>\n\n\n\n<p>What horrors await us in the remote branch?<\/p>\n\n\n\n<pre>$ git diff main skippy\/main<\/pre>\n\n\n\n<p><strong><em>Aside<\/em><\/strong>: To avoid derailing the narrative, I&#8217;ve put a the introduction and examples of DIFF into <a href=\"https:\/\/spacefold.com\/colin\/morethanfour\/2021\/09\/19\/learning-git-appendix-d-whats-the-diff\/\">Appendix D: What&#8217;s the DIFF?<\/a> Check it out if you wish.<\/p>\n\n\n\n<p>This gets messy, because the diff shows us what we need to do to make the source in &#8220;main&#8221; look like the source in &#8220;skippy\/main&#8221;, but we don&#8217;t want to accept <strong>all<\/strong> those changes, because it would undo the work we did this morning. We have to be selective.<\/p>\n\n\n\n<p>Worst case, we can roll back to our &#8220;safe&#8221; commit using <strong>git reset &#8211;hard 3e60b54<\/strong>. Let&#8217;s merge and see what we get:<\/p>\n\n\n\n<pre>$ git merge skippy\/main<\/pre>\n<pre class=\"console-output\">Auto-merging cow_tipper.py\nCONFLICT (content): Merge conflict in cow_tipper.py\nAutomatic merge failed; fix conflicts and then commit the result.<\/pre>\n\n\n\n<p>The results are actually pretty good. We do need to manually resolve (i.e., edit) <strong>cow_tipper.py<\/strong> because blindly accepting either the remote or local version would be incorrect: I need to keep Petra&#8217;s addition (from the remote version), whilst changing it to invoke the function from the new library I added (in the local version).<\/p>\n\n\n\n<p>You do not need to see the code &#8211; it&#8217;s a trivial and contrived example.<\/p>\n\n\n\n<p>Having resolved the conflicts, and tested it (hey, Petra had a bug in her code!), we can commit and push:<\/p>\n\n\n\n<pre>$ git add cow_tipper.py\n$ git commit -m \"resolving merge conflicts; fixing Petra's bug\"\n$ git push skippy<\/pre>\n<pre class=\"console-output\">fatal: The current branch main has no upstream branch.\nTo push the current branch and set the remote as upstream, use\n\n    git push --set-upstream skippy main<\/pre>\n\n\n\n<p>Uh.. what? Has it forgotten? Do we have to remind it? Okay:<\/p>\n\n\n\n<pre>$ git branch --set-upstream-to skippy\/main<\/pre>\n<pre class=\"console-output\">Branch 'main' set up to track remote branch 'main' from 'skippy'.<\/pre>\n\n<pre>$ git push skippy<\/pre>\n<pre class=\"console-output\">Enumerating objects: 14, done.\nCounting objects: 100% (14\/14), done.\nDelta compression using up to 8 threads\nCompressing objects: 100% (9\/9), done.\nWriting objects: 100% (10\/10), 1.03 KiB | 1.03 MiB\/s, done.\nTotal 10 (delta 4), reused 0 (delta 0)\nremote: Resolving deltas: 100% (4\/4), completed with 1 local object.\nTo github.com:buster-kitten\/cow-tipper.git\n   cee496c..d9ac925  main -&gt; main<\/pre>\n\n\n\n<p>Yeah, I don&#8217;t know what happened, but we&#8217;re back now. The remote repo has our combined changes.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Pull<\/h4>\n\n\n\n<p>The Git <strong>pull<\/strong> command combines <strong>fetch<\/strong> and <strong>merge<\/strong> for remote-tracking branches. As Petra enjoys her first coffee of the day, she executes:<\/p>\n\n\n\n<pre>$ git pull origin<\/pre>\n\n\n\n<p>(No, that&#8217;s not a typo. In Petra&#8217;s local repository,the remote reference is named &#8220;origin&#8221;. Only in my local repository is the remote ref called &#8220;skippy&#8221;.)<\/p>\n\n\n\n<p>And Petra now has the latest source files in her local &#8220;main&#8221; branch.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How do I&#8230;?<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Show branches with upstream remote-tracking branches:<\/h4>\n\n\n\n<pre>$ git branch -vv<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Show detailed information about remotes and remote-tracking branches:<\/h4>\n\n\n\n<pre>$ git remote show &lt;remote&gt;<\/pre>\n\n\n\n<p>Further reading:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/git-scm.com\/book\/en\/v2\/Git-Branching-Remote-Branches\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/git-scm.com\/book\/en\/v2\/Git-Branching-Remote-Branches<\/a><\/li><\/ul>\n\n\n\n<p>That&#8217;s all for this section. Next, <a href=\"https:\/\/spacefold.com\/colin\/morethanfour\/2021\/09\/19\/learning-git-4-remotes-ii-reverse-the-polarity\/\">Part 4: Remotes II &#8211; Reverse the Polarity!<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>(Previously: Part 2: Branching) Having Git providing a source control repository for local development is great, but there&#8217;s more. Git repositories can also reference other remote repositories out on the network. The network might be our corporate LAN, or perhaps the Internet. Remote references allow us to get changes made by other developers. They also [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[],"class_list":["post-427","post","type-post","status-publish","format-standard","hentry","category-source-control","post-preview"],"_links":{"self":[{"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/posts\/427","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/comments?post=427"}],"version-history":[{"count":0,"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/posts\/427\/revisions"}],"wp:attachment":[{"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/media?parent=427"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/categories?post=427"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/tags?post=427"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}