Using Git to collaborate

2008-01-08 3-minute read

After spending weeks enraptured by the potential of git, I finally sat down and tried to setup a working environment in which two people could collaborate. It was harder than I thought.

The difficulty was compounded by a number of dumb mistakes in my setup. I finally figured it out with the help of Big Jimmy and by tailing my apache error log when trying to access my remote repositories to figure out what I was doing wrong (it showed a number of “file not found” messages).

Here’s a transcript of how I got it to work. I did all the work in a test environment on liberace (my laptop). I setup http://a.git-remote.liberace/ to point to a directory on my filesystem called a.git-remote and http://b.git-remote.liberace/ to point to a directory called b.git-remote.

# first create the initial collaborator's local repository:

0 jamie@liberace:git-test$ mkdir a.git-local
0 jamie@liberace:git-test$ cd a.git-local/
0 jamie@liberace:a.git-local$ git init
Initialized empty Git repository in .git/
0 jamie@liberace:a.git-local$ echo "a test" > test.txt
0 jamie@liberace:a.git-local$ git add test.txt
0 jamie@liberace:a.git-local$ git commit test.txt
Created initial commit 9461675: Test from a.
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 test.txt

# Next, create the initial collaborator's remote repository (this would
# normally be done via ssh). Notice how I move the initially created
# .git directory to a more reasonably named directory (is there a better
# way to do that with the git init command?).
#
# Also - notice how I chmod the post-update script - that causes git to
# update the server info every time a commit is made.

0 jamie@liberace:a.git-local$ cd ..
0 jamie@liberace:git-test$ git init
Initialized empty Git repository in .git/
0 jamie@liberace:git-test$ mv .git a.git-remote
0 jamie@liberace:git-test$ chmod 755 a.git-remote/hooks/post-update

# Now push local changes to the remote repo. This would normally be done
# over ssh
0 jamie@liberace:git-test$ cd a.git-local/
0 jamie@liberace:a.git-local$ git push ../a.git-remote/ master
Counting objects: 3, done.
adding b.
Writing objects: 100% (3/3), 223 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
To ../a.git-remote/
* [new branch]      master -> master

# now setup the second collaborator I use the git remote add
# command to add an alias so I don't have to retype the full
# URL every time. Maybe this step should be down with git clone?
0 jamie@liberace:a.git-local$ cd ..
0 jamie@liberace:git-test$ mkdir b.git-local
0 jamie@liberace:git-test$ cd b.git-local/
0 jamie@liberace:b.git-local$ git init
Initialized empty Git repository in .git/
0 jamie@liberace:b.git-local$ git remote add a http://a.git-remote.liberace/
0 jamie@liberace:b.git-local$ git pull a master
got 9461675b66f4e08cee6bee4e2f59736ff245ce64
walk 9461675b66f4e08cee6bee4e2f59736ff245ce64
got 970281b52e49f9bd0a70cf8dbf4fea49485d13ce
got 5fc6b4bc688dd10d9ad952716029ccaac0f2fb8e
0 jamie@liberace:b.git-local$ ls
test.txt

# second collaborator commits a change:
0 jamie@liberace:b.git-local$ echo "test b" >> test.txt
0 jamie@liberace:b.git-local$ git add test.txt
0 jamie@liberace:b.git-local$ git commit test.txt
Created commit 7f969da: adding b.
1 files changed, 1 insertions(+), 0 deletions(-)

# second collaborator creates remote repository
0 jamie@liberace:b.git-local$ cd ..
0 jamie@liberace:git-test$ git init
Initialized empty Git repository in .git/
0 jamie@liberace:git-test$ mv .git b.git-remote
0 jamie@liberace:git-test$ chmod 755 b.git-remote/hooks/post-update

# second collaborator pushes changes to remote repo
0 jamie@liberace:git-test$ cd b.git-local/
0 jamie@liberace:b.git-local$ git push ../b.git-remote/ master
Counting objects: 6, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (6/6), 445 bytes, done.
Total 6 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
To ../b.git-remote/
* [new branch]      master -> master

# initial collaborator pulls in second collaborator's changes
0 jamie@liberace:b.git-local$ cd ..
0 jamie@liberace:git-test$ cd a.git-local/
0 jamie@liberace:a.git-local$ git remote add b http://b.git-remote.liberace/
0 jamie@liberace:a.git-local$ git pull b master
got 7f969da23ffb57b70405a9e9fc62ae39cedd0f1b
walk 7f969da23ffb57b70405a9e9fc62ae39cedd0f1b
got 52f8ddad8dc10896059f68a48d4cb3b3175556ed
got 8f9ad5050475fa0981c9d0f911381ffa7ddb7c51
Updating 9461675..7f969da
Fast forward
test.txt |    1 +
1 files changed, 1 insertions(+), 0 deletions(-)

# lo and behold! the chages are present:
0 jamie@liberace:a.git-local$ cat test.txt
a test
test b