I wanted to try out git on the Mac. I'm reading the book Pragmatic
Version Control Using Git by Travis Swicegood. There's a forum
discussing this book on the Pragmatic Programmer's site,
http://forums.pragprog.com/forums/64.
The forum seems to be more focused on reviewing the
book than discussing git issues, however.
Installing and Configuring
I have a Mac Book Pro (Intel) with Snow Leopard. To get MacPorts I
went to the site http://www.macports.org/install.php
and clicked on Snow Leopard.

Once MacPorts is installed, I issued the command
newtricks:~
ted$ sudo port install git-core +svn +doc
There's a Pragmatic Programmer forum entry that discusses how this
macport installation of git did not work, but it worked fine for me.
I can tell git is installed and working by checking its version.
newtricks:~
ted$ which git
/opt/local/bin/git
newtricks:~
ted$ git --version
git
version 1.6.5.7
newtricks:~
ted$
There are only two required configuration values: user.email and
user.name. Here's how you set them; they are silent commands.
git
config --global user.name "Ted Kubaska"
git
config --global user.email "ted.kubaska@gmail.com"
Although not required, the configuration value color.ui is useful.
It color codes various git output. I'll show some examples later.
Display the configuration as follows.
newtricks:~
ted$ git config --global --list
user.name=Ted
Kubaska
user.email=ted.kubaska@gmail.com
color.ui=auto
newtricks:~
ted$
Creating a Git Repository
Creating a git repository is pretty easy, in fact trivial. Just
make a directory, enter it, and issue a git init. Then you can add
files into this repository with git commit. This directory will be
the working tree of code you check out from the repository. The
repository metadata is in the directory/.git, and, guess what, its
contents don't look like CVS.
So I do this ...
newtricks:GitRepo
ted$ mkdir tedsrepo
newtricks:GitRepo
ted$ cd tedsrepo/
newtricks:tedsrepo
ted$ git init
Initialized
empty Git repository in /Users/ted/GitRepo/tedsrepo/.git/
newtricks:tedsrepo
ted$ ls -a
. .. .git
newtricks:tedsrepo
ted$ pwd
/Users/ted/GitRepo/tedsrepo
newtricks:tedsrepo
ted$
Then, in that directory, make a file (call it hello.html) to add
to the repository.
newtricks:tedsrepo
ted$ git add hello.html
newtricks:tedsrepo
ted$ git commit -m "Initial checkin for hello.html"
[master
(root-commit) f2c49ba] Initial checkin
for hello.html
1
files changed, 6 insertions(+), 0 deletions(-)
create
mode 100644 hello.html
newtricks:tedsrepo
ted$ git log
commit
f2c49baf3abafefb03b941db75ae4c026b0c877e
Author:
Ted Kubaska <ted.kubaska@gmail.com>
Date:
Tue Dec 29 21:07:15 2009 -0800
Initial
checkin for hello.html
newtricks:tedsrepo
ted$
Make a change in hello.html. Before you can commit the changed
file, you must stage it. This is something that seems unique to git.
You edit a file, and then you can't just commit it ... you must stage
it first.
newtricks:tedsrepo
ted$ git status
#
On branch master
#
Changed but not updated:
#
(use "git add <file>..." to update what will be
committed)
#
(use "git checkout -- <file>..." to discard changes
in working directory)
#
# modified:
hello.html
#
no
changes added to commit (use "git add" and/or "git
commit -a")
newtricks:tedsrepo
ted$
Notice that a modified, but unstaged file is shown in red. This is
a result of that color.ui configuration value.
So stage the file before committing. Stage with git add. Note that
the filename becomes green.
newtricks:tedsrepo
ted$ git add hello.html
newtricks:tedsrepo
ted$ git status
#
On branch master
#
Changes to be committed:
#
(use "git reset HEAD <file>..." to unstage)
#
# modified:
hello.html
#
newtricks:tedsrepo
ted$
Then, commit.
newtricks:tedsrepo
ted$ git commit -m "added head and title"
[master
4b7d2f1] added head and title
1
files changed, 3 insertions(+), 0 deletions(-)
newtricks:tedsrepo
ted$
Branches
With CVS, I've always been very careful not to proliferate
branches. But I think (from what I've read so far) that branches are
key to the way people use git.
The name of the default branch in git (the branch you start with,
the mainline, if you will) is called master. Master in Git is what I
would call HEAD in CVS.
I thought it was interesting that you can create a branch,
checkout the branch, edit a file and commit it to the branch. Then,
checkout the master and edit and commit. You now have one version of
the file in the branch and another in the master. Now if I rebase the
master, the file in master has the changes that were made in the
branch as well as the changes made on master. This sounds like a
merge to me, although it's not technically a merge because there is a
merge command. I suppose I'll see the difference when I start using
the merge commands.
Here's what I mean in more detail. The following figure
illustrates the actions I'm describing.
Let's say I'm on the master branch of my git repository. I put
three lines in that file. I commit the file, then make a branch
called R1.0. I edit the file again while still on master (the file
now has four lines) and commit it.
Master
line 1
Master
line 2
Master
line 3
Master
line 4 <-- this is the line I added on master (not the branch)
Then, I checkout the branch and edit/commit the file.
Master
line 1
Release
line 1 <-- this is the line I added on the branch (not master)
Master
line 2
Master
line 3
Then, I checkout the master and rebase master with the branch. My
file now has the changes from both
the branch and master.
Master
line 1
Release
line 1
Master
line 2
Master
line 3
Master
line 4
Here's the output I got from the rebase command.
newtricks:tedsrepo
ted$ git rebase R1.0
First,
rewinding head to replay your work on top of it...
Applying:
added 4th master line
Using
index info to reconstruct a base tree...
Falling
back to patching base and 3-way merge...
Auto-merging
hello.txt
newtricks:tedsrepo
ted$ git branch -d R1.0
Deleted
branch R1.0 (was f3a999b).
As I said, it looks like a merge to me, but I've more to learn.
What is also interesting is that (with the branch checked out),
you can tag it. Then, you can checkout master, rebase master with the
branch, and actually delete the branch. You can restore the branch by
make a new branch from the tag, like ...
newtricks:tedsrepo
ted$ git branch R1.0 1.0
where 1.0 is the tag. I made the tag when the branch (called R1.0)
was checked out as
newtricks:tedsrepo
ted$ git tag 1.0 R1.0