asemanfar - a blog about programming

 

Posts tagged with "git"

Factoring Out a Generic App From a Git Repositroy

October 24, 2008

I spent a couple hours today removing any blog-specific details from my blog engine so that I can generic-ify it and make it open source. There were two issues that I ran into with git after making all the generic-ifying changes.

Clearing Commit History

The first was getting rid of all the commit history. I have some sensitive data (such as API keys/secrets) that I'd prefer not to make publicly available. There are two routes that I found to achieving this. The first is to create a shallow clone:

   1  git clone --depth 1 original_repo.git new_bare_repo.git

Unfortunately that didn't work as expected, it created a complete clone. I thought maybe it was because it was creating hard-links since it's a clone of a local git repository. So I added --no-hardlinks to the clone with no avail. Lastly, I tried tricking git into thinking it was a remote repository by simply ssh'ing into my local machine:

   1  git clone --depth 1 ssh://localhost/path/to/original_repo.git new_bare_repo.git

Strangely, that yielded a new repository with a three commit history; I have no idea how it picked three. But since only my last commit removed sensitive data, three wasn't going to cut it. I reverted to a more primitive solution:

   1  cp -r original_repo.git new_bare_repo.git
   2  cd new_bare_repo.git
   3  rm -rf .git
   4  git init
   5  git add .
   6  git commit -m "generic blog"

Although that works, I feel like it's a less elegant solution especially because it wouldn't work if I wanted more than a one-commit history. Anyone have ideas to why the depth flag doesn't work as expected?

Re-applying app-specific changes

So now that I have a new generic blog factored out of my customized blog, I want my customizations to be applied on-top of the generic version so that I could maintain a "blog-name" branch with all my changes on top of the generic version. Here's how I did that:

   1  cd original_repo.git
   2  # assuming HEAD^ refers to the commit immediately before your first generic-ifying commit
   3  git diff --binary HEAD HEAD^ > ../app-specific.diff
   4  cd ../new_bare_repo.git
   5  git checkout -b blog-name
   6  git apply ../app-specific.diff
   7  git commit -m "import blog-specific changes"

Now I have a new repository with no commit history (unfortunately) with a generic blog as the master branch and a branch for my blog-specific changes.

I'll be pushing this to GitHub sometime in the future. I still want to do some significant clean up so that it's more customization-friendly for anyone who wants to use it.

Current Git Branch in Bash Prompt

April 12, 2008

Earlier today, my roommate and I were enjoying our afternoon watching the TextMate for Rails 2 Peepcode and I noticed that in the bash prompt, the current branch was shown in parenthesis. I thought this was a wonderful idea and thought I'd add it to my own bash prompt.

Update: Some much better alternative methods have been posted in the comments, please take a look below.

Here is the code to do it:

   1  export PS1="\[\033[38m\]\u@\h\[\033[01;34m\] \w \[\033[31m\]\`ruby -e \"print (%x{git branch 2> /dev/null}.grep(/^\*/).first || '').gsub(/^\* (.+)$/, '(\1) ')\"\`\[\033[37m\]$\[\033[00m\] "

This will make your bash prompt look like this:

   1  user@hostname currentDirectory (branch name) $

The important part of the PS1 in the first code snippet is this:

   1  # this goes somewhere in your PS1 (it'll make the branch name red)
   2  \[\033[31m\]\`ruby -e \"print (%x{git branch 2> /dev/null}.grep(/^\*/).first || '').gsub(/^\* (.+)$/, '(\1) ')\"\`\[\033[37m\]

I decided to try to do this with sed and not ruby. I came up with this:

   1  export PS1="...\`git branch 2> /dev/null | grep -e ^* | sed -E  s/^\\\\\\\\\*\ \(.+\)$/\(\\\\\\\\\1\)\ /\`\[\033[37m\]$\[\033[00m\] "
   2  # no, your browser is not having rendering issues
   3  # there seriously are that many backslashes

Other than the disgusting backslashes, it's pretty nice. If you use single quotes on the outside instead of double, you can lose a few backslashes:

   1  export PS1='...`git branch 2> /dev/null | grep -e ^* | sed -E  s/^\\\\\*\ \(.+\)$/\(\\\\\1\)\ /`\[\033[37m\]$\[\033[00m\] '