Example #1
0
def rename_branch(from_name, to_name):
    """Rename a git branch
    """
    if not branch_exists(from_name):
        raise GitException, 'Branch "%s" does not exist' % from_name
    if branch_exists(to_name):
        raise GitException, 'Branch "%s" already exists' % to_name

    if get_head_file() == from_name:
        set_head_file(to_name)
    rename(os.path.join(basedir.get(), 'refs', 'heads'), from_name, to_name)

    reflog_dir = os.path.join(basedir.get(), 'logs', 'refs', 'heads')
    if os.path.exists(reflog_dir) \
           and os.path.exists(os.path.join(reflog_dir, from_name)):
        rename(reflog_dir, from_name, to_name)
Example #2
0
def parse_rev(rev):
    """Parse a revision specification into its
    patchname@branchname//patch_id parts. If no branch name has a slash
    in it, also accept / instead of //."""
    files, dirs = list_files_and_dirs(os.path.join(basedir.get(),
                                                   'refs', 'heads'))
    if len(dirs) != 0:
        # We have branch names with / in them.
        branch_chars = r'[^@]'
        patch_id_mark = r'//'
    else:
        # No / in branch names.
        branch_chars = r'[^@/]'
        patch_id_mark = r'(/|//)'
    patch_re = r'(?P<patch>[^@/]+)'
    branch_re = r'@(?P<branch>%s+)' % branch_chars
    patch_id_re = r'%s(?P<patch_id>[a-z.]*)' % patch_id_mark

    # Try //patch_id.
    m = re.match(r'^%s$' % patch_id_re, rev)
    if m:
        return None, None, m.group('patch_id')

    # Try path[@branch]//patch_id.
    m = re.match(r'^%s(%s)?%s$' % (patch_re, branch_re, patch_id_re), rev)
    if m:
        return m.group('patch'), m.group('branch'), m.group('patch_id')

    # Try patch[@branch].
    m = re.match(r'^%s(%s)?$' % (patch_re, branch_re), rev)
    if m:
        return m.group('patch'), m.group('branch'), None

    # No, we can't parse that.
    raise RevParseException
Example #3
0
def create_branch(new_branch, tree_id = None):
    """Create a new branch in the git repository
    """
    if branch_exists(new_branch):
        raise GitException, 'Branch "%s" already exists' % new_branch

    current_head = get_head()
    set_head_file(new_branch)
    __set_head(current_head)

    # a checkout isn't needed if new branch points to the current head
    if tree_id:
        switch(tree_id)

    if os.path.isfile(os.path.join(basedir.get(), 'MERGE_HEAD')):
        os.remove(os.path.join(basedir.get(), 'MERGE_HEAD'))
Example #4
0
def create_branch(new_branch, tree_id=None):
    """Create a new branch in the git repository
    """
    if branch_exists(new_branch):
        raise GitException, 'Branch "%s" already exists' % new_branch

    current_head = get_head()
    set_head_file(new_branch)
    __set_head(current_head)

    # a checkout isn't needed if new branch points to the current head
    if tree_id:
        switch(tree_id)

    if os.path.isfile(os.path.join(basedir.get(), 'MERGE_HEAD')):
        os.remove(os.path.join(basedir.get(), 'MERGE_HEAD'))
Example #5
0
def delete_branch(name):
    """Delete a git branch
    """
    if not branch_exists(name):
        raise GitException, 'Branch "%s" does not exist' % name
    remove_file_and_dirs(os.path.join(basedir.get(), 'refs', 'heads'),
                         name)
Example #6
0
def rename_branch(from_name, to_name):
    """Rename a git branch
    """
    if not branch_exists(from_name):
        raise GitException, 'Branch "%s" does not exist' % from_name
    if branch_exists(to_name):
        raise GitException, 'Branch "%s" already exists' % to_name

    if get_head_file() == from_name:
        set_head_file(to_name)
    rename(os.path.join(basedir.get(), 'refs', 'heads'),
           from_name, to_name)

    reflog_dir = os.path.join(basedir.get(), 'logs', 'refs', 'heads')
    if os.path.exists(reflog_dir) \
           and os.path.exists(os.path.join(reflog_dir, from_name)):
        rename(reflog_dir, from_name, to_name)
