How to convert a Subversion repository to a Git repository

I needed to convert several Subversion repositories to Git. Most of my process for this comes from this post. The following are some condensed steps and additional notes.

  1. Work in a new no-metadata folder; this helps keep your working environment isolated, and will let you re-use the users.txt file if you need to do this to multiple repositories. Create the users.txt file and ensure all authors in the repo are listed. To get started, do something like this, where SVN_URL is the URL of the repo:

    svn log -q SVN_URL | awk -F " \\\\| " '/^r/ {print $2" = "$2" <>"}' | sort -u > users.txt
    

    Note that this will preserve spaces in user names, if present (some other snippets you might find are broken and will not). Now edit users.txt and fill in details. You might need to add a (no author) = No Author <no@author.invalid> line, too, if there are any commits which have no author, such as the empty ones created by some techniques that manipulate dump files to purge files.

  2. Use git-svn like this (replace SVN_URL with the correct URL) to clone the repo without metadata; add --stdlayout if using standard branch folders, or as many -T, -t [...]

Read this post

How to add branches to a non-standard Subversion repository in a way that is compatible with git-svn

I found myself in the unusual situation of having a Subversion repository which was created initially without the usual trunk, branches, and tags folders, but where the team found later that, you know, this newfangled “branches” idea might just come in useful after all. If that's all there was to it, I could have just added those folders in a regular commit and continued on. The tricky part was that we also wanted git-svn compatibility, and for it to recognize branches, it needs the folder structure to be in place from the first commit onward.

Unfortunately, there ain't no easy way to achieve this which also preserves the revision numbers. But it is possible. What I had to do was rewrite the first commit manually:

  1. Checkout the original repo at revision 1.
  2. Copy all the files to a new repo, but this time place it under a trunk top-level folder, ensuring everything is otherwise identical inside.
  3. Also add tags and branches top-level folders.
  4. Commit all those using the same commit message as the original.

Now, this commit still doesn't have the same metadata, so I had to then take an svndump of the new repo, and edit that dump so [...]

Read this post

How to VNC into a running Plasma session

The easy answer is “have the user run krfb inside the session first”. But what if you are the user, and you're already remote from the host by the time you remember you needed to do that?

You need to have configured krfb with a remote control password and any other relevant settings, first. See below, but typically you've already done this at some point, so you can move straight to the important part:

ssh you@yourserver
DISPLAY=:0.0 krfb --nodialog

Then try to connect using krdc, or your VNC viewer of choice.

What if you don't have the password, etc., configured? Then:

ssh -X you@yourserver
krfb

This will display the window locally. Configure and close. This mode of operation doesn't work for actually showing the remote session, evidently because the X session forwarded though SSH is somehow a new/separate session. The key to showing the remote session is passing that DISPLAY environment variable.

Other thoughts: Have a slow network? Disable key repeat, or it might stutter. Also, sshuttle is very handy if you have limited port forwarding (but it won't help the network speed situation).

Read this post

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

Upcasting through covariant interfaces in a constrained generic C# method

Here's a subtle one. Assume you have the appropriate “using System.Collections.Generic;” clause included somewhere up above. Can you spot what's wrong with this code?

interface ITestInterface
{
}

class TestClass<T>
    where T : ITestInterface
{
    public void TestMethod()
    {
        IReadOnlyList<T> x = null;
        IReadOnlyList<ITestInterface> y = x;
    }
}

Seems reasonable, right? An IReadOnlyList is covariant in its stored type, so given that T is constrained to be an ITestInterface, assigning such a list of T to a list of ITestInterface should be fine. And yet, compiling this code will fail at “y = x”, being unable to implicitly convert the types.

After some hair-pulling, I eventually worked out that the solution is to add “class” to the constraints on T. It would seem that, otherwise, the compiler will assume that the generic type T will not have any kind of inheritance for which covariance will be relevant. So it doesn't consider that, and the cast fails.

Read this post

Prevent .xsession-errors growing forever on Debian

The default configuration of the X server in Debian keeps a log of all the console output of the programs a user runs from their X session. It also keeps this log indefinitely. This is quite clearly a design mistake, because even ignoring badly behaved programs (those which are needlessly noisy are indisputably buggy), enough legitimate errors will eventually eat your disk. Plus the unjustifiable assumption that all programs out in the wild will be well-behaved, which is a nice hope but contrary to reality.

Sadly, this behaviour is also an ancient bug that has been, it would seem, forgotten about.

Anyway, here's a relatively simple method to fix that. As root, edit /etc/X11/Xsession. Just below the ERRFILE=$HOME/.xsession-errors line, add this:

ERRFILEOLD="$ERRFILE".old

if [ -f "$ERRFILE" ]; then
set +e
mv -f "$ERRFILE" "$ERRFILEOLD" 2> /dev/null
set -e
fi

Each time the user logs in, the old .xsession-errors log file will be moved to .xsession-errors.old (overwriting anything already with that name), and a new one created. Thus it ensures that the file doesn't grow indefinitely, so long as the user logs out and back in at some point.

Read this post


Page 1 of 3 | Next →