Git Attic
Sometimes when using Git you find yourself with several branches that contain old code or code that has been shelved for the time being. You don't want to just throw it away, but it's really in the way in with your active branches.
I've usually used the solution of tagging and then deleting the branch. I call the tags something like "attic/experiment". This solves the problem of having uninteresting stale branches appear in the "git branch" output. However, "git tag -l" now shows my attic tags, and doing a "git push origin --tags" is no longer desirable, as I don't really want to push these stale branches to a public repository. Besides, if at all possible I like to keep my tags related to release versions, not unstable experiments or debug code.
The truth of the matter is that I need a separate place to store stale branches, neither in refs/heads nor refs/tags. To that end, I decided to use refs/attic. For starters, I moved refs/tags/attic to refs/attic. Bear in mind that tags are often cleaned away into the packed-refs file, so you may need to extract them from there if you're doing this. The advantage of moving the refs is that my stale branches are not visible in "git branch" nor "git tag -l". The downside is that it's difficult to list them at all! They appear in QGit, but I really wanted a way to manage my attic from the command line without using something as cumbersome as "git for-each-ref refs/attic".
To that end I created a simple bash script named "git-attic", which does everything I need. Place in your path and use as follows:
git attic git attic store <ref> [<commit>] git attic remove <ref>
Now, tidying away a stale branch named "experiment" is as simple as "git attic store experiment experiment" and then deleting the branch. If you don't specify a commit object to "git attic store", it will store the current HEAD. You can start using this straight away — it doesn't need any setting up.
The script is attached, but it's pasted below for your perusal. I hope this will be useful to someone else too :)
Edit: Thank you to Eric Raible from the Git mailing list, who suggested a couple of optimisations.
Edit: I've updated the script again since. See new post.
#!/bin/bash
###
# Original Author: Paul Gideon Dann
###
showUsage() {
echo "Usage: git-attic"
echo " git-attic store []"
echo " git-attic remove "
}
case $1 in
"store")
if [[ ! $2 ]]; then
showUsage
exit 1
fi
if [[ $3 ]]; then
OBJECT_SHA1=`git-rev-parse --revs-only $3`
if [[ ! $OBJECT_SHA1 ]]; then
echo "$3 is not a recognisable commit object."
exit 1
fi
else
OBJECT_SHA1=`git show-ref --hash --head HEAD`
fi
git update-ref refs/attic/$2 $OBJECT_SHA1
echo "$2 stored in attic."
;;
"remove")
if [[ ! $2 ]]; then
showUsage
exit 1
fi
OBJECT_SHA1=`git show-ref --hash attic/$2`
if [[ ! $OBJECT_SHA1 ]]; then
echo "$2 does not exist in the attic!"
exit 1
fi
git update-ref -d refs/attic/$2 $OBJECT_SHA1
echo "$2 removed from attic."
;;
*)
if [[ $1 ]]; then
showUsage
else
# display contents of attic
git for-each-ref --format="%(refname)" refs/attic | awk -F / '{print $3}'
fi
;;
esac
Danns.co.uk