Example #7
0
def func(parser, options, args):
    """Mark the conflict as resolved
    """
    if options.reset \
           and options.reset not in file_extensions():
        raise CmdException, 'Unknown reset state: %s' % options.reset

    if options.all and not options.interactive:
        resolved_all(options.reset)
        return

    conflicts = git.get_conflicts()

    if len(args) != 0:
        files = args
    elif options.all:
        files = conflicts
    else:
        parser.error('incorrect number of arguments')

    if not conflicts:
        raise CmdException, 'No more conflicts'

    # check for arguments validity
    if not options.all:
        for filename in files:
            if not filename in conflicts:
                raise CmdException, 'No conflicts for "%s"' % filename

    # resolved
    try:
        for filename in files:
            if options.interactive:
                interactive_merge(filename)
            resolved(filename, options.reset)
            del conflicts[conflicts.index(filename)]
    finally:
        # save or remove the conflicts file. Needs a finally clause to
        # ensure that already solved conflicts are marked
        if conflicts == []:
            os.remove(os.path.join(basedir.get(), 'conflicts'))
        else:
            f = file(os.path.join(basedir.get(), 'conflicts'), 'w+')
            f.writelines([line + '\n' for line in conflicts])
            f.close()
Example #8
0
def func(parser, options, args):
    """Mark the conflict as resolved
    """
    if options.reset \
           and options.reset not in file_extensions():
        raise CmdException, 'Unknown reset state: %s' % options.reset

    if options.all and not options.interactive:
        resolved_all(options.reset)
        return

    conflicts = git.get_conflicts()

    if len(args) != 0:
        files = args
    elif options.all:
        files = conflicts
    else:
        parser.error('incorrect number of arguments')

    if not conflicts:
        raise CmdException, 'No more conflicts'

    # check for arguments validity
    if not options.all:
        for filename in files:
            if not filename in conflicts:
                raise CmdException, 'No conflicts for "%s"' % filename

    # resolved
    try:
        for filename in files:
            if options.interactive:
                interactive_merge(filename)
            resolved(filename, options.reset)
            del conflicts[conflicts.index(filename)]
    finally:
        # save or remove the conflicts file. Needs a finally clause to
        # ensure that already solved conflicts are marked
        if conflicts == []:
            os.remove(os.path.join(basedir.get(), 'conflicts'))
        else:
            f = file(os.path.join(basedir.get(), 'conflicts'), 'w+')
            f.writelines([line + '\n' for line in conflicts])
            f.close()
Example #9
0
 def __init__(self, name=None):
     try:
         if name:
             self.set_name(name)
         else:
             self.set_name(git.get_head_file())
         self.__base_dir = basedir.get()
     except git.GitException, ex:
         raise StackException, "GIT tree not initialised: %s" % ex
Example #10
0
 def __init__(self, name=None):
     try:
         if name:
             self.set_name(name)
         else:
             self.set_name(git.get_head_file())
         self.__base_dir = basedir.get()
     except git.GitException, ex:
         raise StackException, 'GIT tree not initialised: %s' % ex
Example #11
0
def switch_branch(new_branch):
    """Switch to a git branch
    """
    global __head

    if not branch_exists(new_branch):
        raise GitException, 'Branch "%s" does not exist' % new_branch

    tree_id = rev_parse(os.path.join('refs', 'heads', new_branch)
                        + '^{commit}')
    if tree_id != get_head():
        refresh_index()
        if __run('git-read-tree -u -m', [get_head(), tree_id]) != 0:
            raise GitException, 'git-read-tree failed (local changes maybe?)'
        __head = tree_id
    set_head_file(new_branch)

    if os.path.isfile(os.path.join(basedir.get(), 'MERGE_HEAD')):
        os.remove(os.path.join(basedir.get(), 'MERGE_HEAD'))
Example #12
0
def switch_branch(new_branch):
    """Switch to a git branch
    """
    global __head

    if not branch_exists(new_branch):
        raise GitException, 'Branch "%s" does not exist' % new_branch

    tree_id = rev_parse(
        os.path.join('refs', 'heads', new_branch) + '^{commit}')
    if tree_id != get_head():
        refresh_index()
        if __run('git-read-tree -u -m', [get_head(), tree_id]) != 0:
            raise GitException, 'git-read-tree failed (local changes maybe?)'
        __head = tree_id
    set_head_file(new_branch)

    if os.path.isfile(os.path.join(basedir.get(), 'MERGE_HEAD')):
        os.remove(os.path.join(basedir.get(), 'MERGE_HEAD'))
