Archive for the ‘git’ Category

Setting up and using a git wrapper around SVN with git-svn

Posted on January 27th, 2012 in git, Uncategorized | No Comments »

Note: I wrote this post a long time ago but never got around to posting it. A lot of these steps are applicable to porting an SVN repo to Git as well.

Preface on why I love git

Roughly four years ago I switched to git for version control and it’s changed my development life. While SVN is sufficient to “get the job done” in terms of keeping a history of your commits with a group of people, Git is truly the next evolutionary step up in every way. I could expound a whole article on the joy of git, but many others already have, and this articles not about that. But I will kindly throw in my 0.02 on why I personally love it:

  • It’s fast. Git keeps your whole repo’s history local. So no need to ping your repo server for every command. You can even checkout your codebase from 3 weeks ago or a year ago in under a second.”
  • It works offline. That’s right, no internet. Sync up later.
  • It has useful modern tools. Like git stash and git bisect. Both will save you a lot of time.
  • It’s your third hand. Let’s face it, besides svn being slow, it’s not friendly enough to do more than throw your past commits into an empty hole you will probably never see again. With very little setup, you have beautiful colored output in your logs and diffs with git. And “git log” actually pages by default (while keeping colors) instead of flooding your console with the entire repos history! Want to query something in your history log? What about all commits from your friend Bob in the past 2 weeks?
    git log --date=relative --author=nizam --since="2 weeks ago"

    Bam. Done.

  • Easy repo creation. You don’t have to be an admin to setup a git repo. Just cd into a folder and type “git init”. You just created a new repo. I do this all the time, for example in my folder of todo lists, I use it to track history of my todos. At work someone kept messing up the apache config file, all I had to do was “git init” in /etc/httpd/conf and now I can easily “git diff” new changes that were made and revert / adjust if needed.
  • Many ways to use it. Git is promoted as “decentralized” version control, but it can be an easy drop in replacement for any job SVN can do. Which leads me to…

With all those advantages, many larger companies haven’t jumped on the git bandwagon. I believe there’s two reasons this is the case.

  • As programmers get more experienced, they generally become more pragmatic (which is generally a good thing.) They adopt a “if it ain’t broke, don’t fix it.” mentality. After all, SVN get’s the job done.
  • There is a bit of a learning curve with git. But there are a ton of good resources for learning it. I recommend getting your hands dirty with Git Immersion if you’re new or would like to learn. I don’t recommend wrapping git around svn as I’m about to show you for a person who’s learning git.

Getting down to business.

In order to use git with an svn repo, you’ll have to run some commands to import that svn repo, commit by commit into a git repo.

1. First, make sure you have a version of git installed with svn bindings. If you type “git svn” and it give you an error, I’d google one of the resources in reinstalling git with svn bindings.

2. We need to keep

# In your existing svn repo, lets grab a list of authors
svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors.txt
# create a new folder
cd ..; mkdir NEWREPO.git;
git svn clone -A ../OLDREPO/authors.txt https://svn/repo/trunk
git svn fetch # this could take a long time as it checks the repo out one rev at a time.
 
# update your working copy:
git-svn rebase
 
# commit your changes to svn server
git-svn dcommit

kudos to:

http://flavio.castelli.name/howto_use_git_with_svn

Great little bash snippet to summarize your daily git commits.

Posted on January 9th, 2012 in bash, git | No Comments »

For general invoicing and hour tracking, I like to post the details of my git commits. Though, I had my own little version of this script, this one posted at stackoverflow was a lot better looking. Posted here for posterity:

function gdaily {
    NEXT=$(date +%F)
    echo "CHANGELOG"
    echo ----------------------
    git log --no-merges --format="%cd" --date=short | sort -u -r | while read DATE ; do
        echo
        echo [$DATE]
        GIT_PAGER=cat git log --no-merges --format=" * %s" --since=$DATE --until=$NEXT
        NEXT=$DATE
    done
}

Which looks like:

