Git
git is a fast and popular revision control system.
Usage
This backend is selected using the prefix git: for the repository name and can be used both as SourceRepository and as TargetRepository
Importing into git branches
The git target serves as a testbed for proper branch support in Tailor. The relevant parts will be lifted into the generic classes as appropriate.
Branching approaches
There are currently two approaches to branch support in the git target. All of them use the branchpoint repositoy parameter to specify the point of the parent branch where the branch forked off.
- One repository per branch
- This is the intuitive way of branching for many distributed SCM systems, and the only one for some of them (eg. darcs). It is however uncomfortable in several aspects: you need to fetch branches from several repositories (or create an additional one that does the merge), and it does not really help when we'll want to implement merges, since usually the point to merge from won't be readily available, and the branch it belongs to will need to be known as well.
This branching mode makes use of the parent-repo repository parameter. Initialization of the branch's repository is done as a shared clone (using git-clone -s), so the parent branch's revisions are not needlessly duplicated.
[DEFAULT] patch-name-format=%(firstlogline)s remove-first-log-line=True root-directory = /tmp/test projects = trunk-pull, branch-pull [trunk-pull] source = cvsps:bigdiesel target = git:bigdiesel start-revision = INITIAL subdir = trunk [branch-pull] source = cvsps:bigdiesel target = git:bigdiesel-branch start-revision = bigloo-parser INITIAL subdir = bigloo-parser [git:bigdiesel] [git:bigdiesel-branch] parent-repo = ../trunk parent-rev = bigloo-parser_branchpoint
- One single repository for all branches
- This command uses real git branches inside a single bare repository specified through the tailor-standard repository parameter. The name of the branch to import to is specified through the branch parameter, which defaults to master.
[git:bigdiesel] repository = ../bigdiesel.git [git:bigdiesel-branch] repository = ../bigdiesel.git branch = bigloo-parser branchpoint = bigloo-parser_branchpoint
Future developments
- Map of source revisions to target revisions
- Though not specific at all to git or to branches, it is a prerequisite for many of the features listed below. A libdb hash alongside the state file looks like a good candidate to store the map.
- Merge support
- We need to be able to ask the source repository who the parent revisions for the considered revision are, since they are not necessarily just the previous revision from the branch (in fact, prcs even allows the previous revision on the branch to be completely unrelated). Then we'll be able to record merges in the target (if we can map those source revs to target revs).
- Automatic determination of branchpoints
- Some sources have knowledge about branchpoints (in CVS we'll have to guess, but that's CVS, we're used to that). Once we can map source revs, that will be trivial.
- Automatic determination of branches
- In repositories with many branches it is awkward to list them all. Additionally, in SCMs handling history as a full-featured directed graph (eg. Git), there are sometimes temporary branches that were merged into others, and which stay reachable because of the merge, although they don't have a name. They can be numerous, and it would be silly to expect the user to hunt for them all.
Here I expect to define a branch as something that starts off a branchpoint or an initial commit, and extends up to a merge or a (labeled) branch head.
Or maybe not: we may only need to query the source repo about (or explicitly request) branch heads. Then, exploring history backwards will teach us about root commits, branchpoints, and mergepoints.
- Support for joint merges
- That is, support for merges that join two histories that started as separate ones. Public examples in the git repository for git itself include merges of GITK and Gitweb repositories. The automatic determination of branches will be sufficient for SCMs where such merges appear as such, and histories are already kept separated. In CVS, however, due to the lack of renaming capabilities, it can happen that joint merges are done by moving an external CVS module into the repository. Dealing with this requires being able to separate the history of a given subtree up to a given point which is to be considered the merge. Tricky.
