HomePage RecentChanges

# StGITtheory

## A Bit of StGIT Patch Theory

Every patch in StGIT is internally represented as two nodes - the bottom and the top. The nodes are commit IDs stored in the GIT object database. The actual patch is the diff between the trees corresponding to the bottom and the top nodes. This can be written as

    P = diff(Nb, Nt)

    P  - patch
    Nb - bottom (start) node
    Nt - top (end) node

The order of diff arguments is (old, new).

For an ordered stack of patches:

    P1 = diff(N0, N1)
    P2 = diff(N1, N2)
    ...

    Ps = P1 + P2 + P3 + ... = diff(Nsb, Nst)

    Ps  - the cumulative patch of the whole stack
    Nsb - bottom stack node (same as N0)
    Nst - top stack node (same as Nn)

The plus sign presents superposition of patches. Please note that such superposition is not always commutative.

Whenever StGIT pulls changes from another repository, it unapplies (pops) all applied patches, updates the branch using git commands and tries to re-apply (push) the patches that were applied.

Popping a patch from the stack is done by simply setting the stack top Nst to the patch bottom Nb. Pushing is not always trivial and may need merging.

When pushing an unapplied patch P from the stack, it may happen that the patch bottom Nb is different from the stack top Nst, i.e. the patch was originally applied to a different tree. In this case, the patch needs to be adjusted to its new position on the stack. First, the new stack top is calculated by diff3 merging:

    Nst' = diff3(Nst, Nb, Nt)

The order of diff3 parameters is (branch1, ancestor, branch2).

If the merge succeeds, the patch is adjusted as following:

    Nb' = Nst
    Nt' = Nst'
    P'  = diff(Nb', Nt')

Nb' and Nt' become the new bottom and top nodes of the patch, and the stack top is advanced to Nst'.

If the the merge fails, the user is requested to resolve conflicts and refresh the patch by "stg refresh". It is also possible to undo the failed push by "stg push --undo".

This approach allows easy reordering of patches. To reorder applied patches, the user should pop them first and then push them back to the stack in the desired order. Unless the patches modify the same or adjacent lines in the same files, StGIT should be able to adjust the patches automatically for the new order.

## Layout of the .git Directory

    branches/		remote branches to pull (deprecated)
    hooks/			scripts executed by git on some events
    info/
      exclude		list of files ignored for the purpose of commit
      refs			list of commit IDs from refs/ (used on servers)
    objects/		git objects
      00/			unpacked objects
      ...
      ff/
      info/
        packs		list of object packs
      pack/			object packs
        *.idx		index files
        *.pack		actual pack files
    patches/		storage for StGIT patches
      master/		patches for the master branch
        patches/		storage for individual patches
          patch1/		name of one of the StGIT patches
            authdate	patch date
            authemail	author's e-mail
            authname	author's name
            bottom		bottom ID of the patch
            bottom.old	old bottom ID of the patch (for undo)
            commemail	committer's e-mail
            commname	committer's name
            description	patch description
            top		top ID of the patch
            top.old		old top ID of the patch (for undo)
          patch2/		name of another StGIT patch
            ...
        applied		list of applied patches
        current		name of the topmost patch
        description		branch description
        protected		if present, the branch is protected against changes
        unapplied		list of unapplied patches
      other-branch/		patches for "other-branch"
        ...
    refs/			various significant commit IDs
      bases/		bottom commit IDs of the patch stacks
      heads/		top commit IDs of branches
      patches/		commit IDs of StGIT patches
      tags/			commit IDs of tags (commit and tag objects)
    remotes/		remote branches to pull and push
    FETCH_HEAD		list of fetched branches and their commit IDs
    HEAD			reference to the current branch
    ORIG_HEAD		previous commit ID of the head branch
    config			configuration of the repository
    description		description of the repository
    index			directory cache