Example #13
0
    def __init__(self, name=None):
        try:
            if name:
                self.name = name
            else:
                self.name = git.get_head_file()
            self._base_dir = basedir.get()
        except git.GitException as ex:
            raise StackException('GIT tree not initialised: %s' % ex)

        self._dir = os.path.join(self._base_dir, 'patches', self.name)
Example #14
0
def switch_branch(new_branch):
    """Switch to a git branch
    """
    global __head

    if not branch_exists(new_branch):
        raise GitException('Branch "%s" does not exist' % new_branch)

    tree_id = rev_parse('refs/heads/%s^{commit}' % new_branch)
    if tree_id != get_head():
        refresh_index()
        try:
            GRun('read-tree', '-u', '-m', get_head(), tree_id).run()
        except GitRunException:
            raise GitException('read-tree failed (local changes maybe?)')
        __head = tree_id
    set_head_file(new_branch)

    if os.path.isfile(os.path.join(basedir.get(), 'MERGE_HEAD')):
        os.remove(os.path.join(basedir.get(), 'MERGE_HEAD'))
Example #15
0
def tree_status(files=None,
                tree_id='HEAD',
                unknown=False,
                noexclude=True,
                verbose=False,
                diff_flags=[]):
    """Returns a list of pairs - [status, filename]
    """
    if verbose:
        out.start('Checking for changes in the working directory')

    refresh_index()

    if not files:
        files = []
    cache_files = []

    # unknown files
    if unknown:
        exclude_file = os.path.join(basedir.get(), 'info', 'exclude')
        base_exclude = [
            '--exclude=%s' % s
            for s in ['*.[ao]', '*.pyc', '.*', '*~', '#*', 'TAGS', 'tags']
        ]
        base_exclude.append('--exclude-per-directory=.gitignore')

        if os.path.exists(exclude_file):
            extra_exclude = ['--exclude-from=%s' % exclude_file]
        else:
            extra_exclude = []
        if noexclude:
            extra_exclude = base_exclude = []

        lines = _output_lines(['git-ls-files', '--others', '--directory'] +
                              base_exclude + extra_exclude)
        cache_files += [('?', line.strip()) for line in lines]

    # conflicted files
    conflicts = get_conflicts()
    if not conflicts:
        conflicts = []
    cache_files += [('C', filename) for filename in conflicts]

    # the rest
    for line in _output_lines(['git-diff-index'] + diff_flags +
                              [tree_id, '--'] + files):
        fs = tuple(line.rstrip().split(' ', 4)[-1].split('\t', 1))
        if fs[1] not in conflicts:
            cache_files.append(fs)

    if verbose:
        out.done()

    return cache_files
Example #16
0
def get_conflicts():
    """Return the list of file conflicts
    """
    conflicts_file = os.path.join(basedir.get(), 'conflicts')
    if os.path.isfile(conflicts_file):
        f = file(conflicts_file)
        names = [line.strip() for line in f.readlines()]
        f.close()
        return names
    else:
        return None
Example #17
0
File: stack.py Project: snits/stgit
    def __init__(self, name = None):
        try:
            if name:
                self.set_name (name)
            else:
                self.set_name (git.get_head_file())
            self.__base_dir = basedir.get()
        except git.GitException as ex:
            raise StackException('GIT tree not initialised: %s' % ex)

        self._set_dir(os.path.join(self.__base_dir, 'patches', self.get_name()))
Example #18
0
def get_conflicts():
    """Return the list of file conflicts
    """
    conflicts_file = os.path.join(basedir.get(), 'conflicts')
    if os.path.isfile(conflicts_file):
        f = file(conflicts_file)
        names = [line.strip() for line in f.readlines()]
        f.close()
        return names
    else:
        return None