[2012-01-07]
 * Refactor list portfolio page css and js.
 * namespace.data include to load fake api data until it is ready. Portfolio list working again.
 * CurrentUser model defaults and code cleanup.

[2012-01-06]
 * Upgrade portfolio call from GET and POST. To be discussed in tomorrow's standup.

Working with git repos on non-standard ports

Posted on March 30th, 2011 in git, ssh | 2 Comments »

Recently due to some SSH attacks I’ve had to change my default SSH port to something non-standard. While I’m not a proponent of security through obscurity, most automated botnets ping random IP addresses on port 22 to see if there’s an SSH daemon listening before relentlessly hammering down on them—it only makes sense to get off of that port. (I’ve obviously hardened my security in other ways as well.)

Since I run my own little version of GitHub (using a combination of Gitolite, git-commit-notifier, and other open-source tools) which I share with friends, I needed to send out a quick email on how to switch up existing checked-out repositories as well as how to clone new ones using this non-standard port. Since I did the research, I thought I might as well post it here, too:

Cloning a git repository on a non-standard port

The git man file says you can specify a port using the traditional git syntax but I couldn’t get it to work for the life of me, It always defaulted to port 22. Since git just uses SSH anyways, here’s the alternative syntax that also works:

old:

git clone git@domain.com:<project name>

new:

git clone ssh://git@domain.com:<port>/<project name>

Switching an existing checked-out repository to use a non-standard port

To prevent having to re-checkout an entire project, simply change the location of master and all will be fine. There’s a way to do this using a git shell command but I prefer to just modify the .git/config file directly, as that’s all the commands does anyways.

old:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = git@domain.com:<project name>


new:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = ssh://git@domain.com:<port>/<project name>

Set it and forget it method (.ssh/config)

Instead of doing any of the above, if you’re on a Mac or Linux environment, the config file inside of your ~/.ssh folder can save you from typing long ssh commands. It allows you to create short ssh alias’s that predefines a host, username, port, as well as more advanced functionality like running proxy commands, forwarding your ssh agent, etc. It’s well worth taking a look at. When you set an SSH alias anything that uses SSH (git, rsync, scp, etc) all have access to it.

Add the following lines to your ~/.ssh/config:

Host myrepo
     User git
     Port <port number>
     Hostname <hostname.com>

Now you can do a git clone by doing the following:

git clone myrepo:<project name>

Or in your current checked-out project change the remote “origin” url to:

myrepo:<project name>

It will automatically pick up your username, port, and hostname from your .ssh/config file.

A better git log and the wonders of git tig

Posted on January 16th, 2011 in git | No Comments »

I was looking for a remote terminal-friendly version of gitk for visualizing branch and merges and as of yet the closest I’ve gotten is this awesome log command (compliments of this well-done git tutorial):

git log --pretty=format:"%h %ad | %s%d [%an]" --graph --date=short

It wasn’t as full featured as I liked but did the job and doesn’t require installing an extra package. Recently though, I stumbled on a colorful text-based git frontend call tig which is quite handy. Check out the screenshots here. It’s fast and effortless to dig around your repository, drill down wherever you need, and you can even pipe regular git commands to it to see them in interactive full color. Installing it is a breeze with (yum install tig or apt-get install tig) or you can install from source. From here, type tig in your working directory and follow these commands. Checkout tig blame too!

I’d give a longer review on it with screenshots but someone already has here.

I default tig to show the rev-graph (shown here) and use relative dates by adding the following to my global git config in ~/.gitconfig:

[tig]
   show-date = relative
   author-width = 8
   show-rev-graph = yes

You can really modify the short cut commands and colors to your liking using the man file.

Git: committing only partial changes of a file

Posted on December 30th, 2010 in git | 1 Comment »

or better known as “staging patches”.

So you created some new functionality in a file but you have a lot of other code you’re not quite ready to commit yet. Answer: git add -p . It will interactively go though modified sections of your file asking if you want to “stage this hunk”. Answer y for yes, n for no, q for stop, then commit as usual. You can even split hunks if you want to get more fine-grained.

For more details check out this page.