{"id":258,"date":"2014-05-13T21:06:00","date_gmt":"2014-05-13T21:06:00","guid":{"rendered":"https:\/\/questy.org\/?p=258"},"modified":"2024-09-26T19:06:59","modified_gmt":"2024-09-26T19:06:59","slug":"github-git-and-just-plain-revision-control","status":"publish","type":"post","link":"https:\/\/questy.org\/index.php\/2014\/05\/13\/github-git-and-just-plain-revision-control\/","title":{"rendered":"GitHub, Git, and Just Plain Revision Control"},"content":{"rendered":"\n<p>One of the \u201cbugaboos\u201d in the sysadmin world for the longest time was the reluctance to use those \u201cstinky developer tools\u201d in our world for any reason. &nbsp;I\u2019m not sure the impetus behind this, but my wager is on something akin to security or yet another open port or \u201cattack vector\u201d if you will. &nbsp;But today\u2019s competent and conscientious systems admin (not to mention DEVOPS person) will use revision control as their go-to standard for collecting, versioning, backing up, and distributing all manner of things.<\/p>\n\n\n\n<p>I\u2019ve seen some shops use&nbsp;<a href=\"http:\/\/www.nongnu.org\/cvs\/\">CVS<\/a>&nbsp;as their choice, old thought it is, just as a large \u201cbucket\u201d in which to throw things for safekeeping with revisions and rollbacks available in case of some uncertain as yet unencountered event. &nbsp;<a href=\"http:\/\/subversion.apache.org\">Subversion<\/a>&nbsp;was the next generation of revision control tools. &nbsp;Darling of developers and bane of disk space, Subversion still had many more features and performed essentially the same task.<\/p>\n\n\n\n<p>Now,&nbsp;<a href=\"http:\/\/git-scm.com\">Git<\/a>&nbsp;is the flavor of the month, and not only has gained widespread acceptance as a standard way to \u201cdo\u201d revision control, it\u2019s the de-facto way to do DEVOPS in &nbsp;a Puppet world. &nbsp;Granted, there are those brave souls out there who have tried to stick with the older tools, but the workflow and the \u201cglue\u201d between all the various components therein. &nbsp;Hence, this post.<\/p>\n\n\n\n<p><strong>What is Git, really?<\/strong><\/p>\n\n\n\n<p>Git was developed by&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Linus_Torvalds\">Linus Torvalds<\/a>&nbsp;for Linux Kernel collaboration. &nbsp;He needed a new revision control system akin to the previously used&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/BitKeeper\">BitKeeper<\/a>&nbsp;software that was unencumbered by copyright and able to handle the unique distributed development needs of the Linux project. &nbsp;So, rather than try and use someone else\u2019s project, he collated what was needed and developed the project himself.<\/p>\n\n\n\n<p>Now, Git is used both privately and Publicly throughout the world for many projects. &nbsp;Git is lightweight and works in a more efficient manner by moving changes via diffs rather than whole repositories, allows developers to maintain and manage an entire repository on their own systems either connected or disconnected from the Internet. &nbsp;Then, they can \u201cpush\u201d all their changes back to the central repository as needed.<\/p>\n\n\n\n<p><strong>Enter GitHub<\/strong><\/p>\n\n\n\n<p>For our purposes, we\u2019ll specifically be working in&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/GitHub\">GitHub<\/a>. &nbsp;GitHub is a project offering web-based hosting of your code that you can source from anywhere. &nbsp;GitHub offers public and private hosting and a spate of other related services to development collaboration on the Internet. &nbsp;If you do not have a GitHub account, you\u2019ll need to surf on over to the site and sign up for one. &nbsp;It\u2019s free and it\u2019s fast, and I\u2019ll be using and sourcing it heavily as this series continues.<\/p>\n\n\n\n<p><strong>Basic Git<\/strong><\/p>\n\n\n\n<p>Git itself is available on most modern platforms and can easily hook into GitHub for our purposes. &nbsp;I will be mostly referring to command-line usage of git, but you will find quite a bit in the way of tools, frontends, and \u201chelper\u201d apps for Git that you may or may not wish to leverage as you learn and incorporate Git into your workflow. &nbsp;In the meantime, stick with me on command-line work.<\/p>\n\n\n\n<p>When you install git on your unix-like platform, it will drop a few binaries. \u00a0The one we\u2019re most interested in is the git binary itself. \u00a0It\u2019s very simply designed and has a very straightforward set of options you can get from the command line by simply typing \u201cgit\u201d with no options, or \u201cgit help\u201d. \u00a0The output is below:<br><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>usage: git [-v | &#8211;version] [-h | &#8211;help] [-C &lt;path>] [-c &lt;name>=&lt;value>]<br>[&#8211;exec-path[=&lt;path>]] [&#8211;html-path] [&#8211;man-path] [&#8211;info-path]<br>[-p | &#8211;paginate | -P | &#8211;no-pager] [&#8211;no-replace-objects] [&#8211;bare]<br>[&#8211;git-dir=&lt;path>] [&#8211;work-tree=&lt;path>] [&#8211;namespace=&lt;name>]<br>[&#8211;super-prefix=&lt;path>] [&#8211;config-env=&lt;name>=&lt;envvar>]<br>&lt;command> [&lt;args>]<br><br>These are common Git commands used in various situations:<br><br>start a working area (see also: git help tutorial)<br>    clone    Clone a repository into a new directory<br>    init        Create an empty Git repository or reinitialize an existing one  <br><br>work on the current change (see also: git help everyday)<br>    add        Add file contents to the index<br>    mv         Move or rename a file, a directory, or a symlink<br>    restore  Restore working tree files<br>    rm          Remove files from the working tree and from the index<br><br>examine the history and state (see also: git help revisions)<br>    bisect    Use binary search to find the commit that introduced a bug  <br>    diff         Show changes between commits, commit and working tree, etc<br>    grep       Print lines matching a pattern<br>    log         Show commit logs<br>    show     Show various types of objects<br>    status    Show the working tree status<br><br>grow, mark and tweak your common history<br>     branch    List, create, or delete branches<br>     commit   Record changes to the repository<br>     merge    Join two or more development histories together<br>     rebase   Reapply commits on top of another base tip<br>     reset      Reset current HEAD to the specified state<br>     switch    Switch branches<br>     tag         Create, list, delete or verify a tag object signed with GPG<br><br>collaborate (see also: git help workflows)<br>     fetch   Download objects and refs from another repository<br>     pull      Fetch from and integrate with another repository or a local branch  <br>     push   Update remote refs along with associated objects<br><br>&#8216;git help -a&#8217; and &#8216;git help -g&#8217; list available subcommands and some<br>concept guides. See &#8216;git help &lt;command> &#8216; or &#8216;git help &lt;concept>&#8217;<br>to read about a specific subcommand or concept.<br>See &#8216;git help git&#8217; for an overview of the system.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><br>We\u2019re most interested in a small subset of commands for our purposes here. \u00a0They are\u00a0<strong>add, commit, pull, push, branch, checkout, and clone.<\/strong><\/p>\n\n\n\n<p>I will be referencing one particular way to \u201cdo\u201d git which works for me, but as with anything&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/TMTOWTDI\">TMTOWTDI<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/en.wiktionary.org\/wiki\/YMMV\">YMMV<\/a>.<\/p>\n\n\n\n<p><strong>GitHub Portion<\/strong><\/p>\n\n\n\n<p>I am going to assume you\u2019ve created a GitHub Account. &nbsp;When you create your account, you\u2019ll have a unique URL assigned to you based on your username. &nbsp;Mine, for instance, is&nbsp;<a href=\"https:\/\/github.com\/cvquesty\/\">https:\/\/github.com\/cvquesty\/<\/a>. &nbsp;The basic interface to GitHub is rather straightforward and looks like the following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"634\" src=\"https:\/\/i0.wp.com\/questy.org\/wp-content\/uploads\/2024\/08\/mygithub.png?resize=900%2C634&#038;ssl=1\" alt=\"\" class=\"wp-image-201\"\/><\/figure>\n\n\n\n<p>The interface keeps track of all projects you\u2019re working on, the frequency with which you commit or otherwise use your repository, and (most importantly), a centralized server that is storing those projects you can source from any internet connected system.<\/p>\n\n\n\n<p><strong>Make a Repository<\/strong><\/p>\n\n\n\n<p>In the upper right-hand corner of your screen, you\u2019ll notice a \u201c+\u201d symbol. &nbsp;Let\u2019s click that and create us a new repository. &nbsp;You\u2019ll be presented with a dialog to name and describe your new repo. &nbsp;I\u2019ll use the name \u201csample repo\u201d and the description \u201cSample Repo for my Tutorial\u201d with no other options other than the defaults. &nbsp;(we\u2019ll go manually through those processes shortly). &nbsp;After creating the repository by clicking \u201cCreate Repository\u201d, I\u2019m presented with a page that has step-by-step instructions on what to do next. &nbsp;I\u2019ll include that here for you.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"634\" src=\"https:\/\/i0.wp.com\/questy.org\/wp-content\/uploads\/2024\/08\/myrepo.png?resize=900%2C634&#038;ssl=1\" alt=\"\" class=\"wp-image-202\"\/><\/figure>\n\n\n\n<p>As you can see, you have your repo referenced at the top by&nbsp;\/. &nbsp;You have instructions on how to use the repo from both the GitHub desktop client and the command line and some special instructions for if you have it locally on your system, and are just now uploading that content into this repository you\u2019ve created to hold it. &nbsp;We\u2019re interested in the command line instructions.<\/p>\n\n\n\n<p><strong>A Place to Git<\/strong><\/p>\n\n\n\n<p>On my system (a Mac), I have Git installed by default and I have a directory in my home directory simply called \u201cProjects\u201d. &nbsp;Under there, I have a \u201cGit\u201d directory. &nbsp;ALL of my work in Git goes here. &nbsp;This is not a hard\/fast rule. &nbsp;I just chose it as my location to place all my git work so it is centralized and all collected together.<\/p>\n\n\n\n<p>What we\u2019re going to do next is to configure Git, create a location for our repo, make a file to commit to the repo and then push that file up to GitHub to see how that workflow works. &nbsp;Let\u2019s get started.<\/p>\n\n\n\n<p><strong>Configuring Git<\/strong><\/p>\n\n\n\n<p>Since Git is personal to you as a user, you need to let Git know a few things about you. &nbsp;This gives your git server (in our case GitHub) the information it needs when you\u2019re pushing code (like your identity, default commit locations, etc). &nbsp;First, your name and email:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><code class=\"\">git config --global user.name \"John Doe\" <\/code><br><code class=\"\">git config --global user.email you@yourmail.com<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>You\u2019ll only need to perform this once. &nbsp;There are quite a few options and you can read up on those&nbsp;<a href=\"http:\/\/git-scm.com\/book\/en\/Getting-Started-First-Time-Git-Setup\">here<\/a>&nbsp;at your leisure.<\/p>\n\n\n\n<p>Next, create a location for your new repo. &nbsp;I chose my aforementioned directory and created the location:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><code class=\"\">\/Users\/jsheets\/Projects\/Git\/samplerepo<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>for demonstration purposes. &nbsp;From here, though, we can take up with the instructions on the GitHub page displayed after creating your repo. I\u2019ll reproduce that here for reference:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><code class=\"\">cd \/Users\/jsheets\/Projects\/Git\/samplerepo <\/code><br><code class=\"\">touch README.md <\/code><br><code class=\"\">git init <\/code><br><code class=\"\">git add README.md <\/code><br><code class=\"\">git commit -m \"first commit\" <\/code><br><code class=\"\">git remote add origin https:\/\/github.com\/cvquesty\/samplerepo.git <\/code><br><code class=\"\">git push -u origin master<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>If all has gone well, you have now created an empty README.md file, committed it to your local Git repository and then subsequently pushed it up to GitHub. &nbsp;You\u2019ll note that we added \u201corigin\u201d as the remote and then we pushed to \u201corigin\u201d in a thing called \u201cmaster\u201d. &nbsp;What\u2019s that all about?<\/p>\n\n\n\n<p>GitHub (and git) refer to their repo location as \u201corigin\u201d. &nbsp;This becomes handy when you start pushing between remote repositories and from remote to remote to GitHub, etc. &nbsp;So, it makes sense to name GitHub&nbsp;<em>functionally&nbsp;<\/em>as well as it\u2019s assigned domain name. &nbsp;By saying \u201corigin\u201d, we\u2019re making GitHub the de-facto standard center of everything we\u2019re doing.<\/p>\n\n\n\n<p>Next, we refer to \u201cmaster\u201d. &nbsp;What is that? &nbsp;Simply stated, we\u2019re pushing to a \u201cbranch\u201d called \u201cmaster\u201d.<\/p>\n\n\n\n<p><strong>Branching<\/strong><\/p>\n\n\n\n<p>Branching is a method by which you can have multiple code \u201cbranches\u201d or \u201cthreads\u201d in existence simultaneously, and Git is managing them all for you. &nbsp;For instance, you may wish to have one code collection only for use in production systems while maintaining a separate one for development systems. &nbsp;In fact, you can create a random branch with a bug name (bug1234, for instance), commit your changes to that, test it, and push it to origin, then pull it down to all your production hosts, solving a big problem in your site or codebase. &nbsp;Better yet, if it all works great and you\u2019re happy with it, you can \u201cmerge\u201d that bug back into your main code repository, making it a permanent fixture in your code in whatever branch you like. (or even all of them!)<\/p>\n\n\n\n<p>When you first create your repo, GitHub makes a \u201cmain\u201d branch for you automatically, and calls it \u201cmaster\u201d. &nbsp;So, by utilizing the command above, we\u2019re telling Git to push our code (in this case, README.md) to our origin server (GitHub) and put it in the \u201cmaster\u201d branch.<\/p>\n\n\n\n<p>While we\u2019re on the topic, let\u2019s create two more branches so we can get the full hang of this branching thing. &nbsp;(Hint: &nbsp;It\u2019s core to how we integrate this into Puppet).<\/p>\n\n\n\n<p><strong>Makin&#8217; Branches<\/strong><\/p>\n\n\n\n<p>As I said before, GitHub creates a default \u201cmaster\u201d branch for you. &nbsp;If, from your local repository location, you type \u201cgit branch\u201d, Git will list a single branch for you,<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><code class=\"\"><strong>git branch <\/strong><\/code><br><code class=\"\">* master<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>This tells us simply, what branch you are currently in. &nbsp;Now, let\u2019s run two commands to create new branches to be tracked by Git.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td>git branch production<br>git branch development<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Now. &nbsp;Run \u201cgit branch\u201d again:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><code class=\"\"><strong>git branch<\/strong> <\/code><br><code class=\"\">development * <\/code><br><code class=\"\">master <\/code><br><code class=\"\">production<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>As you can see, your other branches are now visible when running the command. &nbsp;If you have color, you may notice that the \u201cmaster\u201d branch is a different color than the others (based on your settings). &nbsp;If you do not have color, the asterisk denotes what branch is active as well.<\/p>\n\n\n\n<p><strong>Checkout and Commit, Branch and Merge<\/strong><\/p>\n\n\n\n<p>We have our repository and we have our branches. &nbsp;We have a single README.md in the current directory, and we are ready to roll committing code and pushing it into our repository. &nbsp;Let\u2019s perform a simple experiment to get the \u201chang\u201d of how the branches work and how to switch between them as needed. &nbsp;Since we\u2019re in \u201cmaster\u201d, let\u2019s edit our README.md to reflect that by placing a single word in the file \u201cmaster\u201d. (use vim as discussed in our last tutorial).<\/p>\n\n\n\n<p>Once you\u2019re done with your edit, you\u2019ll see that the text is in the file. &nbsp;you can edit it and you can cat the file and see the contents, but if you view the file up at GitHub, that content is not there yet. &nbsp;Some sort of way, a mechanism must be used to put that data there. &nbsp;Well, there is such a process, and it is a two part process.<\/p>\n\n\n\n<p>Recall I mentioned that one of the features of Git is that you can have a complete repository local to your machine. &nbsp;you can work on that repo and make all sorts of changes completely disconnected from your server (in our case GitHub\u2026 \u201corigin\u201d as it is named to Git). &nbsp;Therefore, in reality you are dealing with not one, but two repositories. &nbsp;The local one on your machine and the remote one at origin. &nbsp;(remember the \u201cgit remote add origin\u201d above?)<\/p>\n\n\n\n<p>So, to finalize your changes locally, you must \u201ccommit\u201d them to your local repository as \u201cfinal\u201d. &nbsp;THEN, you can \u201cpush\u201d those changes into your main server (in our case GitHub). &nbsp; We did as much above with our procedure where we did the commit with a message, and then a push up to origin. &nbsp;However, now that we\u2019ve made changes locally, they are not yet reflected at GitHub. &nbsp;Logic would dictate another commit is in order:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><code class=\"\"><strong>git commit <\/strong><\/code><br><code class=\"\">or <\/code><br><code class=\"\"><strong>git commit -m 'Some message about your commit'<\/strong><\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>As you can see, there are two routes you can go. &nbsp;If you simply supply the \u201cgit commit\u201d without any options, you will be brought into the system text editor you (or your OS) has configured in the $EDITOR environment variable. &nbsp;Most platforms use \u201cvi\u201d or \u201cvim\u201d for this, but I have also seen \u201cpico\u201d used in some distributions like Ubuntu Linux. &nbsp;In any event, you can edit the file by placing your comments in. &nbsp;After exiting the file, saving the content, the commit will be complete. &nbsp;If, however, you do not put anything, git will not commit the changes. &nbsp;This is to enforce good coding practice by requiring some notes about what a committer is doing before making the changes. &nbsp;It\u2019s a highly recommended workflow to follow.<\/p>\n\n\n\n<p>Once your commit is complete, phase 1 (local commit) is over. &nbsp;You can commit over and over, as many times as you like. &nbsp;you are a full, local repository. &nbsp;In fact, I\u2019d encourage many commits. &nbsp;Commit when you think about it. &nbsp;Commit before you walk away from your system. &nbsp;Commit randomly for no reason in mid-workflow. &nbsp;The more commits you have, the less likely you are to lose work.<\/p>\n\n\n\n<p>Finally, to get the data up to GitHub, we need to \u201cpush\u201d that data off your repository and into your \u201corigin\u201d repository. This is quite simple, and you\u2019ve done it before:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><code class=\"\">git push -u origin master<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Sometimes you may wish to not keep specifying the location you\u2019re pushing to. &nbsp;If so, you can set a default location for each branch. &nbsp;Git will tell you just how to do that if you forget the \u201c-u location branch\u201d option. &nbsp;Let\u2019s say I\u2019m in my aster&nbsp;branch and I simply run a \u201cgit push\u201d. &nbsp;Git will tell me I did something wrong, but will&nbsp;<em>also&nbsp;<\/em>tell me how to eliminate that problem:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><code class=\"\">fatal: The current branch master\u00a0has no upstream branch. To push the current branch and set the remote as upstream, use <\/code><br><br><code class=\"\">git push --set-upstream origin\u00a0master<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>\u201cfatal\u201d seems a&nbsp;<em>little&nbsp;<\/em>melodramatic since Git gives you the answer as to what to do right there. &nbsp;All you need to do is set the default target once with that last line, and from that point forward, you only need type \u201cgit push\u201d when pushing to GitHub. &nbsp;Hint: &nbsp;I do this in ALL my branches at create time. &nbsp;It saves a lot of typing over time, and like any good Sysadmin, I\u2019m lazy. &nbsp;\ud83d\ude42<\/p>\n\n\n\n<p>So, now I\u2019ve got multiple branches that need this setting, but I\u2019m still stuck in \u201cmaster\u201d. &nbsp;How do I get to \u201cdevelopment\u201d or \u201cproduction\u201d to perform the same tasks?<\/p>\n\n\n\n<p>Git provides a \u201ccheckout\u201d command. &nbsp;What you\u2019re saying with \u201ccheckout\u201d is: &nbsp;&#8220;Git, I want to be working on branch \u201cx\u201d, and I want you to make that my current branch. &nbsp;if there are any differences between that branch and the one I\u2019m on, please make those changes on-disk for me so I can exclusively be working in branch \u201cx\u201d\u201c. &nbsp;A little verbose, but you get the point. &nbsp;So, to move to the next branch and do all the wonderful things we did in &#8220;master\u201d above, we perform:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><code class=\"\">git checkout development <\/code><br><code class=\"\">edit README.md to say different text <\/code><br><code class=\"\">git commit -a -m 'editing README for development branch' <\/code><br><code class=\"\">git push --set-upstream origin development <\/code><br><code class=\"\">git push<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>If all has gone well, your development README.md file is now changed and pushed into GitHub. &nbsp;What about \u201cmaster\u201d, though? &nbsp;Well, let\u2019s take a look:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><code class=\"\">git checkout master cat README.md<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>If all has gone well, the contents of README.md are back to what was in your \u201cmaster\u201d branch. &nbsp;By checking out \u201cdevelopment\u201d, it\u2019ll change back to the new content there. &nbsp;As a test, checkout the \u201cproduction\u201d branch, change the README.md file, commit it, set your upstream push target and then push the contents to GitHub.<\/p>\n\n\n\n<p>Now you\u2019re cooking with gas.<\/p>\n\n\n\n<p><strong>Conclusion<\/strong><\/p>\n\n\n\n<p>This is a simple tutorial to get you started with Git &amp; GitHub. &nbsp;There are MANY tutorials and books that can make you into a Git expert, but are way outside the scope of this humble little blog. &nbsp;let me provide a few of those for you here:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><code class=\"\">[Git Help](http:\/\/git-scm.com\/documentation) <\/code><br><code class=\"\">[Git Book](http:\/\/git-scm.com\/book)<\/code><br><code class=\"\">[GitHub Help](https:\/\/help.github.com)<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>This documentation should be more than enough to get you moving and well underway with Git ins-and-outs for committing Puppet code and using r10k to interface with and distribute that code around your environment.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the \u201cbugaboos\u201d in the sysadmin world for the longest time was the reluctance to use those \u201cstinky developer tools\u201d in our world for any reason. &nbsp;I\u2019m not sure the impetus behind this, but my wager is on something akin to security or yet another open port or \u201cattack vector\u201d if you will. &nbsp;But [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[6],"tags":[],"class_list":["post-258","post","type-post","status-publish","format-standard","hentry","category-technology"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/questy.org\/index.php\/wp-json\/wp\/v2\/posts\/258","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/questy.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/questy.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/questy.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/questy.org\/index.php\/wp-json\/wp\/v2\/comments?post=258"}],"version-history":[{"count":3,"href":"https:\/\/questy.org\/index.php\/wp-json\/wp\/v2\/posts\/258\/revisions"}],"predecessor-version":[{"id":261,"href":"https:\/\/questy.org\/index.php\/wp-json\/wp\/v2\/posts\/258\/revisions\/261"}],"wp:attachment":[{"href":"https:\/\/questy.org\/index.php\/wp-json\/wp\/v2\/media?parent=258"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/questy.org\/index.php\/wp-json\/wp\/v2\/categories?post=258"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/questy.org\/index.php\/wp-json\/wp\/v2\/tags?post=258"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}