Sunday, November 25, 2012

Git-hierarchy --- how to use

Documentation on git-hierarchy.

Definitions:

Note: when I say branch, I mean the named head.

A "feature branch", or a segment, is a triple:
1/ branch
2/ start commit reference. (points to a real commit - sha1-hash)
3/ base symbolic reference -- name of branch to re-base it on.

A sum is a branch name and a list of summands -- symbolic references
of branches, which should be (re-)merged to form the "unique commit" of the branch.

Sums are handy for:
- the final release commit
- as the "base" reference for segments.

poset: the partial ordering of (relevant) heads, induced by:
 segment-head > the head referenced by the base symref.
 sum-head > each of the heads referenced by the list of summands.

Operations:

git-segment  list, describe, create segments, split
git-sum    list, describe, create, modify  sums

git-rebase-poset the main tool -- rebase/remerge all the sums & segments.
so that for each segment  start is (again) equal to base, and sum-heads commits are joins of the summands.

git-rename  .. when renaming branches, rename the whole segment/sum, or
               update the other symbolic references to reference the changed  name.

git-delete  .. check if possible to delete the sum/segment, or if anything is
               referencing it -> abort.

Implementation:

start ... could have used tags. not now.
bases ... symbolic references; ex.  ref/base/antiflicker points at "ref: refs/heads/master".

summands ... symbolic refs. ex.  ref/sum/all/1  points at "ref: refs/heads/antiflicker",        ref/sum/all/2 points at "ref: refs/heads/auto-raise ...

Transferring to other repos

For now it's only a tool for individual use. There are some limitations in Git, which I had to work around:

  • "git push" resolves symbolic refs before sending them.
  • "git fetch" from GitHub does not fetch refs other than tags & branches.


So, if I want to at least transfer the structure, I need to patch git, or use this trick:

I can for example make a tag whose message -- as string -- is a table - dump of the symrefs:
sym-ref-name      ref: .....

git tag "hierarchy-refs" -m "$(git-dump-refs)"
and on fetching:
git cat-file tag hierarchy-refs |tail -n +6 |  git-recover-symbolic-refs





Thursday, October 11, 2012

System to keep a hierarchy of modifications for public software.




System to keep a hierarchy of modifications for public software.


I have developed a few extensions to free/open software, over past years.

Doing so in spare time, my priority was to get the features done,
at the cost of code quality, sharing(?).

During years, naturally, a need arose to re-apply those big patches to
evolving upstream sources.

So, inspired by Debian, I started to experiment with Quilt, and
represented my modifications as progressions of patches.



But there were certain projects, where my changes were so big,
that I was not able to extract such a linear sequence without
additional tools.

With the help of Git and especially Magit, I started to
classify separate diff hunks, then group those classified as related
and regroup etc.

  (I did this for my changes to Sawfish WM).

The whole set of changes grew to be  layers of changes, some dependent
on previous ones;  not a previous one, but more of them.


So I wanted to understand this partial ordering, and somehow represent it in Git.

The benefit for this would be easier future rebasing upon new upstream,
since rebasing smaller parts requires  less knowledge (decisions) at a time. And
some of my features can be also implemented upstream -- so I can just drop that
part of my changes, and  adapt/rework the rest.


Single "features" are thus represented as a linear sequence of commits,
and the dependency between them is represented by "basing" one  "feature"
on  a merge (commit) of  prerequisite features.


So, in my current version, I have merges - "sums", which are just lists
of features - "segments". And "segments" are "branches"  with
a Start commit (a hash id), and a symbolic "base", which is a "sum".
That base-sum can also be a trivial sum -- a simple  segment.

Rebasing such a hierarchy is a matter of walking in the topological order of
the dependency (between features -- segments) and sums,
rebasing them --onto the updated "bases"  or  redoing merges.



Code is here