Version 14 (modified by pv, 4 years ago)

Notes about branches in Git/Bzr/Hg

* This is work in progress *

Rationale for git

Comparison with bzr / hg, problems of svn.

Branches

One usability difference between the Git, bzr and hg is how they deal with branches:

  • Git:
    • A repository may contain several branches, and one can switch between them in the same working copy.
    • Branches are essentially pointers to the heads of revision DAGs, and have separate versioning from the repository contents (the reflog). In practice branches themselves are not versioned -- but in practice reflog is a bit difficult to use.
    • Branches can be relatively fluid and temporary in nature, and can be altered, added, and deleted easily.
    • Branches are local to a repository -- but users can use git-remote to deal with "remote" branches from other repositories. This allows mirroring the branches of the remote repository locally, and referring to them with convenient names. Also, possible to list from command line what branches are available on the remote repo.
  • Bzr:
    • Repository is the same thing as a branch. (XXX: is this true?)
    • Each working copy is associated with a single repository. (XXX: can the branch be switched easily?)
    • Branches, remote and local, are referred to using their full URLs. (XXX: is there a way to specify aliases?)
    • Remote branches are not mirrored.
  • Hg:
    • Hg has several branch concepts:
      • Each repository can be understood as a branch in itself. Works similarly as Bzr. Giving aliases possible.
      • A repository may contain "named branches"
        • Named branches are pointers to heads of revision DAGs within the repo, but are versioned together with the repository content.
        • They are permanent, and cannot be deleted (except by merging them).
        • They are transmitted when the repository is cloned and are "global" -- each clone of the same repo has the same named branches, if they are in sync.
      • Hg has plugins that provide somewhat Git-like branches: "localbranch" and "bookmarks".

Evaluation:

  • Git's branches can be easily used as topic branches, and also as permanent ones. Switching between branches is very fast within the same working copy.
  • Git's collaboration features appear to be the best of the three.
  • Bzr's repository branches are clumsier than Git's for use as topic branches; requires cd'ing to a different working copy. Long URLs difficult to remember, and no way to list available branches from command line.
  • Hg's repository branches: similar to Bzr.
  • Hg's named branches: use as throwaway topic branches questionable, since they cannot be deleted.
  • Hg's plugins: at least the localbranch one seemed to suffer from the 80%-20% problem. Also, it was not suitable for collaboration, as IIRC there was no way to publish the local branches separately.

How to do the migration

The migration from svn repository to git repository should keep as mush information from svn as possible: history, tags and branches.

Tool for the migration

svn-all-fast-export: see http://repo.or.cz/w/svn-all-fast-export.git

This is an exporter coded by KDE people to handle KDE migration - thus, it can certainly handle numpy and scipy. It can skip some branches, or paths outside the usual trunk/branches/tags (f2py-research, for example), and export svn "tags" as real tags.

usage

For numpy, the following seems to work - it ignores branches outside the /branches namespace, convert the tags.

create repository myproject
end repository

match /trunk/
  repository myproject
  branch master
end match

# Ignore extra 'repositories' which are not numpy code, but were in numpy
# repository.
match /f2py-research/
end match
match /vendor/
end match
match /numpy.sunperf/
end match
match /cleaned_math_config/
end match
match /numpy-docs/
end match

# Take usual svn branches
match /branches/([^/]+)/
  repository myproject
  branch \1
end match

# This rule will create tags that don't exist in any of the
# branches. It's not what you want.
# See the merged-branches-tags.rules file
match /tags/([^/]+)/
  repository myproject
  branch refs/tags/\1
end match