class Patch:
"""Basic patch implementation
"""
- def __init__(self, name, patch_dir):
- self.__patch_dir = patch_dir
+ def __init__(self, name, series_dir):
+ self.__series_dir = series_dir
self.__name = name
- self.__dir = os.path.join(self.__patch_dir, self.__name)
+ self.__dir = os.path.join(self.__series_dir, self.__name)
def create(self):
os.mkdir(self.__dir)
def rename(self, newname):
olddir = self.__dir
self.__name = newname
- self.__dir = os.path.join(self.__patch_dir, self.__name)
+ self.__dir = os.path.join(self.__series_dir, self.__name)
os.rename(olddir, self.__dir)
return self.__get_field('authname')
def set_authname(self, name):
- if not name and config.has_option('stgit', 'authname'):
- name = config.get('stgit', 'authname')
+ if not name:
+ if config.has_option('stgit', 'authname'):
+ name = config.get('stgit', 'authname')
+ elif 'GIT_AUTHOR_NAME' in os.environ:
+ name = os.environ['GIT_AUTHOR_NAME']
self.__set_field('authname', name)
def get_authemail(self):
return self.__get_field('authemail')
def set_authemail(self, address):
- if not address and config.has_option('stgit', 'authemail'):
- address = config.get('stgit', 'authemail')
+ if not address:
+ if config.has_option('stgit', 'authemail'):
+ address = config.get('stgit', 'authemail')
+ elif 'GIT_AUTHOR_EMAIL' in os.environ:
+ address = os.environ['GIT_AUTHOR_EMAIL']
self.__set_field('authemail', address)
def get_authdate(self):
return self.__get_field('authdate')
- def set_authdate(self, authdate):
- self.__set_field('authdate', authdate)
+ def set_authdate(self, date):
+ if not date and 'GIT_AUTHOR_DATE' in os.environ:
+ date = os.environ['GIT_AUTHOR_DATE']
+ self.__set_field('authdate', date)
def get_commname(self):
return self.__get_field('commname')
def set_commname(self, name):
- if not name and config.has_option('stgit', 'commname'):
- name = config.get('stgit', 'commname')
+ if not name:
+ if config.has_option('stgit', 'commname'):
+ name = config.get('stgit', 'commname')
+ elif 'GIT_COMMITTER_NAME' in os.environ:
+ name = os.environ['GIT_COMMITTER_NAME']
self.__set_field('commname', name)
def get_commemail(self):
return self.__get_field('commemail')
def set_commemail(self, address):
- if not address and config.has_option('stgit', 'commemail'):
- address = config.get('stgit', 'commemail')
+ if not address:
+ if config.has_option('stgit', 'commemail'):
+ address = config.get('stgit', 'commemail')
+ elif 'GIT_COMMITTER_EMAIL' in os.environ:
+ address = os.environ['GIT_COMMITTER_EMAIL']
self.__set_field('commemail', address)
def __init__(self, name = None):
"""Takes a series name as the parameter.
"""
- if name:
- self.__name = name
- else:
- self.__name = git.get_head_file()
-
- if self.__name:
+ try:
+ if name:
+ self.__name = name
+ else:
+ self.__name = git.get_head_file()
base_dir = git.get_base_dir()
- self.__patch_dir = os.path.join(base_dir, 'patches',
- self.__name)
- self.__base_file = os.path.join(base_dir, 'refs', 'bases',
- self.__name)
- self.__applied_file = os.path.join(self.__patch_dir, 'applied')
- self.__unapplied_file = os.path.join(self.__patch_dir, 'unapplied')
- self.__current_file = os.path.join(self.__patch_dir, 'current')
- self.__descr_file = os.path.join(self.__patch_dir, 'description')
+ except git.GitException, ex:
+ raise StackException, 'GIT tree not initialised: %s' % ex
+
+ self.__series_dir = os.path.join(base_dir, 'patches',
+ self.__name)
+ self.__base_file = os.path.join(base_dir, 'refs', 'bases',
+ self.__name)
+
+ self.__applied_file = os.path.join(self.__series_dir, 'applied')
+ self.__unapplied_file = os.path.join(self.__series_dir, 'unapplied')
+ self.__current_file = os.path.join(self.__series_dir, 'current')
+ self.__descr_file = os.path.join(self.__series_dir, 'description')
+
+ # where this series keeps its patches
+ self.__patch_dir = os.path.join(self.__series_dir, 'patches')
+ if not os.path.isdir(self.__patch_dir):
+ self.__patch_dir = self.__series_dir
def get_branch(self):
"""Return the branch name for the Series object
return self.__base_file
def get_protected(self):
- return os.path.isfile(os.path.join(self.__patch_dir, 'protected'))
+ return os.path.isfile(os.path.join(self.__series_dir, 'protected'))
def protect(self):
- protect_file = os.path.join(self.__patch_dir, 'protected')
+ protect_file = os.path.join(self.__series_dir, 'protected')
if not os.path.isfile(protect_file):
create_empty_file(protect_file)
def unprotect(self):
- protect_file = os.path.join(self.__patch_dir, 'protected')
+ protect_file = os.path.join(self.__series_dir, 'protected')
if os.path.isfile(protect_file):
os.remove(protect_file)
create_empty_file(self.__applied_file)
create_empty_file(self.__unapplied_file)
create_empty_file(self.__descr_file)
+ os.makedirs(os.path.join(self.__series_dir, 'patches'))
self.__begin_stack_check()
+ def convert(self):
+ """Either convert to use a separate patch directory, or
+ unconvert to place the patches in the same directory with
+ series control files
+ """
+ if self.__patch_dir == self.__series_dir:
+ print 'Converting old-style to new-style...',
+ sys.stdout.flush()
+
+ self.__patch_dir = os.path.join(self.__series_dir, 'patches')
+ os.makedirs(self.__patch_dir)
+
+ for p in self.get_applied() + self.get_unapplied():
+ src = os.path.join(self.__series_dir, p)
+ dest = os.path.join(self.__patch_dir, p)
+ os.rename(src, dest)
+
+ print 'done'
+
+ else:
+ print 'Converting new-style to old-style...',
+ sys.stdout.flush()
+
+ for p in self.get_applied() + self.get_unapplied():
+ src = os.path.join(self.__patch_dir, p)
+ dest = os.path.join(self.__series_dir, p)
+ os.rename(src, dest)
+
+ if not os.listdir(self.__patch_dir):
+ os.rmdir(self.__patch_dir)
+ print 'done'
+ else:
+ print 'Patch directory %s is not empty.' % self.__name
+
+ self.__patch_dir = self.__series_dir
+
def rename(self, to_name):
"""Renames a series
"""
git.rename_branch(self.__name, to_name)
- if os.path.isdir(self.__patch_dir):
- os.rename(self.__patch_dir, to_stack.__patch_dir)
+ if os.path.isdir(self.__series_dir):
+ os.rename(self.__series_dir, to_stack.__series_dir)
if os.path.exists(self.__base_file):
os.rename(self.__base_file, to_stack.__base_file)
self.__init__(to_name)
+ def clone(self, target_series):
+ """Clones a series
+ """
+ base = read_string(self.get_base_file())
+ git.create_branch(target_series, tree_id = base)
+ Series(target_series).init()
+ new_series = Series(target_series)
+
+ # generate an artificial description file
+ write_string(new_series.__descr_file, 'clone of "%s"' % self.__name)
+
+ # clone self's entire series as unapplied patches
+ patches = self.get_applied() + self.get_unapplied()
+ patches.reverse()
+ for p in patches:
+ patch = self.get_patch(p)
+ new_series.new_patch(p, message = patch.get_description(),
+ can_edit = False, unapplied = True,
+ bottom = patch.get_bottom(),
+ top = patch.get_top(),
+ author_name = patch.get_authname(),
+ author_email = patch.get_authemail(),
+ author_date = patch.get_authdate())
+
+ # fast forward the cloned series to self's top
+ new_series.forward_patches(self.get_applied())
+
def delete(self, force = False):
"""Deletes an stgit series
"""
if not os.listdir(self.__patch_dir):
os.rmdir(self.__patch_dir)
else:
+ print 'Patch directory %s is not empty.' % self.__name
+ if not os.listdir(self.__series_dir):
+ os.rmdir(self.__series_dir)
+ else:
print 'Series directory %s is not empty.' % self.__name
if os.path.exists(self.__base_file):
os.remove(self.__base_file)
- def refresh_patch(self, message = None, edit = False, show_patch = False,
+ def refresh_patch(self, files = None, message = None, edit = False,
+ show_patch = False,
cache_update = True,
author_name = None, author_email = None,
author_date = None,
if not committer_email:
committer_email = patch.get_commemail()
- commit_id = git.commit(message = descr, parents = [patch.get_bottom()],
+ commit_id = git.commit(files = files,
+ message = descr, parents = [patch.get_bottom()],
cache_update = cache_update,
allowempty = True,
author_name = author_name,