Git Setup - 2011

Some information on how I am using GIT.

My Git Tools: Git Add, Git List, Git Update Set

Other: Git Annex, Git Tutorials

Working Environment

The following are my main machines where I work:

  • Laptop - my main laptop, although I have a few
  • Workstation - home workstation
  • Office - there are a number of these, depending on where I am working
  • Shared - server for mostly windows users accessing files via samba.


Here are a set of repositories I work with:

  • main (need a better name) - the repository which eventually code needs to go back to
    • github/* lots of git hub repositories I work with
    • XCSoar
    • work/* lots of business and work related repositories
    • private/* lots of private repositories
    • libraries/* Many libraries, e.g. ExtJS, Sencha Touch, do not come as GIT. But I want to keep them for diffs etc.
  • backup - a location which is useful as backup and for moving between Workstation and Laptop
  • key - USB Key. Some work repositories can only be sync by USB Key, no internet access

Local Directory Tree

How do I setup the tree.

  • ~/pad/ - General projects. Fairly free form
  • ~/shared/ - My shared things with other local users
  • ~/$company/ - A company set of projects


What special tasks do I need to do?

  • git_add bak key s3 - Add "Key" or "Backup" repository to existing git repo
    • Ignore if key already exists
    • Look for root path (predefined set, e.g. /Volumes/X, /media/X, etc) automatically (must exist) if KEY.
    • Look for existing bare repository on root path, or SSH server
    • Otherwise create a bare repository from this one (same name as directory)
  • git_update_set - Pull/Push all "Key" or "Backup"
    • Find all repositories (one level deep I think)
    • Pull/Push each matching repository name
cd ~/tmp/
git clone --bare $GITDIR
rsync -av $NEWDIR git@server:~/
git remote add origin git@server:$NEWDIR
git push origin master
git config branch.master.remote origin
git config branch.master.merge refs/heads/master

Creating a bare repository

  • git clone, will pull. So it works if I ssh to my server first... but that is painful
  • One way is to use git clone to a temporary location and rsync it across, again painful
    • OLDDIR=`pwd`; mkdir /tmp/a; cd /tmp/a; git clone --bare $OLDDIR; rsync -a $X git@...:~/

Some Worked Examples

Workstation first time

For example, I want to get my shared files setup correctly. These are pretty simple, as there is really just one origin.

  • mkdir ~/shared/
  • cd ~/shared
  • foreach a,b,c - git clone git@localserver:a ...

Now for a harder example...

Using JS Libraries

I now have a basic javascript library...

# Download library, e.g. ExtJS 4.0
# Extract into ~/pad/ExtJS/, removing the version number
git init; git add *; git commit -m 'original 4.0.0'; git tag 4.0.0
cd ../tmp; git clone --bare ../ExtJS; rsync -av ExtJS.git git@yourserver:~/; cd ../ExtJS
git remote add origin git@server:ExtJS
git push origin master
git config branch.master.remote origin
git config branch.master.merge refs/heads/master

Special Case - Non-standard repository

In at least two instances, I need to keep two separate repositories for releases. In one case this is because we can only release publicly changes that have been approved. This means that our history must not be released. One way to do this is to generate and apply patches. Fortunately it is really only a one way thing at the moment.

Sharing with the family

We have a server here which is used to store things like Network Point plans for our house. It is on the file server as 3 out of the 4 users are using a spreadsheet program to read / write and are not in a position to learn/use git (well not yet).

  • Dealing with binary files, e.g. XLSX, etc ?
    • Merging?
  • Remote file system, specifically SMB on Mac & LInux - git issues, e.g disabling permissions, user, groups
  • GIT
    • git init

Big issue with SMB Shares

I can't "git clone" on a SMB File Share. It always displays: "error: could not commit config file". But I have discovered that if I use git clone on my local disk, then rsync that to the SMB share, then all push, pull, commit work correctly.

Updating the Shared Set

As no one else using the shared set uses git, it all has to be done by me:

cd $ServerDir/Example/Shared
git commit -a -m 'Shared updates'
git pull
git push
cd ~/shared/Example
git pull


Don't forget to:

git config --global "Scott Penrose"
git config --global ""
git config --global github.user scottp
git config --global github.token SECRET!
git config --global color.diff auto 
git config --global color.status auto 
git config --global color.branch auto

Found this great new one here:

git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

then type "git lg"

Workflow - feature branch

  • clone the remote repo
  • git co -b my_new_feature
  • and commit some stuff
  • git rebase master
  • and commit some stuff
  • git rebase master
  • ..finish the feature
  • git co master
  • git merge my_new_feature


Complicated Workflows

Feature branch, Backup repository, Single patch

I am working on multiple features at once. To help I keep a separate branch for each. I use a remote repository to allow me to backup (if it is not pushed to a remote repository it is not real. Never trust a hard disk), and to allow easier move between workstation and desktop. The project requires a single commit for single feature.

  • Start with a clean branch as close to time from master
  • Work on changes in branch, testing etc
  • Rebase from master for updates
    • git checkout master; git pull origin master; git checkout feature; git rebase master
  • Squash your commits (git rebase -i YourFirst) (should we do this before or after rebase master)
  • Request pull from this branch

See Also

Old information

Git and my love/hate relationship

  • NOTE: This is from about 2009 - I still have these issues to understand, but it is now a little out of date...

Although my title uses hate, I love git. It is the answer to my SCM dreams.

Git is powerful, with that power also comes a long learning curve. There are things about Git which are quite hard. Now I would not change them, they are an advantage. It is like a powerful programming language. But they are hard...

Projects I now use Git with: Ext.Direct, Perl6, Most of my Perl modules and ExtJS libraries. See

Laptop, Server, Workstation

Let me say right here, and up front, the problems I am having are because I am a n00b - and I am writing them down here to help others, and to find the solutions...

A basic scenario I use when starting a project is this.

  • Start git repository on my laptop
  • Create a blank on the server, push from laptop to server.
  • Create a blank on my workstation, pull from server.

OK All good. Now on my workstation I decide to rename some files. Note that at this point, all is committed and pushed to the server, so git push says up to date, and git status says up to date.

  • Laptop - rename files, git commit, git push
  • Workstation - git pull - BANG !!!!

I always end up with:

error: Entry 'www/lib/RandomFile.js' not uptodate. Cannot merge

Regular problem with pull from GitHub

extjs-direct-perl$ git status
# On branch master
nothing to commit (working directory clean)

extjs-direct-perl$ git pull origin master
 * branch            master     -> FETCH_HEAD
error: Entry 'README' not uptodate. Cannot merge.
fatal: merging of trees b8cdcc4a9d6a2911f18f4d84de114ab9a0ee7cc5 and 2ce28d50ce3f126bb083601a871c47cda0396756 failed

extjs-direct-perl$ git push origin master
 ! [rejected]        master -> master (non-fast forward)
error: failed to push some refs to ''

What do I do?

FYI: I suspect a bug. I worked around and around on this, even updating to git 1.6.4 and the following sequence, along the way... fixed the problem:

 1093  git fetch origin master
 1094  git merge master
 1095  git status
 1096  git checkout -f
 1099  git status
 1100  git push origin master
 1101  git push --help
 1102  git push -v origin master
 1103  git pull origin master
 1104  git status
 1105  git diff
 1106  git diff
 1108  git push origin master

Why, which one, I can't tell... will have to wait until it happens again.

NOTE: I always get, after a pull, something along the lines of

scottp@Ermintrude:1106:/Volumes/ubuntu/4gw/extjs-direct-perl$ git diff
diff --git a/module/RPC/ b/module/RPC/
old mode 100644
new mode 100755
diff --git a/module/wrap.cgi b/module/wrap.cgi
old mode 100644
new mode 100755

I suspect therefore that my problems are around mode changes rather than content.