Example #19
0
File: git.py Project: guanqun/stgit
def switch_branch(new_branch):
    """Switch to a git branch
    """
    global __head

    if not branch_exists(new_branch):
        raise GitException, 'Branch "%s" does not exist' % new_branch

    tree_id = rev_parse('refs/heads/%s^{commit}' % new_branch)
    if tree_id != get_head():
        refresh_index()
        try:
            GRun('read-tree', '-u', '-m', get_head(), tree_id).run()
        except GitRunException:
            raise GitException, 'read-tree failed (local changes maybe?)'
        __head = tree_id
    set_head_file(new_branch)

    if os.path.isfile(os.path.join(basedir.get(), 'MERGE_HEAD')):
        os.remove(os.path.join(basedir.get(), 'MERGE_HEAD'))
Example #20
0
def rename_branch(from_name, to_name):
    """Rename a git branch."""
    rename_ref('refs/heads/%s' % from_name, 'refs/heads/%s' % to_name)
    try:
        if get_head_file() == from_name:
            set_head_file(to_name)
    except DetachedHeadException:
        pass  # detached HEAD, so the renamee can't be the current branch
    reflog_dir = os.path.join(basedir.get(), 'logs', 'refs', 'heads')
    if (os.path.exists(reflog_dir)
            and os.path.exists(os.path.join(reflog_dir, from_name))):
        rename(reflog_dir, from_name, to_name)
Example #21
0
File: git.py Project: guanqun/stgit
def rename_branch(from_name, to_name):
    """Rename a git branch."""
    rename_ref('refs/heads/%s' % from_name, 'refs/heads/%s' % to_name)
    try:
        if get_head_file() == from_name:
            set_head_file(to_name)
    except DetachedHeadException:
        pass # detached HEAD, so the renamee can't be the current branch
    reflog_dir = os.path.join(basedir.get(), 'logs', 'refs', 'heads')
    if os.path.exists(reflog_dir) \
           and os.path.exists(os.path.join(reflog_dir, from_name)):
        rename(reflog_dir, from_name, to_name)
Example #22
0
File: git.py Project: snits/stgit
def create_branch(new_branch, tree_id = None):
    """Create a new branch in the git repository
    """
    if branch_exists(new_branch):
        raise GitException('Branch "%s" already exists' % new_branch)

    current_head_file = get_head_file()
    current_head = get_head()
    set_head_file(new_branch)
    __set_head(current_head)

    # a checkout isn't needed if new branch points to the current head
    if tree_id:
        try:
            switch(tree_id)
        except GitException:
            # Tree switching failed. Revert the head file
            set_head_file(current_head_file)
            delete_branch(new_branch)
            raise

    if os.path.isfile(os.path.join(basedir.get(), 'MERGE_HEAD')):
        os.remove(os.path.join(basedir.get(), 'MERGE_HEAD'))
Example #23
0
def create_branch(new_branch, tree_id=None):
    """Create a new branch in the git repository
    """
    if branch_exists(new_branch):
        raise GitException('Branch "%s" already exists' % new_branch)

    current_head_file = get_head_file()
    current_head = get_head()
    set_head_file(new_branch)
    __set_head(current_head)

    # a checkout isn't needed if new branch points to the current head
    if tree_id:
        try:
            switch(tree_id)
        except GitException:
            # Tree switching failed. Revert the head file
            set_head_file(current_head_file)
            delete_branch(new_branch)
            raise

    if os.path.isfile(os.path.join(basedir.get(), 'MERGE_HEAD')):
        os.remove(os.path.join(basedir.get(), 'MERGE_HEAD'))
Example #24
0
def tree_status(files = None, tree_id = 'HEAD', unknown = False,
                  noexclude = True, verbose = False, diff_flags = []):
    """Returns a list of pairs - [status, filename]
    """
    if verbose:
        out.start('Checking for changes in the working directory')

    refresh_index()

    if not files:
        files = []
    cache_files = []

    # unknown files
    if unknown:
        exclude_file = os.path.join(basedir.get(), 'info', 'exclude')
        base_exclude = ['--exclude=%s' % s for s in
                        ['*.[ao]', '*.pyc', '.*', '*~', '#*', 'TAGS', 'tags']]
        base_exclude.append('--exclude-per-directory=.gitignore')

        if os.path.exists(exclude_file):
            extra_exclude = ['--exclude-from=%s' % exclude_file]
        else:
            extra_exclude = []
        if noexclude:
            extra_exclude = base_exclude = []

        lines = _output_lines(['git-ls-files', '--others', '--directory']
                        + base_exclude + extra_exclude)
        cache_files += [('?', line.strip()) for line in lines]

    # conflicted files
    conflicts = get_conflicts()
    if not conflicts:
        conflicts = []
    cache_files += [('C', filename) for filename in conflicts]

    # the rest
    for line in _output_lines(['git-diff-index'] + diff_flags +
                              [ tree_id, '--'] + files):
        fs = tuple(line.rstrip().split(' ',4)[-1].split('\t',1))
        if fs[1] not in conflicts:
            cache_files.append(fs)

    if verbose:
        out.done()

    return cache_files
