Setting up a remote git repository
Posted by Mark Fenoglio under Git, Mac OS X for IWFrameworks
December 22, 2009

While a subversion repository typically manages many projects, git is a project-centered technology. For each project I create, I want to be able to manage my local repository such that I can push production-ready versions out to remote servers. For example, several client applications are built using the Istarel Workshop frameworks: When a new stable release is ready, I want to be able to easily deploy that new version to client servers to replace the previous framework release.

Create the remote repository

I first need to create a bare repository on the remote server.

markf$ ssh user@www.istarelworkshop.com
user$ mkdir -p git/fw && cd git/fw
user$ git --bare init
Initialized empty Git repository in /path/to/git/fw/
user$ exit

What exactly is a bare repository? Git generally assumes you want a working repository; that is, an active repository where a whole host of change-related activities will be taking place. But that isn't what I want here. I don't need all the history and file detail that a .git directory usually implies. All I need for this remote repository is the repository itself (i.e., the project files in the state as defined by a push to this remote server).

Inform the local repository

Before I can push to that remote repository on www.istarelworkshop.com, I need to modify the configuration file of my local repository. To show the evolution of our local git repository through this process, here is the initial configuration state in my working repository.

markf$ cd ~/Sites/fw
markf$ cat .git/config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true

In order to communicate with that remote repository, the local working repository needs to know about it.

markf$ git remote add workshop
       ssh://user@www.istarelworkshop.com/path/to/git/fw
markf$ cat .git/config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
[remote "workshop"]
    url = ssh://user@www.istarelworkshop.com/path/to/git/fw
    fetch = +refs/heads/*:refs/remotes/workshop/*

Create an ssh key

At this stage, remote push to my www.istarelworkshop.com repository will work just fine. However, it will require me to enter my password every time I do so. To simplify future automation of push-related processes, and to lay the foundation for more secure remote interactions, I will create a private/public ssh key.

I create the keys on my local machine and then copy the public part of the key to the remote machine.

markf$ cd ~/.ssh
markf$ ssh-keygen -t dsa

Leave the passphrase empty (you will be prompted twice for the passphrase). At this point, I have created a private (~/.ssh/id_dsa) and public (~/.ssh/id_dsa.pub) key. I want to copy the public key to the remote server.

markf$ ssh user@www.istarelworkshop.com
user$ mkdir .ssh && cd .ssh
user$ vi authorized_keys

Paste the contents of the local public key into ~/.ssh/authorized_keys on the remote server. Note: if the .ssh directory already exists on the remote server, you may only need to append the contents of ~/.ssh/id_dsa.pub to ~/.ssh/authorized_keys.

Deploy to the remote repository

With the preliminary work complete, I can now push the Istarel Workshop frameworks out to www.istarelworkshop.com.

markf$ git push workshop master
Counting objects: 287, done.
Compressing objects: 100% (279/279), done.
Writing objects: 100% (287/287), 165.89 KiB | 84 KiB/s, done.
Total 287 (delta 68), reused 0 (delta 0)
refs/heads/master: 0000000000000000000000000000000000000000 ->
                   9da9ef18470740afe623966eec4dbf45cd22788b
To ssh://user@www.istarelworkshop.com/path/to/fw
 * [new branch]      master -> master

The last step is to clone that remote repository so that the framework files are accessible to applications.

markf$ ssh user@www.istarelworkshop.com
user$ git clone git/fw fw
Installing and using Git
Posted by Mark Fenoglio under Git, Mac OS X for IWFrameworks
December 18, 2009

Installing git is always a simple procedure, but with MacPorts, it becomes a one line Unix command. I also want to set some key configuration settings for git.

markf$ sudo port install git-core
markf$ git config --global user.name "Mark Fenoglio"
markf$ git config --global user.email markf@istarelworkshop.com
markf$ git config --global color.diff auto
markf$ git config --global color.status auto
markf$ git config --global color.branch auto

The first two git config commands set important defaults for identifying the author of changes to the repository. The last three commands are to provide color when git presents information in the console.

Istarel Workshop Frameworks

I intend to eventually migrate all my projects to git, but I want to start with the Istarel Workshop frameworks. This will give me a chance to establish some best practices, particularly with respect to deployment. Before I start, I want to remove all of subversion's hidden directories.

markf$ cd ~/Sites/fw
markf$ find . -type d -name '.svn' -print0 | xargs -0 rm -rdf

Now I am ready to establish the git repository for my frameworks.

markf$ git init
Initialized empty Git repository in /Users/markf/Sites/fw/.git/

All that I've done at this point is create an empty working directory. Now I need to populate my local repository with the initial snapshot of the project.

markf$ git add .
markf$ git commit

When the commit happens, an intermediate file is opened in your designated editor and you should create the commit message there. When that temporary file is saved, git saves the initial version of my project.

Commit in Git
Nugget posted by Mark Fenoglio
October 4, 2009

In Git, each commit is a product of all the modifications and new files added to the working copy. Unlike with Subversion, where all modified files are assumed to be part of the commit, Git requires you to explicitly add them. Fortunately, there is a handy shortcut for adding everything.

markf$ cd ~/Sites/fw
markf$ git add .
markf$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#    modified:   controller/IWOrderedListController.php
#    modified:   html/IWRequest.php
#    modified:   html/IWURL.php
#    modified:   navigator/IWNavigator.php
#    modified:   test/Autoload.php
#    new file:   test/html/IWRequestTest.php
#

When you add modifications and new files in this fashion, Git also respects its own ignore list.