Up to this point we've mostly looked at how things work rather than how they are made. Though we won't start building anything just yet, it is time to take a step in that direction and look at some of the programs we'll be using to build our application.
As you might expect, there are many tools available to accomplish the necessary tasks involved in building a complete web application, but even more numerous are people's opinions about which are best.
The aim of this book is not to convince you that these tools are better than their competitors, but instead to offer suggestions as to dependable options, options that tend to be favorites in the Ruby and Rails communities.
Without question, the most foundational of the preferences in the Rails community is that for Unix-like operating systems in general and for Mac OS X specifically.
Examples of operating systems would be Mac OS X, Microsoft Windows, and Linux.
Personally, I run Linux (Linux Mint 14 MATE 64-bit) and don't have any trouble following along with Rails tutorials and screencasts made by and for people using OS X. The reason for this is that Linux is also a Unix-like operating system and that its default shell, like OS X, is Bash.
More on Bash next section.
So if you're on a Mac, great! You won't have have to configure much.
And if you're on Linux, even better! Because that's what I'm running.
But if you happen to be on Windows, I highly encourage you to create a Virtual Machine (VM) or Live USB (or Live CD) of Linux to follow along. Downloading Linux is free and running it as a VM will let you stay in Windows while using a Live USB will require you to restart your machine and boot Linux off of the USB drive (instead of Windows).
You can even (carefully) install Linux on your machine this way if you like it, but it's not necessary to follow along.
For a detailed walkthrough of how to set up a virtual machine for yourself, please can check out my blog post on the subject.
It should still apply, but downloading and using the latest version of Linux Mint is recommended!
Having said all of that, you can use both Ruby and Rails in Windows as well as all of the tools in this chapter with the glaring exception of Bash. And though you're certainly welcome to download and install them in Windows on your own, I've never done anything of the sort and won't be able to be of any help.
Additionally, I wrote this book with Unix-like systems in mind, so there may be some things that won't transfer directly to Windows.
Bash is the default shell for many Unix-like systems, including OS X and Linux.
Before the advent of the Graphical User Interface (GUI) computer users would have do everything by typing commands to their computer, instead of clicking on something on the screen. There were no windows and no mouse, just text and the keyboard.
The means by which we can interact with our computers have certainly increased and evolved significantly, but we can still access a shell from most any modern operating system today. OS X and Linux in particular, both being Unix-like, stay true to their roots and allow for easy access to a shell (Bash by default) via a terminal application.
Here's me screwing around in a terminal on my machine:
The terminal is also referred to as the CLI (Command Line Interface). The term "shell" is different than these terms, but they've come to be used more or less interchangeably.
Also, other shells have grown in popularity, Zsh most notably, but Bash is still the default.
You're encouraged to look around, but an understanding of Bash will cover all the necessary parts of a good shell.
To open a terminal in OS X, it's my understanding that you can go to: Applications -> Utilities -> Terminal
In Linux Mint, I see it under: Main Menu -> Accessories -> Terminal
Your variety of Linux might have it somewhere else, but I've typically seen it under "Accessories" in the distros I've used.
All right, fire up a terminal and let's get started!
You won't need to remember every last thing in this section to get started with Rails, but what you'll see here lays the foundation for working in the command line, which Rails does require.
First of all, we're going to need to know how to move around, and to know how to do that it would sure help to know where we are.
pwd and hit
ENTER. In my terminal, this prints
What on earth is
pwd is a Bash command. To figure what it does, let's look at its manpage using the
$ man pwd
Whenever you see
$at the front of a line like this, it indicates that it is intended to be run in a terminal. Most systems will have some kind of special character like
$preceding the flashing cursor where your commands are typed.
Other characters sometimes used for this purpose include
I won't reproduce the whole manpage here, but just in case you don't have a terminal handy while reading along, the manpage shows "NAME" is shown to be
pwd - print name of current/working directory.
Okay... but what is
Answering this is easy, if not a little recursive:
$ man man
"man - an interface to the on-line reference manuals"
man is a command to view the manual page (manpage) for a command.
Let's go back to our results from
pwd now. What does
Any path in a Unix-like system that leads with a
/ is an absolute path for that file system. In fact,
/ all by itself is the path to the top-most directory, which is referred to as the root directory or, more simply, root.
If you're coming from Windows, this may look strange since you're likely used to absolute paths looking like
C:\Users\Brad\My Documents\. Unix-like systems don't use the physical drive prefix (like the
C:\in Windows) due to the way they allow for the mounting of partitions.
Though interesting, the details of this difference are not strictly necessary to understanding what we're doing here.
brad are both names of directories, with
brad. These names demonstrates a convention in these systems for lowercase directory names; that is, though uppercase characters are permitted in directory names, they are discouraged.
Another convention is to avoid spaces in these names, but if you insist of using them you'll have to escape the spaces with a
Any path without a leading
/ is a relative path; that is, a path relative to the working directory. For instance, if our current directory was
brad would be a relative path back to where we were (
Actually, let's give that a try.
First, let's change to the absolute path
$ cd /home $ pwd /home
then let's go back to
/home/brad/ using the relative path
$ cd brad $ pwd /home/brad
Your home directory will obviously be named something else. ...unless you're also a Brad.
cd stands for "change directory" and it's our primary means of getting around.
So now that we can move around between directories, let's create a new directory using
mkdir (as in "make directory"):
$ mkdir rails
Notice that we are using the
mkdir command and passing it the argument
rails which will be treated as a string. Equivalently, we could have done
$ mkdir "rails", but Bash already treats anything surrounded by spaces as a string.
Again, to use a literal space we would have to escape with a backslash like
$ mkdir awful\ dir\ nameor we could skip the backslash and just use quotes like
$ mkdir "still an awful dir name".
Furthermore, passing a literal string argument like this works to alleviate any issues that would be caused by special characters that hold some meaning in Bash.
Now let's check that we actually created something by listing the contents of the current directory using
ls (as in "list"):
$ ls rails
This will print
rails to the screen all by itself if the directory is otherwise empty.
cd serves as our legs in Bash, then
ls would certainly be our eyes.
ls command will take arguments, but it also accepts flags (as do many other commands). Flags are used to set options for a command as it is run.
For example, if we wanted more detailed information about the contents of the directory, we could use the
-l flag (which stands for "long listing") to accomplish this:
$ ls -l. Some flags are preceded instead by two hyphens and spell out what they're used for, like this:
$ ls --help.
Let's jump into our new directory with
cd and list its contents with
$ cd rails; ls
Here we see that we can execute several commands in one line if we separate them with a
Okay, so we're in our
/home/brad/rails directory now. How would we go back up to
Well, we could certainly do
$ cd /home/brad but that seems a bit excessive when all we really want is to simply "go back".
To look for a way out, let's add an extra flag to an
ls that will display all the contents of the current directory:
$ ls -a . ..
You'll see that this prints
.. which we didn't create ourselves. These two are special.
. means "this directory" and
.. is a reference to the parent directory.
Let's use it with
cd to get back to
/home/brad and then
pwd to check where we are:
$ cd ..; pwd /home/brad
Some systems will recognize
~as your home directory, meaning that in my case,
~will be equivalent to
/home/brad. So if we specifically wanted to go to our home directory instead of just "back", we could have used
$ cd ~.
Awesome. Now let's test the
. theory and see if it really references the current directory.
First, let's do a regular old
$ ls rails
Now, let's pass
ls an argument for the path of the directory whose contents we want listed.
$ ls /home/brad rails
Same output, good deal.
So passing it as an argument, let's see if
. gives us the same thing for "the current directory".
$ ls . rails
It sure does.
We can also use
./railsto mean "the
railsdirectory in the current directory" and even to execute certain files.
To create some files to play around with, we'll first need to understand standard output (
stdout). So far when we've been using commands like
ls that print to the terminal, what they're actually doing is printing to
stdout. Bash will print this to the terminal by default, but we can also redirect it, into files for example.
First, let's take a look at a command that simply prints its arguments to stdout named
$ echo foobar foobar
So that simply prints
foobar in the terminal, via
The beauty of doing things in the command line though is that we have several means of redirecting this
stdout. One such redirection is to a file, using
> and designating a filename.
If no file exists for that filename, one will be created and the stdout then added to it.
Let's give it a try:
$ echo "This will end up in a file." > test
You may also see
> testwritten equivalently as
>test. I kind of prefer the space for some reason.
We can even put it in front of the argument, as in
$ echo >test "Text to be echoed.".
Also, notice that even though the file just contains plain text, the filename is simply
test.txt. Unix-like systems don't get confused by filenames without extensions, but feel free to add them if you like.
Did it work?
Well let's look. We can use
cat to check the contents of our new file.
cat's manpage reads
cat - concatenate files and print on the standard output.
$ cat test This will end up in a file.
And there's our text. Perfect.
Oh, and be careful with
>, because it will overwrite the entire file. Check it out:
$ echo "This will be the entirety of the new file text." > test; cat test This will be the entirety of the new file text.
What if we want to add on to a file?
In that case, we would use
>> instead because it appends to a file. As seen here:
$ echo "Restart file" > test $ echo "Add to file" >> test $ cat test Restart file Add to file
There's also another fairly common, yet strange technique used to create an empty file. It uses the
$ touch foobar
ls to see that a new file
foobar has indeed been created.
touch, much like
cat, will create a file for you to perform its task if the file does not yet exist.
Why on earth would you want to create an empty file?
Can't think of an example, but I know I use it for this pretty frequently.
So what is the task we're asking
touch to perform?
touch is used to update the timestamps for a given file, to the current time by default. To test this out, try the following:
$ ls -l; touch test; ls -l -rw-r--r-- 1 brad brad 0 Sep 26 01:21 test -rw-r--r-- 1 brad brad 0 Sep 26 01:22 test
After running these commands, notice that the timestamps for the file
test were updated for the second
-rw-r--r--out front has to do with file permissions. We won't have to mess with these, but it's possible to adjust them using
The first spot, here
-, indicates that
testis not a directory (i.e. a file). If it were instead a directory, it would be a
The rest are grouped in threes for user, group, and other. From left to right it is possible to have
rwxwhich stands for read, write, and execution.
Thus, from the output about we can see that
testis a file, readable and writable to the user that created it (
brad), and readable by anyone else.
Another useful tool in Bash is the wildcard character
*, for globbing files. To better demonstrate this, first we'll want some more files:
$ touch test1.txt test2.txt
Now, let's say we want to list only the files in the current directory whose names start with "test":
$ ls test* test test1.txt test2.txt
You can read this in English as "list all the files [in the current directory] whose names begin with test", which is what we're looking for here.
If we wanted files whose names even just had
testsomewhere in them we could use
We could also search for all the files in the current directory that ended in ".txt" with this:
$ ls *.txt test1.txt test2.txt
And what about deleting files?
For that, we use
rm ("remove"). If we wanted to delete all the files ending in ".txt", it would look like this:
$ rm *.txt $ ls test* test
Be cautious with this command, as it will delete the files when you hit
ENTER and it will not ask if you are sure that that's what you wanted to do.
If this bothers you, you're going to love the next section on Git which, among a multitude of other things, can help us to live without fear of blowing away files accidentally.
We can also move files with
mv and copy them with
$ cd rails # change into rails for an empty directory $ touch foo # create a file to play with $ ls foo $ mv foo bar # move `foo` file to `bar` (rename the file) $ ls bar $ cp bar foo # copy `bar` file to `foo` $ ls bar foo
Anything following a
#on a line in Bash is a comment and will not be run.
Also, notice that
mvcan be used to rename files by way of moving them.
In fact, Bash offers
for's, and other language functions that we won't need to understand in this book, but they are available.
These language features may not make sense in the terminal, but Bash can be saved to file as a shell script (commonly with the extension
.sh) and run later.
We can use lowercase characters in Bash variable names, but the convention is definitely to use uppercase characters. Setting variable can be done simply with
= like so:
To access the value of a variable, we then have to use
$, as seen in this example with
$ echo $FOO bar
Another type of redirection available in Bash is the pipe. Pipes let you send the output from one command in as the input for another.
...and so on and so on, ad nauseam.
To make this interesting, let's combine some things from earlier with some new commands in an example.
While writing this book, I kept track of my total words written for the chapters as a basic benchmark for progress. To calculate this, I used the program
wc (word count) like this:
$ wc -w chapters/*
chapters is the name of the directory where all the individual chapter files are,
chapters/* is a glob of all the files in
-w is a flag to just give the word count.
And not the byte and newline counts.
At time of me writing this, the output looks like:
1363 chapters/00 2562 chapters/01 14787 chapters/02 3909 chapters/03 1522 chapters/04 2275 chapters/05 2396 chapters/06 28814 total
Proofreading Brad-of-the-future here, I totally finished Chapter 2 now. And it's well over 20k words!
You can see that each line has the name of the file it represents at the end, except for the last line, which is a total.
The thing is, I really only care about that last line, so how could I just print that?
Actually, there's probably a flag for
wcto do that, but for this example, we're going to pretend like I forgot about
manand just started reinventing the wheel like a digital barbarian.
One tool that comes to mind to accomplish this is
grep. The term "grep" has a rather interesting history, but for our purposes the manpage gives a fitting description:
print lines matching a pattern.
There is much, much more complicated stuff that can be done with
grep, but in this case, we could consider the "pattern" we are looking for to be the word "total". Put simply, we only want to print lines from the output of
wc that contain the word "total".
First, let's use
grep on a regular file, then we'll see how we can pipe
wc to it to filter its output.
You'll remember that our
test file contains the text:
Restart file Add to file
To print only the lines in the file that contain the text "Add", we could use grep like this:
$ grep Add file Add to file
The first argument we pass to
grep is the pattern to try to match and the second is the file to look in. And it works as advertised.
Derail: equivalently, we could use the
<, the standard input operator, to pass the file to
stdin.$ grep Add
But the text we want to match for
wc is being sent to
stdout, not a file, so how to we send it to
grep instead of just outputting it to the terminal?
Well, we can pipe it into
| like this:
$ wc chapters/* | grep total
This line might read in English something like: "calculate the word count for all of the files in the
chapters directory then search those for lines that contain the pattern
total and send those to
In short, the
| above passes the output from
Sometimes, you'll want to accomplish something in the command line and only to find yourself be stopped and effectively asked for your credentials.
A classic example of this is the installing of new programs with
apt-get in Ubuntu Linux derivatives, like Linux Mint.
The first argument you pass
apt-get is the action you want it to perform, which in following case is
install, and the rest of the arguments are interpreted as the names of the programs you want that action performed on.
So let's pretend I don't have
vim, my dearest text editor, installed on my system
...and that I occupy some kind of hellish, parallel dimension where I am required to use a mouse to do everything on my computer.
An initial attempt to install
vim might look like this:
$ apt-get install vim E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied) E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
There's a "Permission denied" in there along with the interrogative: "are you root?"
Not to be confused with the "root directory", "root" here refers instead to the root user (or super user) which is an account within a Unix-like system used for administrative purposes. This root user is capable of doing things that lesser users in the system cannot, such as installing new programs. If you own the machine you're on and are running a Unix-like system, chances are your user account is a super user account.
So why am I being asked if I am root?
Because Bash doesn't grant super user permissions to a terminal by default. Ostensibly, this is to prevent you from doing something accidentally or a malicious passerby from doing something intentionally to damage your system.
It can also just generally get in your way if you just want to install a new program.
"It's me, yes, go, install." - Brad Chase
If you are sure that what you typed is what you wanted to do, you can easily prove yourself authorized to do so by prefixing the same command with
sudo and then entering your password.
sudostands for "super user do".
Let's try installing
vim again, once more, with feeling. ...kidding, this time with
$ sudo apt-get install vim [sudo] password for brad:
There, now all is well with the world.
Actually, if you've decided to work through the rest of the book using some variety of Debian Linux (e.g. Ubuntu, Linux Mint, Debian), there some dependencies you should install with
apt-get to avoid problems later on when we're playing with Rails. Just run the following in your terminal:
$ sudo apt-get install curl sqlite3 libsqlite3-dev nodejs g++ libpq-dev
If you copy and paste the Bash above, be sure to remove the
$from the front of the line.
You'll also want to install Chrome within Linux. You can download an installer here. If you're using a Debian distribution, you can just click the completed download (a
.deb file) and then
If you want to view the contents of a text file in the terminal, often times
cat will be a poor choice since it will output the entirety of the file to the terminal. This functionality is great for writing to file and piping, not so much for reading.
One tool that would help here is
more will display only as much of the top of the document as can be displayed in the terminal. To see more of the document, you can press
SPACE to move down. Pressing
q will exit and get return back to a Bash prompt.
One quirk of
more is that you can only move down the document, not up. Luckily there is also a program named
less, which works almost identically, except that you can use
PgDn to move either direction in the document.
Still other times, you'll know that what you're looking for is at the very top of a text file and really just want to see that.
In this case, we'd be well served to use the
head command, which will print the first ten lines of a file.
What if wee want more? Say, twenty lines?
Then we'd specify that like so:
$ head -20 foo.txt
As you might expect, there is an opposite to this named
tail that will print the last ten lines of a text file (or however many you tell it to, same as you would with
These programs are useful all on their own, but they are very handy to pipe to as well.
When I have some piece of Ruby throwing a tremendously long error trace, I'll pipe it to
lessso I can easily scroll through it with the arrow keys, like this:
$ rake --trace db:setup | less.
ENTER after a
\ will not run the current line, but allow that particular Bash statement to continue onto the next of line of the terminal.
For example, the following are equivalent:
$ touch foo bar
$ touch \ foo \ bar
Some programs will run and run until you tell them to stop.
Our Rails server will prove to be an example of this later.
c) will send an interrupt signal that tells a program to stop what it's doing and close.
Ctrl-cin this context is often represented as
Ctrl-d represents EOF (End Of File) and will cause certain programs to close. In fact, this works as a quick way to close out of a Bash terminal.
Things like EOF and signals are something worth understanding, but well out of scope for us in this book. All we really need to know for now is that
^C closes things.
You might end up with some pretty long file names and program names that can be a pain to type out. To help keep this from driving you crazy, try tab completion.
Let's say we have a crazy long file name:
$ touch crazylongfilename
If we wanted to
cat the contents of this (empty) file, we could type
cat c then hit
TAB and have the rest of the filename filled in for us.
Now let's see what happens if the name isn't as unique for the directory:
$ touch crazy
Try to tab complete with
cat c like we did before. You'll see that the terminal finishes
crazy for you, but what about
TAB twice and you'll see both filenames listed.
Note that if there is ambiguity in the completion, no space will be left after the text.
$ cat crazyimplies that the completion is ambiguous and not complete, whereas
$ cat crazylongfilename implies that there was only one possible completion and it was made (where
is the cursor).
This difference is subtle, but easy to pick up on if you're looking for it.
By default, Bash will respond to Emacs key bindings. Here are a few that I find most useful:
||previously run line|
||next line (if used after a
||move cursor forward/back through a word|
||move cursor forward/back one character|
||kill (cut) from the cursor until the end of the line|
||yank (paste) text that was last "killed"|
||delete word under/in front of cursor (this text can also be yanked)|
||delete character under cursor|
After typing in a terminal for a while, you'll end up with your prompt at the bottom of the screen. If this gets on your nerves, as it does mine, just hit
clear the terminal and put you back up at the top.
As you might have guessed after playing around with
Ctrl-p (previously run line), Bash will keep track of what you have previously executed.
This is made even more useful with
Ctrl-r which serves as a sort of autocomplete on your Bash history.
For example, remember my
$ rake --trace db:setup | less from earlier?
Well, it's a pain to type repeatedly. And it might not be something I ran recently, so instead of
Ctrl-ping back through all of my commands, I might simply remember that I ran this recently and that it contains the text "setup". To run it again, I could simply hit
setup, make sure that the line it brings up is in fact the one I want to run, and then hit
Be sure to check that you've got the line you want. ...I've run things I didn't intend to using this method on more than one occasion.
So that's a Bash intro and then some!
Again, don't worry if you didn't catch every last thing above because we'll really only need to understand the absolute basics of the command line to use Rails later.
There's always more to learn here though, so make a point of circling back to this if you feel so moved.
Some other interesting topics include
This is one rare point in the book where I am going to cop out and not give you even a brief tutorial on a topic.
The reason for this is that I believe choosing a text editor to be an entirely subjective matter of personal preference, something that I wouldn't dare try to choose for you.
Having said that, I acknowledge that you deserve to be provided with options. And that I can do.
As noted in the previous section, I'm a fanatic user of Vim. Vim takes a different approach to text editing (modal editing) and has a purportedly steep learning curve because of this. Unfortunately, I can't honestly speak to the difficulty of learning Vim because I mostly remapped my editing habits from Emacs when I switched to Vim.
I migrated from Emacs to Vim because Emacs was making my hands hurt on an almost daily basis. I blamed this on the the fact that it requires a lot of use of modifier keys like
Alt, but I don't know if this was true.
I still have this problem with Vim from time to time on days of particularly heavy typing, but otherwise it (and a different keyboard) has seemed to do the trick. I was also pleasantly surprised to find that my thinking largely aligns with the way things are done in Vim, so I'm glad I made the switch.
Having said all that, Vim and Emacs are definitely worth taking a look later if you're interested. Additionally, they're both free, so that's great.
They are, however, not recommended for use in this tutorial. They are topics unto themselves and there is plenty of other things to pay attention to first.
So for the sake of maintaining forward motion, let's see some text editors that are super intuitive and user-friendly.
If you are working on a Mac, an immensely popular text editor for OS X is TextMate.
This one is paid.
If you are working in some variety of Debian Linux (high five!), an easy and free choice is something like
Yet another option is the cross-platform Sublime Text. I've never personally tried it, but it is used and loved by a colleague of mine.
This one has a free evaluation but is eventually paid.
Another free one I've used on and off over the years for basic editing is jEdit.
These last two options work on Windows.
So, it doesn't matter what you choose, except that it does.
Speaking in the long term, you don't want to stick with a text editor you don't like just the same as you wouldn't want to buy a pair of shoes and continue to wear them after they don't fit.
But right this minute, anything that can open, edit, and save text files will do.
Long story short: no.
Building Rails applications requires the use of a command line and the creation and editing of text files, nothing more.
Also, much of the time spent programming is spent editing code rather than writing code. The IDE's I have had the misfortune of using have largely ignored this, whereas the text editors I've used shine here.
Furthermore, I think that the text editor is the most organic relationship that a programmer can possibly have with their code. It's abstract enough that we need not be bothered with the writing bytes to spinning, magnetic disks, yet basic enough that we are fully responsible for the syntactic correctness of our typing as well as its semantic relationship to the code around it.
I believe the text editor, in its simplicity, grants to a programmer the awareness and accountability that one should have over their own work.
...but that's really just my opinion. Please feel free to use an IDE to follow along if you've found one you like.
Remember our talk about Version Control Systems?
Well, the unquestionable favorite VCS for Rails programmers is Git. And for good reason; it does its job very well.
Git was actually started by the creator of Linux, Linux Torvalds, and is used to this day in the continued development and maintenance of the Linux kernel.
So it also has that going for it.
We'll be making basic use of Git later on in our Rails tutorial, and will only need to understand a handful of steps to accomplish what we need it for. The steps are as follows:
Git is a yet another topic best illustrated by example, so let's jump right in.
Oh, and make sure you have Git installed before moving on.
In the terminal try running:$ git
If this complains
No command 'git' found, then you don't have Git installed.
On Debian Linux variants you can install it simply with:$ sudo apt-get install git
Otherwise, you can get it here.
First, we need a directory to hold the files we want to track. Let's create and move into a new directory:
$ mkdir project; cd project
Then we'll make some files:
$ touch file1 file2
Now it's Git's turn.
To start, we need to tell Git that we would like to create a repository for the current directory:
$ git init Initialized empty Git repository in /home/brad/project/.git/
This initializes a Git repo for the current directory, but note that it is an empty one.
Why didn't it just put the files into the new repo?
Because sometimes there are files that we don't want Git to track, such as files that contain passwords, secret keys, sensitive logs, etc.
We can even tell Git to ignore certain files using a
What did Git actually do to create this new repo?
All it really did was create a new directory:
$ ls file1 file2
I don't see it. Where is this
Try again with the
$ ls -a . .. file1 file2 .git
.git is a hidden directory, because Bash will hide any file or directory with a
. at the very beginning of its name.
We never want to directly mess with anything in this directory, but it is where Git is keeping track of things.
So the repo is there but empty. Let's add our files to it.
We could do this by selecting only the files we want to add:
$ git add file1 file2
or by adding everything in the directory:
$ git add .
Adding files like this tells Git that we want it to track changes to those files, but we have not yet committed the changes we've made. To demonstrate that this is the case, we can use
git status to see the status of our changes:
$ git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached
..." to unstage) # # new file: file1 # new file: file2 #
I prefer the abbreviated formatting of
git status -smyself though:$ git status -s A file1 A file2
As you can see here, Git is watching the files and sees that there are
Changes to be committed, namely that there are two new files.
In Git, a commit is something like a checkpoint that we create. We can move on, making changes and more commits for those changes, but anywhere along the way we can go back to any of the previous commits; that is, we can ask Git to change the contents of the tracked directory back to the state it was in when that commit was made.
Let's make our initial commit now:
$ git commit -m 'initial commit' [master (root-commit) 46d917e] initial commit 0 files changed create mode 100644 file1 create mode 100644 file2
We have to include a message with the commit, and so we might as well do this right along with our
git commit by using the
-m flag followed by our commit message.
As noted earlier, we'll only be covering Git knowledge that is needed for later, so we won't be looking at how to go back to a previous commit.
Even so, it makes sense to see how things progress locally from here while working with Git, so let's make a change to a file and commit the changes.
In the real world, we'd almost certainly have made some kind of change from our text editor, but since we really only need a file to be different for the sake of example, let's just
echo something into
$ echo >file1 foo
The file has changed, so let's see if Git noticed:
$ git status # On branch master # Changes not staged for commit: # (use "git add
..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: file1 # no changes added to commit (use "git add" and/or "git commit -a")
$ git status -s M file1
The output above lists our options, but let's take a look at what we might and might not want.
If we want all of the changes we've made to go in a new commit, the easiest way to do this would be to add the
-a flag on another
git commit, like this:
$ git commit -am "updated file1" [master e65a3bc] updated file1 1 file changed, 1 insertion(+)
This flag automatically stages all changes made to tracked files for the commit.
We could also accomplish the exact same thing with another
$ git add . $ git commit -m "updated file1" [master e65a3bc] updated file1 1 file changed, 1 insertion(+)
Sometimes, we won't want all of the changes to go though. In this case we would just
git add the files we want staged for the commit:
$ git add file1 $ git commit -m "updated file1" [master e65a3bc] updated file1 1 file changed, 1 insertion(+)
These are all equivalent since we've only changed one file, but do note that we don't have to stage all changes for the next commit.
Git does a great job versioning changes locally, but it also makes it easy to store your code remotely, share your code with the world, and collaborate with others. There are a number of ways to do this, but one of the most enjoyable ways is to use GitHub (pronounced "get-hub").
GitHub offers free (public) remote Git repositories along with a bunch of other helpful tools. Feel free to look around at all they have to offer, but we'll be focusing on the fact that they'll grant us a free remote repo.
First, you'll need to sign up.
Then, you'll need to create a new repository.
After you create the repo, the folks at GitHub give you some incredibly timely information, telling you how to
Push an existing repository from the command line.
Follow what you see displayed there, but it looked something like this for me:
$ git remote add origin email@example.com:bchase/reponame.git $ git push -u origin master Counting objects: 9, done. Delta compression using up to 4 threads. Compressing objects: 100% (6/6), done. Writing objects: 100% (9/9), 683 bytes, done. Total 9 (delta 0), reused 0 (delta 0) To firstname.lastname@example.org:bchase/reponame.git * [new branch] master -> master Branch master set up to track remote branch master from origin.
We don't really need to understand all of that (I don't), but these two lines pretty straightforward:
originof our changes to the
We haven't covered branches, but suffice it to say that our changes earlier ended up in the
masterbranch by default.
After this if we add and commit changes, we can push them up to this remote repo much more easily with just:
$ git push
So that concludes the amount of Git knowledge we will need later and covers most of the absolute basics.
If you're interested in learning more about Git, this is a terrific resource put together, as it happens, by the good people at GitHub.
So far it's been all sunshine and rainbows talking about these different languages and tools, but the truth is: sometimes things are confusing and, perhaps more often, they break.
If you run into an error or problem that you can't figure out, try googling it.
Chances are, if your query has to do with programming terms, you'll find a Stack Overflow question in the top results.
Stack Overflow is a site that allows users to ask questions and then lets their peers answer and vote for the best answer among those given. This system works better than anything else I've seen and I cannot recommend it highly enough.
And do be sure when using Stack Overflow to first search for a question similar to yours before asking your own. People do not take kindly to seeing duplicate questions and you will likely hear about it.
Well, that concludes the non-Ruby tools we'll be needing to build our Rails app.
Why not cover the Ruby tools here too?
Because they're in the very next chapter!