Example #25
0
def get_template(tfile):
    """Return the string in the template file passed as argument or
    None if the file wasn't found.
    """
    tmpl_list = [ os.path.join(basedir.get(), tfile),
                  os.path.join(os.path.expanduser('~'), '.stgit', 'templates',
                               tfile),
                  os.path.join(sys.prefix, 'share', 'stgit', 'templates',
                               tfile) ]

    for t in tmpl_list:
        if os.path.isfile(t):
            with open(t) as f:
                return f.read()
    else:
        return None
Example #26
0
def get_template(tfile):
    """Return the string in the template file passed as argument or
    None if the file wasn't found.
    """
    tmpl_list = [
        os.path.join(basedir.get(), tfile),
        os.path.join(os.path.expanduser('~'), '.stgit', 'templates', tfile),
        os.path.join(sys.prefix, 'share', 'stgit', 'templates', tfile)
    ]

    for t in tmpl_list:
        if os.path.isfile(t):
            with open(t) as f:
                return f.read()
    else:
        return None
Example #27
0
def get_template(tfile):
    """Return the string in the template file passed as argument or
    None if the file wasn't found.
    """
    tmpl_dirs = [
        basedir.get(),
        os.path.join(os.path.expanduser('~'), '.stgit', 'templates'),
        os.path.join(sys.prefix, 'share', 'stgit', 'templates'),
        os.path.join(os.path.dirname(__file__), os.pardir, 'templates'),
    ]

    for d in tmpl_dirs:
        tmpl_path = os.path.join(d, tfile)
        if os.path.isfile(tmpl_path):
            with io.open(tmpl_path, 'r') as f:
                return f.read()
    else:
        return None
Example #28
0
def fetch_head():
    """Return the git id for the tip of the parent branch as left by
    'git fetch'.
    """

    fetch_head = None
    stream = open(os.path.join(basedir.get(), 'FETCH_HEAD'), "r")
    for line in stream:
        # Only consider lines not tagged not-for-merge
        m = re.match('^([^\t]*)\t\t', line)
        if m:
            if fetch_head:
                raise GitException, "StGit does not support multiple FETCH_HEAD"
            else:
                fetch_head = m.group(1)
    stream.close()

    # here we are sure to have a single fetch_head
    return fetch_head
Example #29
0
def fetch_head():
    """Return the git id for the tip of the parent branch as left by
    'git fetch'.
    """

    fetch_head=None
    stream = open(os.path.join(basedir.get(), 'FETCH_HEAD'), "r")
    for line in stream:
        # Only consider lines not tagged not-for-merge
        m = re.match('^([^\t]*)\t\t', line)
        if m:
            if fetch_head:
                raise GitException, "StGit does not support multiple FETCH_HEAD"
            else:
                fetch_head=m.group(1)
    stream.close()

    # here we are sure to have a single fetch_head
    return fetch_head
Example #30
0
def remotes_local_branches(remote):
    """Returns the list of local branches fetched from given remote
    """
    branches = []
    if remote in __remotes_from_config():
        for line in config.getall('remote.%s.fetch' % remote):
            branches.append(refspec_localpart(line))
    elif remote in __remotes_from_dir('remotes'):
        stream = open(os.path.join(basedir.get(), 'remotes', remote), 'r')
        for line in stream:
            # Only consider Pull lines
            m = re.match('^Pull: (.*)\n$', line)
            if m:
                branches.append(refspec_localpart(m.group(1)))
        stream.close()
    elif remote in __remotes_from_dir('branches'):
        # old-style branches only declare one branch
        branches.append('refs/heads/' + remote)
    else:
        raise GitException('Unknown remote "%s"' % remote)

    return branches
