chiark / gitweb /
96ccb79a5ca1f5f27b8102893611acfe2bad658d
[stgit] / stgit / lib / stackupgrade.py
1 import os.path
2 from stgit import utils
3 from stgit.out import out
4 from stgit.config import config
5
6 # The current StGit metadata format version.
7 FORMAT_VERSION = 2
8
9 def format_version_key(branch):
10     return 'branch.%s.stgit.stackformatversion' % branch
11
12 def update_to_current_format_version(repository, branch):
13     """Update a potentially older StGit directory structure to the latest
14     version. Note: This function should depend as little as possible
15     on external functions that may change during a format version
16     bump, since it must remain able to process older formats."""
17
18     branch_dir = os.path.join(repository.directory, 'patches', branch)
19     key = format_version_key(branch)
20     old_key = 'branch.%s.stgitformatversion' % branch
21     def get_format_version():
22         """Return the integer format version number, or None if the
23         branch doesn't have any StGit metadata at all, of any version."""
24         fv = config.get(key)
25         ofv = config.get(old_key)
26         if fv:
27             # Great, there's an explicitly recorded format version
28             # number, which means that the branch is initialized and
29             # of that exact version.
30             return int(fv)
31         elif ofv:
32             # Old name for the version info: upgrade it.
33             config.set(key, ofv)
34             config.unset(old_key)
35             return int(ofv)
36         elif os.path.isdir(os.path.join(branch_dir, 'patches')):
37             # There's a .git/patches/<branch>/patches dirctory, which
38             # means this is an initialized version 1 branch.
39             return 1
40         elif os.path.isdir(branch_dir):
41             # There's a .git/patches/<branch> directory, which means
42             # this is an initialized version 0 branch.
43             return 0
44         else:
45             # The branch doesn't seem to be initialized at all.
46             return None
47     def set_format_version(v):
48         out.info('Upgraded branch %s to format version %d' % (branch, v))
49         config.set(key, '%d' % v)
50     def mkdir(d):
51         if not os.path.isdir(d):
52             os.makedirs(d)
53     def rm(f):
54         if os.path.exists(f):
55             os.remove(f)
56     def rm_ref(ref):
57         if repository.refs.exists(ref):
58             repository.refs.delete(ref)
59
60     # Update 0 -> 1.
61     if get_format_version() == 0:
62         mkdir(os.path.join(branch_dir, 'trash'))
63         patch_dir = os.path.join(branch_dir, 'patches')
64         mkdir(patch_dir)
65         refs_base = 'refs/patches/%s' % branch
66         for patch in (file(os.path.join(branch_dir, 'unapplied')).readlines()
67                       + file(os.path.join(branch_dir, 'applied')).readlines()):
68             patch = patch.strip()
69             os.rename(os.path.join(branch_dir, patch),
70                       os.path.join(patch_dir, patch))
71             topfield = os.path.join(patch_dir, patch, 'top')
72             if os.path.isfile(topfield):
73                 top = utils.read_string(topfield, False)
74             else:
75                 top = None
76             if top:
77                 repository.refs.set(refs_base + '/' + patch,
78                                     repository.get_commit(top), 'StGit upgrade')
79         set_format_version(1)
80
81     # Update 1 -> 2.
82     if get_format_version() == 1:
83         desc_file = os.path.join(branch_dir, 'description')
84         if os.path.isfile(desc_file):
85             desc = utils.read_string(desc_file)
86             if desc:
87                 config.set('branch.%s.description' % branch, desc)
88             rm(desc_file)
89         rm(os.path.join(branch_dir, 'current'))
90         rm_ref('refs/bases/%s' % branch)
91         set_format_version(2)
92
93     # Make sure we're at the latest version.
94     fv = get_format_version()
95     if not fv in [None, FORMAT_VERSION]:
96         raise StackException('Branch %s is at format version %d, expected %d'
97                              % (branch, fv, FORMAT_VERSION))
98     return fv != None # true if branch is initialized