Git

This book is not intended to be a complete resource on Git, but to use Code Manager effectively, you should know some basics about Git.

Git is a modern code repository that allows for asynchronous work on the same code set by multiple users. It accomplishes this by distinguishing every code commit as the difference between the previous code commit. Every commit is the unique delta in code between the last commit and the current changes. The first commit might add hundreds of lines of code to a code base, but the following commit might be as simple as removing one line and replacing it with another. When this code is cloned (or copied) by another user, it brings down the latest code and allows the user to roll back to previous commits.

As an introduction to Git, let's walk through a scenario. Suppose that you are using Git to redecorate your living room. The current commit is how your living room looks right now. If you liked how it looked last summer, before you replaced your couch, you could roll back to the previous commit and set your living room back to a previously accepted state. Commits should be seen as accepted states of code, or, in this case, accepted states of your living room.

First and foremost, we don't want to break our living room while building a new one, so we'll clone it with git clone. This makes a copy of the current living room, and its entire change history is bundled in. To keep things simple, we'll use the most recent version of our living room. If we wanted to make a change to the living room, we could purchase a new couch, a new TV, and two new lamps. Let's suppose that we love the lamps, but we're not sure about the couch and the TV. If we use git add on the lamps, it will add those lamps to the staging directory. Git will report the following:

$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

new object: Lamps

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: Couch
modified: Television

We've asked Git to track the changes on the new lamps that we love. When we type git commit, we're asked to write what the change is, and then, Git will commit the new living room to memory:

$ git commit -m 'Beautiful New Lamps'

[master 0b1ae47] Beautiful New Lamps
1 object changed, 0 insertions(+), 0 deletions(-)
create mode 100644 Lamps

Notice that the couch and TV are not included in this manifest of changes. In our working directory, or our current living room, the couch and TV are still present, but they're not permanent changes until we also add and commit them. Optionally, we could send our new commit (the lamps) back to our remote repository for safekeeping, and to let any other decorator use our most current living room composition with git push.

In short, we clone (copy) a living room format. We make changes to that format at will. The changes that we're sure we like, we add and commit. The changes that we're unsure about remain present, but only in our current working directory (or the current state of our living room). We could either add and commit our couch and television, or simply git stash and return our living room to the last known good state, which is now our previous living room, plus the new lamps. This pattern gives us the option to try drastic changes, and only commit the ones that we're sure about as a checkpoint in time. Once we have a commit (checkpoint) that we're willing to stand behind, we can then push that back to the version of the living room that everyone can see.

Let's go over using Git against code, instead of in the living room. The first step is to clone, or copy, a repository. The command git clone copies an entire repository and its history, and brings it to the local workstation. This copy of code is entirely separate from where it was cloned (its origin). git clone creates an entirely standalone copy of the original repository. 

When a user first enters a code repository, all of the code is in the working directory. A user can make changes to the code at will here, and Git will track the delta between the last commit and what is currently in the repository. Git has a command called git status that allows a user to inspect what files are different from the last commit. In the following example, a module has been cloned, values have been changed in init.pp, and the user has run the git status from inside the directory of the module:

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: init.pp

You may have noticed Changes not staged for commit. Git recognizes the working directory, changes staged for a commit, and every commit in the repository history. The standard workflow is to clone a repository, make changes, stage them for a commit, and make a new atomic commit, before pushing it back to a central repository.

Although we generally don't make changes to a module procured from the Puppet Forge (the primary external repository for Puppet Code), let's go over what it's like to clone, change, commit, and (optionally) push our code back to the original repository, which Git automatically tags as origin.

First, we'll clone and make a local copy of puppetlabs/ntp:

$ git clone [email protected]:puppetlabs/puppetlabs-ntp.git
Cloning into 'puppetlabs-ntp'...
remote: Counting objects: 7522, done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 7522 (delta 5), reused 18 (delta 5), pack-reused 7504
Receiving objects: 100% (7522/7522), 1.64 MiB | 0 bytes/s, done.
Resolving deltas: 100% (4429/4429), done.

Notice that it cloned the repository and applied 4,429 deltas. We now have a local copy of the entire repository contained on GitHub. It will create a directory called puppetlabs-ntp, which we must enter by using a change directory to continue in the local repository.

Next, we'll edit the files that we intend to edit. In this case, I added a single comment to manifests/init.pp in the repository. I can check how Git views the repository with the command git status:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: init.pp

no changes added to commit (use "git add" and/or "git commit -a")

Git now sees the change to the local repository. I want to ensure that this change is committed to the repository, so next, I'll add it to the staging directory, highlighting it for a commit with git add manifests/init.pp. If we run another simple git status, we will notice that our code is no longer not staged for commit, but is now under Changes to be committed:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)

modified: manifests/init.pp

With init.pp in the staging directory, I can commit this code to a new version. Running the command git commit will open your default editor, allowing you to comment and name your commit. I will run the command with an -m flag, which allows me to pass the message on the command line, rather than by opening up my default editor:

$ git commit -m 'Simple Clarification Comment added to init.pp feature'
[master 4538890] Simple Clarification Comment added to init.pp feature
1 file changed, 1 insertion(+)

Now, my local repository has the new commit locally. I can view this commit with the command git log:

commit 45388902ef5cf125ea2109197e115f050d603406 (HEAD -> master)
Author: Ryan Russell-Yates <[email protected]>
Date: Sun Apr 8 16:28:26 2018 -0700

Simple Clarification Comment added to init.pp feature

Most notably, this change is only on the local repository on my laptop. To share this code, I want to push my commit back to where I retrieved the original code from. When you run git clone locally, it also records where the code came from, and, by default, names the remote repository origin. If I run the command git remote -v, I can actually see the URL that the repository came from:

$ git remote -v
origin [email protected]:puppetlabs/puppetlabs-ntp.git (fetch)
origin [email protected]:puppetlabs/puppetlabs-ntp.git (push)

If I had permission to push directly to this repository, I could send my new commit to the source with the simple command, git push origin master. Master is the name of the branch, or the specific code set inside of a repository I'm working on.

Branches are a concept in Git that allow us to create a copy of code and work on it in what is similar to a separate directory. By default, Git creates a master branch, which is the intended location of the most up-to-date functional code. We can create a new branch in Git and change code without impacting the original branch that it came from. The most efficient use of Git is for trunk-based development, where we start on the master branch, create a new branch that contains new features, test those features, and eventually, merge our branch back into the master branch. This model allows us to work on, share, test, and even implement code, without impacting the original code set.

When we type git checkout -b new_branch, we create a new branch, based on the original branch that we were on. We can then work here, add additional commits, and even push it back to the source, without impacting the original code. Only when the code is merged back into the original branch does it have an impact on that branch. Think of it as the Git equivalent of copying a set of code to a new directory, working on it, testing it, and then copying it back to the original source when finished.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.211.66