Example #31
0
def remotes_local_branches(remote):
    """Returns the list of local branches fetched from given remote
    """

    branches = []
    if remote in __remotes_from_config():
        for line in config.getall('remote.%s.fetch' % remote):
            branches.append(refspec_localpart(line))
    elif remote in __remotes_from_dir('remotes'):
        stream = open(os.path.join(basedir.get(), 'remotes', remote), 'r')
        for line in stream:
            # Only consider Pull lines
            m = re.match('^Pull: (.*)\n$', line)
            if m:
                branches.append(refspec_localpart(m.group(1)))
        stream.close()
    elif remote in __remotes_from_dir('branches'):
        # old-style branches only declare one branch
        branches.append('refs/heads/'+remote);
    else:
        raise GitException, 'Unknown remote "%s"' % remote

    return branches
Example #32
0
def __conflict(path):
    """Write the conflict file for the 'path' variable and exit
    """
    append_string(os.path.join(basedir.get(), 'conflicts'), path)
Example #33
0
def resolved_all(reset = None):
    conflicts = git.get_conflicts()
    if conflicts:
        for filename in conflicts:
            resolved(filename, reset)
        os.remove(os.path.join(basedir.get(), 'conflicts'))
Example #34
0
def check_conflicts():
    if os.path.exists(os.path.join(basedir.get(), 'conflicts')):
        raise CmdException, \
              'Unsolved conflicts. Please resolve them first or\n' \
              '  revert the changes with "status --reset"'
Example #35
0
def __remotes_from_dir(dir):
    d = os.path.join(basedir.get(), dir)
    if os.path.exists(d):
        return os.listdir(d)
    else:
        return []
Example #36
0
def func(parser, options, args):

    if options.create:

        if len(args) == 0 or len(args) > 2:
            parser.error('incorrect number of arguments')

        check_local_changes()
        check_conflicts()
        check_head_top_equal()

        tree_id = None
        if len(args) >= 2:
            parentbranch = None
            try:
                branchpoint = git.rev_parse(args[1])

                # first, look for branchpoint in well-known branch namespaces
                for namespace in ('refs/heads/', 'remotes/'):
                    # check if branchpoint exists in namespace
                    try:
                        maybehead = git.rev_parse(namespace + args[1])
                    except git.GitException:
                        maybehead = None

                    # check if git resolved branchpoint to this namespace
                    if maybehead and branchpoint == maybehead:
                        # we are for sure referring to a branch
                        parentbranch = namespace + args[1]

            except git.GitException:
                # should use a more specific exception to catch only
                # non-git refs ?
                out.info('Don\'t know how to determine parent branch'
                         ' from "%s"' % args[1])
                # exception in branch = rev_parse() leaves branchpoint unbound
                branchpoint = None

            tree_id = branchpoint or git_id(args[1])

            if parentbranch:
                out.info('Recording "%s" as parent branch' % parentbranch)
            else:
                out.info('Don\'t know how to determine parent branch'
                         ' from "%s"' % args[1])
        else:
            # branch stack off current branch
            parentbranch = git.get_head_file()

        if parentbranch:
            parentremote = git.identify_remote(parentbranch)
            if parentremote:
                out.info('Using remote "%s" to pull parent from' %
                         parentremote)
            else:
                out.info('Recording as a local branch')
        else:
            # no known parent branch, can't guess the remote
            parentremote = None

        stack.Series(args[0]).init(create_at=tree_id,
                                   parent_remote=parentremote,
                                   parent_branch=parentbranch)

        out.info('Branch "%s" created' % args[0])
        return

    elif options.clone:

        if len(args) == 0:
            clone = crt_series.get_name() + \
                    time.strftime('-%C%y%m%d-%H%M%S')
        elif len(args) == 1:
            clone = args[0]
        else:
            parser.error('incorrect number of arguments')

        check_local_changes()
        check_conflicts()
        check_head_top_equal()

        out.start('Cloning current branch to "%s"' % clone)
        crt_series.clone(clone)
        out.done()

        return

    elif options.delete:

        if len(args) != 1:
            parser.error('incorrect number of arguments')
        __delete_branch(args[0], options.force)
        return

    elif options.list:

        if len(args) != 0:
            parser.error('incorrect number of arguments')

        branches = []
        basepath = os.path.join(basedir.get(), 'refs', 'heads')
        for path, files, dirs in walk_tree(basepath):
            branches += [os.path.join(path, f) for f in files]
        branches.sort()

        if branches:
            out.info('Available branches:')
            max_len = max([len(i) for i in branches])
            for i in branches:
                __print_branch(i, max_len)
        else:
            out.info('No branches')
        return

    elif options.protect:

        if len(args) == 0:
            branch_name = crt_series.get_name()
        elif len(args) == 1:
            branch_name = args[0]
        else:
            parser.error('incorrect number of arguments')
        branch = stack.Series(branch_name)

        if not branch.is_initialised():
            raise CmdException, 'Branch "%s" is not controlled by StGIT' \
                  % branch_name

        out.start('Protecting branch "%s"' % branch_name)
        branch.protect()
        out.done()

        return

    elif options.rename:

        if len(args) != 2:
            parser.error('incorrect number of arguments')

        if __is_current_branch(args[0]):
            raise CmdException, 'Renaming the current branch is not supported'

        stack.Series(args[0]).rename(args[1])

        out.info('Renamed branch "%s" to "%s"' % (args[0], args[1]))

        return

    elif options.unprotect:

        if len(args) == 0:
            branch_name = crt_series.get_name()
        elif len(args) == 1:
            branch_name = args[0]
        else:
            parser.error('incorrect number of arguments')
        branch = stack.Series(branch_name)

        if not branch.is_initialised():
            raise CmdException, 'Branch "%s" is not controlled by StGIT' \
                  % branch_name

        out.info('Unprotecting branch "%s"' % branch_name)
        branch.unprotect()
        out.done()

        return

    elif options.description is not None:

        if len(args) == 0:
            branch_name = crt_series.get_name()
        elif len(args) == 1:
            branch_name = args[0]
        else:
            parser.error('incorrect number of arguments')
        branch = stack.Series(branch_name)

        if not branch.is_initialised():
            raise CmdException, 'Branch "%s" is not controlled by StGIT' \
                  % branch_name

        branch.set_description(options.description)

        return

    elif len(args) == 1:

        if __is_current_branch(args[0]):
            raise CmdException, 'Branch "%s" is already the current branch' \
                  % args[0]

        check_local_changes()
        check_conflicts()
        check_head_top_equal()

        out.start('Switching to branch "%s"' % args[0])
        git.switch_branch(args[0])
        out.done()
        return

    # default action: print the current branch
    if len(args) != 0:
        parser.error('incorrect number of arguments')

    print crt_series.get_name()
