Etc

Git Notes — svn Migration, Undoing Local Commits, rebase vs merge

Contents

Three separate git notes, collected into one page — from the commands used while moving off svn, through to working out what rebase actually does.

Migrating from svn to git

1
2
git svn clone --stdlayout --no-metadata -A users.txt svn://example.com/repository/projectname
cd projectname

users.txt maps svn accounts to git accounts. This is the command that builds it, but it never worked for me — probably a missing perl.

1
svn log ^/ --xml | grep -P "^<author" | sort -u | \ perl -pe 's/<author>(.*?)<\/author>/$1 = /' > users.txt

Handling the ignore file

1
git svn show-ignore -i trunk > .gitignore

Pointing at the remote

1
git remote add origin git@git.example.com:group/projectname.git

Converting tags

svn tags arrive as remote branches in git. This turns them into real tags.

1
git for-each-ref refs/remotes/tags | cut -d / -f 4- | grep -v @ | while read tagname; do git tag "$tagname" "tags/$tagname"; git branch -r -d "tags/$tagname"; done

Converting branches

1
git for-each-ref refs/remotes | cut -d / -f 3- | grep -v @ | while read branchname; do git branch "$branchname" "refs/remotes/$branchname"; git branch -r -d "$branchname"; done

Pushing

1
2
git push origin --all
git push origin --tags

GitLab backup and restore

1
sudo gitlab-rake gitlab:backup:create

Restore the most recent one.

1
sudo gitlab-rake gitlab:backup:restore

Restoring a specific point takes an option. I never tried it.

1
BACKUP=timestamp_of_backup (required if more than one backup exists)

Discarding local commits

To throw away commits that only exist locally and rewind to the remote, naming the target explicitly is the reliable form. This assumes develop is checked out.

1
git reset --hard remotes/origin/develop

Without a target it seems to reset against the remote of whatever is checked out.

1
git reset --hard

rebase and merge

rebase and merge always confused me. After losing work to rebase once, I stuck to merge only.

Looking it up: rebase means relocating the base of a branch.

Working in gitflow, I created a feature branch and then rebased the develop commits that had piled up in the meantime. The develop commits made during that work landed underneath the local feature branch.

The history stays clean, which is nice. There is one problem though. If the feature branch was already pushed, you end up with two feature branches. Since local is the newer one, deleting the feature on remote/origin and pushing fresh seems to fix it.

A diagram would explain this well, but I cannot draw.

During a rebase, conflicts are resolved one step at a time against each commit on the local feature branch. That can produce results you did not want — you may resolve the same file several times.

So if you are going to use rebase, keep the cycle short. The longer you wait, the more intermediate commits pile up and the more times you resolve.

Summary

  • svn migration is git svn clone --stdlayout plus manual tag/branch cleanup
  • To discard local commits, name the target: git reset --hard remotes/origin/<branch>
  • rebase relocates the base. Clean history, but a pushed branch splits into two
  • Rebase often. Waiting means resolving the same file repeatedly