Skip to content

Instantly share code, notes, and snippets.

@tfnico
Created July 4, 2012 20:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tfnico/3049457 to your computer and use it in GitHub Desktop.
Save tfnico/3049457 to your computer and use it in GitHub Desktop.
Me and @fhd's trygit.org tutorial
#!
cd /tmp
mkdir stuff
cd stuff
echo "Chapter one: it was a cold and stormful night" > essay.txt
cp essay.txt essay.new.txt
echo "Chapter two: The Commitments" >> essay.new.txt
cp essay.new.txt essay.txt.bob
echo "Chapter three: And then along came the butler" >> essay.txt.bob
cp essay.new.txt essay-2011.10.12.txt
echo "Chapter three: There's something rotten" >> essay.new.txt
➜ ~/projects/trygit/[master]>cat trygit-tutorials/1-intro/tutorial.txt
Try git!
Let's get to it!
<run init-stuff.sh>
So, you've got a folder of important files. Type 'ls' to see what's going on there..
> cd stuff
> ls
Notice this is more or less the same content, where you've made various backups and copies every time you change something major.
Over time, it gets a bit messy. You don't know which file is the newest, you don't know where you wrote that new chapter, and so on.
Historically, programmers have been especially prone to this kind of mess, and most of them have at some point come up with their own organized way of making copies and backups, to keep track of what code the put together at what time.
To deal with this very typical problem, source code management (SCM), or revision-control systems came into existence.
Now there are some very popular SCMs in use today, like CVS, Subversion and so on. The problem with these alternatives are that they require a lot of setup, a server, and generally a lot of infrastructure to get up and running. Frankly speaking, they are also pretty crappy in terms of functionality, compared to modern SCMs like Git.
Enough babbling. You want to use Git to take care of your stuff! In Git terms, you want to turn your 'stuff' folder into a _repository_. This is how:
> git init
Well done! You have now created a git repository. It is still empty though. Even though there are a bunch of files in the directory, none of them have physically entered the repository yet. To actually see this, type:
FGTD (Funky Git Term Definition): A git repository usually looks like a folder that contains a hidden folder '.git/' - inside of which all the history of your files are stored. You usually have one repository for each project you have going at the time. This could be a school-assignment, your life-long diary, or an open source project. It is generally a bad idea to put different things that don't belong together in the same repository. You can create as many as you like, so make a new one for each "thing" you're doing.
> git status
The result tells us that there are some "untracked" files here. Let's try "tracking" our essay. We'll start with the oldest version we have, and track that first. Let's say the one simply called "essay.txt" is the oldest:
> git add essay.txt
Now, let's check that status again:
> git status
Now git tells us that there is a new file to be committed. Let's do that:
> git commit -m "First version of the essay"
Congratulations! You are now a "committer".
The sentence after -m is our _commit message_. It's a note to our future self on why we made this change, and as you can imagine, these messages become pretty valuable over time when we're trying to remember why we did what.
FGTD: Although we're speaking of adding *files* to the repository, we are actually adding *changes*. This time the changes happens to be a new file, but later on, we will be adding changes in the shape of modifications to files that already exist.
Let's study what we just did a bit.
Entering files into the repository is a two-step process:
1) Add them to the staging area, where you prepare which of your files will go into the repository
2) Commit the staging area into the repository.
FGTD: The staging area is more correctly called 'the index'. Although it might seem a bit of effort to *first* add stuff to the index, and *then* commit them, this turns out quite handy when you've made a lot of local changes, but you only want to commit a few of them in one go.
Commits are the main citizens of any SCM. The history of your project is made up of a chain of commits, all linked together. Our repository now has its first commit, so let's have a look at it:
> git show
Here you see all that went down in your latest commit:
* A cryptic looking series of 40 numbers and letters. This is the unique commit identifier, aka the SHA, or hash.
* Name and email of the one who made the commit (you)
* Date
* Diff, which is a line-by-line breakdown of what was added and/or removed in this commit. In this case, we have only added one line. You can see it is added because it has a plus (+) sign in front of it. Removed lines are marked with a minus (-).
FGTD: You can actually use git show on a variety of things, like different commits, branches, tags, files, and so on. If you don't specify anything, it will implicitly show you the HEAD commit. This is a very important term in git. HEAD is like a symbolic flag that is always pointing at your latest commit.
So, we have tracked the first and original version of our essay. Now let's proceed to the next version. We'll overwrite the essay.txt with the file we happen to know was the next one we saved. Don't worry about accidentally losing old stuff in essay.txt, we can always retrieve it from history.
> mv essay-2011.10.12.txt essay.txt
Alright, now before we commit, let's see what changes we have:
> git status
The essay.txt has been changed, but not staged for commit. We'll fix that in a moment. Let's see what exactly has changed first:
> git diff
Ah, we have added a new line to the essay. That should be safe to commit.
> git add essay.txt
> git commit -m "Second version, saved on 2011-10-12"
Well done! You can do another 'git show' to see that it worked as expected.
Onwards with the next version of the file:
> mv essay.new.txt essay.txt
> git diff
Now a third line should be added.
This time, instead of staging essay.txt again with 'git add', we'll commit all modified files in one swoop with the -a parameter:
> git commit -a -m "Third version"
Now we only have one unversioned file left. This one contains a chapter our friend Bob contributed during the holidays. We can't quite remember when he wrote it, but let's move it onto the essay.txt file and look at the diff:
> mv essay.txt.bob essay.txt
> git diff
It appears that the latest file version replaces the contents of chapter three. That means Bob has written a chapter 3, although we already had one. This isn't what we intended for him to do, but he probably based his work on an older copy of our essay.
Let's fix this. We could say that Bob "branched out" after we had written (or committed) the second chapter. We can express exactly this in the revision history using a git branch. We first create a branch called "bobs-chapter" based on the second version (the last version Bob and us have in common).
> git branch bobs-chapter HEAD~2
We will now switch to work on this branch, and commit Bob's work:
> git checkout bobs-chapter
[this is as far as I got]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment