Git Setup - 2011
Some information on how I am using GIT.
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
- 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
GITDIR=`pwd` cd ~/tmp/ git clone --bare $GITDIR rsync -av $NEWDIR git@server:~/ cd $GITDIR 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
# 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 ?
- Remote file system, specifically SMB on Mac & LInux - git issues, e.g disabling permissions, user, groups
- 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 user.name "Scott Penrose" git config --global user.email "email@example.com" 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: http://coderwall.com/p/euwpig?i=3&p=1&t=git
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
- ..work and commit some stuff
- git rebase master
- ..work and commit some stuff
- git rebase master
- ..finish the feature
- git co master
- git merge my_new_feature
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
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...
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 From firstname.lastname@example.org:scottp/extjs-direct-perl * 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 To email@example.com:scottp/extjs-direct-perl.git ! [rejected] master -> master (non-fast forward) error: failed to push some refs to 'firstname.lastname@example.org:scottp/extjs-direct-perl.git'
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/ExtDirect.pm b/module/RPC/ExtDirect.pm 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.