Preserving merge trees when using git-svn

If you're like me, you might be using git-svn to connect to centralized SVN repositories (e.g., at the workplace) while keeping many of the powerful features of git. Sometimes you might be working in a local feature branch that is linked to a remote branch, and do a git svn rebase to grab updates from the SVN server. This command only fetches from the corresponding server branch. But, if an SVN merge, say from trunk, had happened on that branch at the server, then git-svn needs the corresponding local master branch to be up-to-date to notice that it was the parent of that merge. If you hadn't fetched from master recently, you lose the merge tree. Oops.

Before the rebase it would've been better to use git svn fetch --all (or it ought to have been, assuming git-svn fetches revisions in order once for all branches). But you might forget to do that. If that's where you find yourself, it is possible to recover. In the feature branch, use git svn reset -r{REV} -p, replacing {REV} with the revision number of the SVN merge which git-svn failed to assign a parent. Then do git svn fetch --all before [...]

Read this post

How to make private git repositories open for public access

Some of my personal projects are tracked using private git repositories, hosted on this server. I can access these via ssh, but for a while I've had in mind to make at least a couple of them publicly accessible... somehow. After finally getting around to looking into it, this turns out to be deceptively simple using git-daemon (instructions for Debian distros):

  1. Install the git-daemon-sysvinit package.
  2. Enable the daemon by editing /etc/default/git-daemon. Reboot, or start the git-daemon service by hand.
  3. Add a symlink to each git repo you want to make public under /var/lib/git. These will then be accessible via git://<hostname>/git/<linkname>.
  4. Ensure the git protocol port (9418) forwards to the server.

Simple! The git protocol is faster than serving over http(s), and the standard configuration ensures that anonymous clients can pull, but not push, which is exactly what I was after.

Over the next little while I'll introduce the couple of projects that I'm opening up for public access.

Read this post

How to find, and obliterate, large files in the history of a subversion repository

Sometimes, as I have, you'll find yourself working with colleagues who, through no fault of their own, are either not acquainted with the etiquette of Subversion repository use, or simply have an accident. What you may then end up with is a repository that contains one or more giant blobs of useless data that, really, should never have been added in the first place. Whether or not the culprit well-intentionedly removes these giant blobs in subsequent revisions, you're still left with a huge chunk of nothing-much wasting space on your server's hard drive.

Though a long-standing item on Subversion's wishlist, there is no command that will simply obliterate files from the repository's history. Nevertheless, there is a way to achieve this. Here's how.

The first step of the process is to determine which files need to go. (Some snippets in the following are derived from StackOverflow and Christosoft blog.) First, find the size of each revision in the repository. Replacing REPO appropriately, run this on your server:

REPO=[/absolute/path/to/repo]
for r in `svn log -q file://$REPO | grep ^r | cut -d ' ' -f 1 | tr -d r`
do
    echo "revision $r is " `svn diff -c $r file://$REPO [...]

Read this post


Page 1 of 1