Example #37
0
File: git.py Project: guanqun/stgit
def exclude_files():
    files = [os.path.join(basedir.get(), 'info', 'exclude')]
    user_exclude = config.get('core.excludesfile')
    if user_exclude:
        files.append(user_exclude)
    return files
Example #38
0
def func(parser, options, args):

    if options.create:

        if len(args) == 0 or len(args) > 2:
            parser.error('incorrect number of arguments')

        check_local_changes()
        check_conflicts()
        check_head_top_equal()

        tree_id = None
        if len(args) >= 2:
            parentbranch = None
            try:
                branchpoint = git.rev_parse(args[1])

                # first, look for branchpoint in well-known branch namespaces
                for namespace in ('refs/heads/', 'remotes/'):
                    # check if branchpoint exists in namespace
                    try:
                        maybehead = git.rev_parse(namespace + args[1])
                    except git.GitException:
                        maybehead = None

                    # check if git resolved branchpoint to this namespace
                    if maybehead and branchpoint == maybehead:
                        # we are for sure referring to a branch
                        parentbranch = namespace + args[1]

            except git.GitException:
                # should use a more specific exception to catch only
                # non-git refs ?
                out.info('Don\'t know how to determine parent branch'
                         ' from "%s"' % args[1])
                # exception in branch = rev_parse() leaves branchpoint unbound
                branchpoint = None

            tree_id = branchpoint or git_id(args[1])

            if parentbranch:
                out.info('Recording "%s" as parent branch' % parentbranch)
            else:
                out.info('Don\'t know how to determine parent branch'
                         ' from "%s"' % args[1])                
        else:
            # branch stack off current branch
            parentbranch = git.get_head_file()

        if parentbranch:
            parentremote = git.identify_remote(parentbranch)
            if parentremote:
                out.info('Using remote "%s" to pull parent from'
                         % parentremote)
            else:
                out.info('Recording as a local branch')
        else:
            # no known parent branch, can't guess the remote
            parentremote = None

        stack.Series(args[0]).init(create_at = tree_id,
                                   parent_remote = parentremote,
                                   parent_branch = parentbranch)

        out.info('Branch "%s" created' % args[0])
        return

    elif options.clone:

        if len(args) == 0:
            clone = crt_series.get_name() + \
                    time.strftime('-%C%y%m%d-%H%M%S')
        elif len(args) == 1:
            clone = args[0]
        else:
            parser.error('incorrect number of arguments')

        check_local_changes()
        check_conflicts()
        check_head_top_equal()

        out.start('Cloning current branch to "%s"' % clone)
        crt_series.clone(clone)
        out.done()

        return

    elif options.delete:

        if len(args) != 1:
            parser.error('incorrect number of arguments')
        __delete_branch(args[0], options.force)
        return

    elif options.list:

        if len(args) != 0:
            parser.error('incorrect number of arguments')

        branches = []
        basepath = os.path.join(basedir.get(), 'refs', 'heads')
        for path, files, dirs in walk_tree(basepath):
            branches += [os.path.join(path, f) for f in files]
        branches.sort()

        if branches:
            out.info('Available branches:')
            max_len = max([len(i) for i in branches])
            for i in branches:
                __print_branch(i, max_len)
        else:
            out.info('No branches')
        return

    elif options.protect:

        if len(args) == 0:
            branch_name = crt_series.get_name()
        elif len(args) == 1:
            branch_name = args[0]
        else:
            parser.error('incorrect number of arguments')
        branch = stack.Series(branch_name)

        if not branch.is_initialised():
            raise CmdException, 'Branch "%s" is not controlled by StGIT' \
                  % branch_name

        out.start('Protecting branch "%s"' % branch_name)
        branch.protect()
        out.done()

        return

    elif options.rename:

        if len(args) != 2:
            parser.error('incorrect number of arguments')

        if __is_current_branch(args[0]):
            raise CmdException, 'Renaming the current branch is not supported'

        stack.Series(args[0]).rename(args[1])

        out.info('Renamed branch "%s" to "%s"' % (args[0], args[1]))

        return

    elif options.unprotect:

        if len(args) == 0:
            branch_name = crt_series.get_name()
        elif len(args) == 1:
            branch_name = args[0]
        else:
            parser.error('incorrect number of arguments')
        branch = stack.Series(branch_name)

        if not branch.is_initialised():
            raise CmdException, 'Branch "%s" is not controlled by StGIT' \
                  % branch_name

        out.info('Unprotecting branch "%s"' % branch_name)
        branch.unprotect()
        out.done()

        return

    elif options.description is not None:

        if len(args) == 0:
            branch_name = crt_series.get_name()
        elif len(args) == 1:
            branch_name = args[0]
        else:
            parser.error('incorrect number of arguments')
        branch = stack.Series(branch_name)

        if not branch.is_initialised():
            raise CmdException, 'Branch "%s" is not controlled by StGIT' \
                  % branch_name

        branch.set_description(options.description)

        return

    elif len(args) == 1:

        if __is_current_branch(args[0]):
            raise CmdException, 'Branch "%s" is already the current branch' \
                  % args[0]

        check_local_changes()
        check_conflicts()
        check_head_top_equal()

        out.start('Switching to branch "%s"' % args[0])
        git.switch_branch(args[0])
        out.done()
        return

    # default action: print the current branch
    if len(args) != 0:
        parser.error('incorrect number of arguments')

    print crt_series.get_name()
Example #39
0
def delete_branch(name):
    """Delete a git branch
    """
    if not branch_exists(name):
        raise GitException, 'Branch "%s" does not exist' % name
    remove_file_and_dirs(os.path.join(basedir.get(), 'refs', 'heads'), name)
Example #40
0
def __conflict(path):
    """Write the conflict file for the 'path' variable and exit
    """
    append_string(os.path.join(basedir.get(), 'conflicts'), path)
Example #41
0
def __remotes_from_dir(dir):
    d = os.path.join(basedir.get(), dir)
    if os.path.exists(d):
        return os.listdir(d)
    else:
        return None