W1006 Source Control
Source control enables us to track and manage changes to our code. This functionality becomes increasingly critical as the size of our projects grow both in terms of the lines of code and the number of coders. Source control shows us who changed the code and when. We're able to compare one revision of code to another. And, when necessary, we can rollback changes to a previous revision. Source control can be a tremendous help to you (and your team) when you want to easily recover from accidentally damaging a project and as such, provides you with the freedom to experiment without fear. However, you must use the source control system regularly and often or it won't be able to help you. In this experience we'll configure our source control system, learn (a bit) about how to use it, and then place our journals under source control.
There are many options to choose from when selecting a source control system. We'll be using one called git, created by Linus Torvalds in 2005. It's a distributed version-control system, meaning that every Git directory on every computer is a repository with a complete history and full version-tracking abilities.
Let's say you're a graphic artist, specializing in photo restoration, and working for the director of a museum. You've received an old photo that you're responsible to restore. Every step requires a lot of work and, being human, sometimes you make a mistake. Even if you didn't make a mistake your director might not agree with the choices that you've made. You (smartly) decide that just like every other project you've done, you'll track every version of your file in git.
Let's consider your progress through this process:
You commit each version of your project into git. Git considers each commit to be a snapshot of the current project. Each snapshot includes every current version of every file in your project that you've added to git, so it becomes a simple matter to move back in time to any version. While you're able to attach comments to each commit, internally, git uses a something called an SHA-1 hash to uniquely identify each commit. The hash is a 40-character string generated from the content of the files and directory structure. The hash will look something like this: 24b9da6552252987aa493b52f8696cd6d3b00373. You'll see this type of string in the git log.
Git enables us to experiment fearlessly because (as long as we've been diligent with our commits) we can also go back to a previous (working) version.
As a first step, we'll need to let Git know about our name and email address. Be sure to change your name and email address appropriately. You'll need to be able to receive email at the address you specify in order to complete the setup process.
Note: These commands, if successful, will complete silently.
Let's setup a new directory for all of our experiences and within, a directory for this experience:
One can consider the structure of a project, consisting of directories, files, and the associated content, as two dimensional. The repository can then be considered a three-dimensional structure formed by storing every committed version of the project structure across time. In order to initialize the repository, we issue the init command in the root of our project:
Note that this repository exists locally, alongside your other files for the project. There is no central server repository.
Add a File and Check Status
Let's create a small file that we can add to our project:
Let's find out what Git knows about this file:
Note that "file1.txt" is displayed in red under the title "Untracked files". Git is telling us that this file isn't currently being tracked. If we want to track it we'll need to tell Git to do so:
Let's check the status now:
Note that "file1.txt" is displayed in green under the title "Changes to be committed". Git is telling us that this file will be included in the next commit.
The previous status output mentioned a command to be used to unstage. What's a stage?
There are three states that a file in your project could be in:
- modified - a tracked file has been modified, but hasn't yet been staged
- staged - the current version of the file's data has been marked for inclusion in the next commit snapshot
- committed - the file's data has been safely stored in the repository
Consequently, there are three main sections of a git project:
- working directory - These are the files of your project that you interact (work) with
- staging area - a list of objects (directories and files) that will go into the next commit
- repository - this is where git stores all of the information, i.e. metadata (data that describes other data) and objects (directories and files) associated with your project
In order to create a new snapshot of all staged objects, we use the commit command. As part of the commit, it's helpful to explain (both to our fellow programmers and to our future selves) what it is that we changed and why. To facilitate this, git will open emacs so that we can edit our commit comments.
Emacs will now open. We'll see something similar to:
Let's add a helpful comment:
We then save the file and exit emacs as usual:- - - -
Git will then let us know that the commit was successful with a message similar to the following:
Let's add some additional text to file1.txt and also create a new file, file2.txt. Use emacs to:
- Add a new line to the end of "file1.txt" with the text, "This is a new line."
- Add a new file, "file2.txt" with the text, "This is a new line in a new file."
Then, exit emacs, and take a look at the status provided by git.
Let's stage the new versions of both of these files:
Then, have a look at the status again:
Before we commit our changes, let's remind ourselves of what's changed. We can compare our working directory to the repository with git diff. To compare the staged area to the repository, we add the --cached flag:
To conclude this section, let's commit our changes.
Create Journal Repository
We'll create a repository for all of our journals. First, we'll temporarily move to our journal directory:
As such, the general workflow is as follows:
- Initialize the repository. This need be done **only once**.
- Create and/or modify files in your working directory
- Add the files to the staging area
- Commit all of the staged changes to the repository
Now, return from the Journals directory:
Ignoring Unimportant Files
Emacs produces some files that are temporary in nature and should be excluded from git. However, unless we specify which files to ignore, git status will show these temporary files in addition to the files which are important to us. At best, this can be annoying. In order to instruct git to ignore these temporary files, create a special file in your git directory named .gitignore (the leading period is significant). For example:
To this file, add the following two lines:
The * character is known as a wildcard character and it will match any standard character, instructing git to ignore files such as story.txt~ and #story.txt#.
Save the file and exit emacs. Repeat this process for any new git repository that you create.