Git is easy to setup locally. You might be in a directory, working on a new project, and you just do a:
local$ git init
local$ git add .
local$ git commit
... and suddenly you're all setup. But what if you've done this locally, and you want to use a remote repo as a backup of this local repo?
remote$ mkdir yourproject.git
remote$ cd yourproject.git
remote$ git init --bare
local$ git remote add origin ssh://yourserver.tld/~/yourproject.git
local$ git push origin master
... and you're done! From then on you should be able to simply do a:
local$ git push
... to continue to "backup" your repo.
If Git is complaining about trailing whitespace in the files you are trying to commit, and you don't think it should be (that's your decision) then you can stop it whinging by changing your config:
$ git config core.whitespace -trailing-space
Now add and commit again.
Want this to work on all your git repos, not just the current one?
$ git config --global core.whitespace -trailing-space
If, when trying to commit, you ever get a message like:
unable to create temporary sha1 filename sha_hash File exists
... from git, you need to do a few things from within the root level of your git repo.
$ git fsck
# should show you some dangling objects
$ git gc
# should show you some progress as it prunes old dangling objects
If committing still doesn't work after this, you need to try:
$ git prune
... because git-gc by default only prunes dangling objects that are older than two weeks, whereas prune gets them all.
My error still hadn't gone away after this. Turns out I had accidentally done some git adding as root instead of the user I currently was. So I needed to do this:
$ sudo git gc
$ sudo git prune
Then I:
$ sudo chown -R myusername: .git/
... to make sure all the objects belonged to me. Committing then worked fine!
I'm building a new virtual machine and I'd forgotten how to tell git who I was. Here it is:
git config --global user.name "Citizen Snips"
git config --global user.email "snips@mailinator.com"
The Git FAQ has an entry of note:
Why won't I see changes in the remote repo after "git push"? The push operation is always about propagating the repository history and updating the refs, and never touches the working tree files. In particular, if you push to update the branch that is checked out in a remote repository the files in the work tree will not be updated.
This is a feature not a bug, despite what certain other bloggers will tell you. Why? Because you might have some uncommitted changes in the remote repo - and you don't want a git-push from somewhere wiping them out without getting a chance to commit them.
That being said, suppose you do want the remote repo to automatically update its working tree when you do a git-push. Well, you can get a nice post-update hook here http://utsl.gen.nz/git/post-update
Or, if you are certain your remote repo hasn't been changed (git-status can help you find this out) then you can simply run:
remote$ git reset --hard HEAD
... on it (the remote repo) and the repo there will match the repo that you pushed from.
(Oh yeah, this tip obviously only applies to remote repos that haven't been initialised with the --bare option... so it only applies to a specific type of workflow.)
Why are SCM and ticket systems separate?
e.g. Why use git or svn and then have to tie them in with RT or Jira? Couldn't there be a nice command line utility that reports on tickets and bugs too?
Instead of tying commits to bugs in external reporting systems, it would be great to issue some command in your SCM to:
... etc.
On the right you will notice a new tag cloud. I wrote a tag_cloud templatetag in Django for it. Generating a tag cloud involves a little calculation, so I cached it using Django 1.0's Template Fragment Caching. It lets me wrap anything in a template with a cache templatetag, specifying seconds to cache for.
I have two separate cache settings, one for dev and one for prod environments (in their corresponding settings files.) They are using Django's filesystem caching - so the cache is just stored on disk. I am storing the cache in a subdirectory of the codebase, but I don't want the cache being carried around in the Git repo, so I added:
/cache/*
... to my .gitignore file in the codebase root. Nice!
As you are no-doubt aware, I am developing this blog with the aid of Git. Since it is just me, I am working on master and intend on releasing straight from there. (On a larger project you might branch first, create release candidates etc, and then eventually tag and release from the branch.)
So, to tag and release from master, I followed this process:
$ git branch
* master
... confirms I'm on master.
$ git tag 0.1
... creates my 0.1 release as a tag from master.
$ git archive --format=tar --prefix=vnv-v0.1/ 0.1 | gzip > vnv-v0.1.tar.gz
... creates a gzipped tarball from the 0.1 tag. The prefix specifies the root directory that the tarball will explode to. (Don't forget that trailing slash.)
$ ls *tar.gz
vnv-v0.1.tar.gz
Nice!
$ mv vnv-v0.1.tar.gz /tmp/
$ cd /tmp/
$ tar -xzf vnv-v0.1.tar.gz
$ ls vnv*
vnv-v0.1.tar.gz
vnv-v0.1:
README SETUP* code/ db/ deploy.pl* dist/ doc/ media/ template/
... if prefix had been XXX then the tarball would still be called vnv-v0.1.tar.gz but it would have exploded to a directory called XXX/
To view your log:
$ git log
works well, but for a bit more verbose output - specifically to see which files were changed in which commits, you can use:
$ git whatchanged
I am using SQLite 3 as the storage backend for this blog. I am finding that the major advantage to this is that your DB gets carried around in your codebase.
If I deploy, make some changes to production (eg. add some blog entries) then I can just do this from my production shell:
$ git add .
$ git commit -m "* DB from production"
$ git push
... and then this in my development environment:
$ git pull
and my development environment has the updated production database! Nice.
Now, because I used git add ., the codebase will also include all the UGC, including uploaded images and such. Very nice.
Django Python 960.gs Git Vim NetBSD Nginx
This is the blog of Brad Willis, a software engineer living in Brisbane.
Help
Latest entries
*BSD Agile Apache Apple apt Athletics Best-Practice Censorship Comedy Cool Crosswords Deployment Django English Exim Firefox Git Hardcore Health irssi Javascript Jira Languages Linux Makefile Mathematics Mobile Broadband Mutt MySQL NetBSD nginx Nokia OpenVZ OSX Perl Privacy Python Rant Requirements rsync Ruby Shell Slackware SQL SQLite SSH Standards Subversion Television Testing ThisBlog Vim VMWare (Fusion) VPN X zsh
Checking for exceptions in doctests
Homer's Curling Speech
retry in Python
Vim Makefile tabs
Centos (or RH) IPTables
Converting ssh2 public keys to openssh
Vim comment hints
Context managers in Perl
Dish rotation
Git - fixing commit user
apt stuff
Using shell variables in AWK
Linux - Too many open files
Tell gvim to save and quit... remotely
Vim - automatically remove whitespace at EOL
Python - relative paths from within modules
TV Aspect Ratios
Git - Which commits are in your branch only?
Subversion setup cheat sheet
Force detach a screen session
Modify sudo's use of environment variables
Install all Perl modules
Mutt - delete old messages
OpenVZ VPS and swap space
fail2ban on NetBSD for ssh
NetBSD - Using sup
Python - testing for a sys.exit
Python Best Practice Link Dump
Python script names
Perl - Using an expensive module
Speed of git clone
Perl Modules with Custom Prefix
Perl: tr vs. s
Brilliant sysadmin Reference
Why is GRUB better than LILO?
Why is swap space important?
Perldoc Output
Git's Index
Jira Project Keys
Git GUI