Пример #1
0
def non_git_rebase(upstream_branch, directory=None):
    # Create a temporary storage directory
    tmp_dir = mkdtemp()
    # Get the root of the git repository
    git_root = get_root(directory)
    try:
        # Copy the new upstream source into the temporary directory
        with inbranch(upstream_branch):
            ignores = ('.git', '.gitignore', '.svn', '.hgignore', '.hg', 'CVS')
            parent_source = os.path.join(tmp_dir, 'parent_source')
            my_copytree(git_root, parent_source, ignores)

        # Clear out the local branch
        execute_command('git rm -rf *', cwd=directory)
        # Collect .* files (excluding .git)
        dot_items = []
        for item in os.listdir(git_root):
            if item in ['.git', '..', '.']:
                continue
            if item.startswith('.'):
                dot_items.append(item)
        # Remove and .* files missed by 'git rm -rf *'
        if len(dot_items) > 0:
            execute_command('git rm -rf ' + ' '.join(dot_items), cwd=directory)
        # Clear out any untracked files
        execute_command('git clean -fdx', cwd=directory)  # for good measure?

        # Copy the parent source into the newly cleaned directory
        my_copytree(parent_source, git_root)

        # Commit changes to the repository
        execute_command('git add ./*', cwd=directory)
        # Collect .* files
        dot_items = []
        for item in os.listdir(git_root):
            if item in ['.git', '..', '.']:
                continue
            if item.startswith('.'):
                dot_items.append(item)
        # Add any .* files missed by 'git add ./*'
        if len(dot_items) > 0:
            execute_command('git add ' + ' '.join(dot_items), cwd=directory)
        # Remove any straggling untracked files
        execute_command('git clean -dXf', cwd=directory)
        # Only if we have local changes commit
        # (not true if the upstream didn't change any files)
        cmd = 'git commit '
        if not has_changes(directory):
            cmd += '--allow-empty '
        cmd += '-m "Rebase from \'' + upstream_branch + "'"
        if not has_changes(directory):
            cmd += " (no changes)"
        cmd += '"'
        execute_command(cmd, cwd=directory)
    finally:
        # Clean up
        if os.path.exists(tmp_dir):
            shutil.rmtree(tmp_dir)
Пример #2
0
def non_git_rebase(upstream_branch, directory=None):
    # Create a temporary storage directory
    tmp_dir = mkdtemp()
    # Get the root of the git repository
    git_root = get_root(directory)
    try:
        # Copy the new upstream source into the temporary directory
        with inbranch(upstream_branch):
            ignores = (".git", ".gitignore", ".svn", ".hgignore", ".hg", "CVS")
            parent_source = os.path.join(tmp_dir, "parent_source")
            my_copytree(git_root, parent_source, ignores)

        # Clear out the local branch
        execute_command("git rm -rf *", cwd=directory)
        # Collect .* files (excluding .git)
        dot_items = []
        for item in os.listdir(git_root):
            if item in [".git", "..", "."]:
                continue
            if item.startswith("."):
                dot_items.append(item)
        # Remove and .* files missed by 'git rm -rf *'
        if len(dot_items) > 0:
            execute_command("git rm -rf " + " ".join(dot_items), cwd=directory)
        # Clear out any untracked files
        execute_command("git clean -fdx", cwd=directory)  # for good measure?

        # Copy the parent source into the newly cleaned directory
        my_copytree(parent_source, git_root)

        # Commit changes to the repository
        execute_command("git add ./*", cwd=directory)
        # Collect .* files
        dot_items = []
        for item in os.listdir(git_root):
            if item in [".git", "..", "."]:
                continue
            if item.startswith("."):
                dot_items.append(item)
        # Add any .* files missed by 'git add ./*'
        if len(dot_items) > 0:
            execute_command("git add " + " ".join(dot_items), cwd=directory)
        # Remove any straggling untracked files
        execute_command("git clean -dXf", cwd=directory)
        # Only if we have local changes commit
        # (not true if the upstream didn't change any files)
        cmd = "git commit "
        if not has_changes(directory):
            cmd += "--allow-empty "
        cmd += "-m \"Rebase from '" + upstream_branch + "'"
        if not has_changes(directory):
            cmd += " (no changes)"
        cmd += '"'
        execute_command(cmd, cwd=directory)
    finally:
        # Clean up
        if os.path.exists(tmp_dir):
            shutil.rmtree(tmp_dir)
Пример #3
0
def upconvert_bloom_to_config_branch():
    global _has_checked_bloom_branch
    if _has_checked_bloom_branch:
        return
    # Assert that this repository does not have multiple remotes
    check_for_multiple_remotes()
    if get_root() is None:
        # Not a git repository
        return
    track_branches(['bloom', BLOOM_CONFIG_BRANCH])
    if show('bloom', PLACEHOLDER_FILE) is not None:
        return
    if show('bloom', 'bloom.conf') is not None:
        # Wait for the bloom.conf upconvert...
        return
    if not branch_exists('bloom'):
        return
    _has_checked_bloom_branch = True
    info("Moving configurations from deprecated 'bloom' branch "
         "to the '{0}' branch.".format(BLOOM_CONFIG_BRANCH))
    tmp_dir = mkdtemp()
    git_root = get_root()
    try:
        # Copy the new upstream source into the temporary directory
        with inbranch('bloom'):
            ignores = ('.git', '.gitignore', '.svn', '.hgignore', '.hg', 'CVS')
            configs = os.path.join(tmp_dir, 'configs')
            my_copytree(git_root, configs, ignores)
            if [x for x in os.listdir(os.getcwd()) if x not in ignores]:
                execute_command('git rm -rf ./*')
            with open(PLACEHOLDER_FILE, 'w') as f:
                f.write("""\
This branch ('bloom') has been deprecated in favor of storing settings and overlay files in the master branch.

Please goto the master branch for anything which referenced the bloom branch.

You can delete this branch at your convenience.
""")
            execute_command('git add ' + PLACEHOLDER_FILE)
            if has_changes():
                execute_command('git commit -m "DEPRECATING BRANCH"')
        if not branch_exists(BLOOM_CONFIG_BRANCH):
            info("Creating '{0}' branch.".format(BLOOM_CONFIG_BRANCH))
            create_branch(BLOOM_CONFIG_BRANCH, orphaned=True)
        with inbranch(BLOOM_CONFIG_BRANCH):
            my_copytree(configs, git_root)
            execute_command('git add ./*')
            if has_changes():
                execute_command('git commit -m '
                                '"Moving configs from bloom branch"')
    finally:
        # Clean up
        if os.path.exists(tmp_dir):
            shutil.rmtree(tmp_dir)
Пример #4
0
def non_git_rebase(upstream_branch, directory=None):
    # Create a temporary storage directory
    tmp_dir = mkdtemp()
    # Get the root of the git repository
    git_root = get_root(directory)
    try:
        # Copy the new upstream source into the temporary directory
        with inbranch(upstream_branch):
            ignores = ('.git', '.gitignore', '.svn', '.hgignore', '.hg', 'CVS')
            parent_source = os.path.join(tmp_dir, 'parent_source')
            my_copytree(git_root, parent_source, ignores)
        # Clear out any untracked files
        execute_command('git clean -fdx', cwd=directory)  # for good measure?
        # Collect files (excluding .git)
        items = []
        for item in os.listdir(git_root):
            if item in ['.git', '..', '.']:
                continue
            items.append(item)
        # Remove all files
        if len(items) > 0:
            execute_command('git rm -rf ' + ' '.join(items), cwd=directory)

        # Copy the parent source into the newly cleaned directory
        my_copytree(parent_source, git_root)

        # Commit changes to the repository
        execute_command('git add ./*', cwd=directory)
        # Collect .* files
        dot_items = []
        for item in os.listdir(git_root):
            if item in ['.git', '..', '.']:
                continue
            if item.startswith('.'):
                dot_items.append(item)
        # Add any .* files missed by 'git add ./*'
        if len(dot_items) > 0:
            execute_command('git add ' + ' '.join(dot_items), cwd=directory)
        # Remove any straggling untracked files
        execute_command('git clean -dXf', cwd=directory)
        # Only if we have local changes commit
        # (not true if the upstream didn't change any files)
        cmd = 'git commit '
        if not has_changes(directory):
            cmd += '--allow-empty '
        cmd += '-m "Rebase from \'' + upstream_branch + "'"
        if not has_changes(directory):
            cmd += " (no changes)"
        cmd += '"'
        execute_command(cmd, cwd=directory)
    finally:
        # Clean up
        if os.path.exists(tmp_dir):
            shutil.rmtree(tmp_dir)
Пример #5
0
def upconvert_bloom_to_config_branch():
    global _has_checked_bloom_branch
    if _has_checked_bloom_branch:
        return
    # Assert that this repository does not have multiple remotes
    check_for_multiple_remotes()
    if get_root() is None:
        # Not a git repository
        return
    track_branches(['bloom', BLOOM_CONFIG_BRANCH])
    if show('bloom', PLACEHOLDER_FILE) is not None:
        return
    if show('bloom', 'bloom.conf') is not None:
        # Wait for the bloom.conf upconvert...
        return
    if not branch_exists('bloom'):
        return
    _has_checked_bloom_branch = True
    info("Moving configurations from deprecated 'bloom' branch "
         "to the '{0}' branch.".format(BLOOM_CONFIG_BRANCH))
    tmp_dir = mkdtemp()
    git_root = get_root()
    try:
        # Copy the new upstream source into the temporary directory
        with inbranch('bloom'):
            ignores = ('.git', '.gitignore', '.svn', '.hgignore', '.hg', 'CVS')
            configs = os.path.join(tmp_dir, 'configs')
            my_copytree(git_root, configs, ignores)
            if [x for x in os.listdir(os.getcwd()) if x not in ignores]:
                execute_command('git rm -rf ./*')
            with open(PLACEHOLDER_FILE, 'w') as f:
                f.write("""\
This branch ('bloom') has been deprecated in favor of storing settings and overlay files in the master branch.

Please goto the master branch for anything which referenced the bloom branch.

You can delete this branch at your convenience.
""")
            execute_command('git add ' + PLACEHOLDER_FILE)
            if has_changes():
                execute_command('git commit -m "DEPRECATING BRANCH"')
        if not branch_exists(BLOOM_CONFIG_BRANCH):
            info("Creating '{0}' branch.".format(BLOOM_CONFIG_BRANCH))
            create_branch(BLOOM_CONFIG_BRANCH, orphaned=True)
        with inbranch(BLOOM_CONFIG_BRANCH):
            my_copytree(configs, git_root)
            execute_command('git add ./*')
            if has_changes():
                execute_command('git commit -m '
                                '"Moving configs from bloom branch"')
    finally:
        # Clean up
        if os.path.exists(tmp_dir):
            shutil.rmtree(tmp_dir)
Пример #6
0
def commit_summary():
    global _summary_file
    if get_root() is None:
        return
    if _summary_file is None:
        return
    if not os.path.exists(_summary_file.name):
        return
    try:
        with inbranch('master'):
            readme_name = 'README.md'
            readme = ''
            if os.path.isfile(readme_name):
                with open(readme_name, 'r') as f:
                    readme = f.read()
            _summary_file.close()
            with open(_summary_file.name, 'r') as f:
                readme = f.read() + "\n\n" + readme
            with open(readme_name, 'w') as f:
                f.write(readme)
            execute_command('git add ' + readme_name)
            if has_changes():
                execute_command('git commit -m "Updating README.md"')
    finally:
        if _summary_file is not None:
            _summary_file.close()
            if os.path.exists(_summary_file.name):
                os.remove(_summary_file.name)
Пример #7
0
 def fn(config):
     global _patch_config_keys
     conf_path = 'patches.conf'
     if directory is not None:
         conf_path = os.path.join(directory, conf_path)
     config_keys = list(config.keys())
     config_keys.sort()
     if _patch_config_keys != config_keys:
         raise RuntimeError("Invalid config passed to set_patch_config")
     cmd = 'git config -f {0} patches.'.format(conf_path)
     try:
         for key in config:
             _cmd = cmd + key + ' "' + config[key] + '"'
             execute_command(_cmd, cwd=directory)
         # Stage the patches.conf file
         cmd = 'git add ' + conf_path
         execute_command(cmd, cwd=directory)
         if has_changes(directory):
             # Commit the changed config file
             cmd = 'git commit -m "Updated patches.conf"'
             execute_command(cmd, cwd=directory)
     except subprocess.CalledProcessError as err:
         print_exc(traceback.format_exc())
         error("Failed to set patches info: " + str(err))
         raise
Пример #8
0
 def fn(config):
     global _patch_config_keys
     conf_path = 'patches.conf'
     if directory is not None:
         conf_path = os.path.join(directory, conf_path)
     config_keys = config.keys()
     config_keys.sort()
     if _patch_config_keys != config_keys:
         raise RuntimeError("Invalid config passed to set_patch_config")
     cmd = 'git config -f {0} patches.'.format(conf_path)
     try:
         for key in config:
             _cmd = cmd + key + ' "' + config[key] + '"'
             execute_command(_cmd, cwd=directory)
         # Stage the patches.conf file
         cmd = 'git add ' + conf_path
         execute_command(cmd, cwd=directory)
         if has_changes(directory):
             # Commit the changed config file
             cmd = 'git commit -m "Updated patches.conf"'
             execute_command(cmd, cwd=directory)
     except subprocess.CalledProcessError as err:
         print_exc(traceback.format_exc())
         error("Failed to set patches info: " + str(err))
         raise
Пример #9
0
 def store_original_config(self, config, patches_branch):
     with inbranch(patches_branch):
         with open('rpm.store', 'w+') as f:
             f.write(json.dumps(config))
         execute_command('git add rpm.store')
         if has_changes():
             execute_command('git commit -m "Store original patch config"')
Пример #10
0
 def store_original_config(self, config, patches_branch):
     with inbranch(patches_branch):
         with open('debian.store', 'w+') as f:
             f.write(json.dumps(config))
         execute_command('git add debian.store')
         if has_changes():
             execute_command('git commit -m "Store original patch config"')
Пример #11
0
def set_upstream(upstream_repo, upstream_repo_type, upstream_repo_branch):
    # Check for a bloom branch
    if branch_exists('bloom', False):
        # Found a bloom branch
        debug("Found a bloom branch, checking out.")
        # Check out the bloom branch
        checkout('bloom')
    else:
        # No bloom branch found, create one
        create_branch('bloom', changeto=True)

    # Now set the upstream using the bloom config
    cmd = 'git config -f bloom.conf bloom.upstream "{0}"'.format(upstream_repo)
    execute_command(cmd)
    cmd = 'git config -f bloom.conf ' \
        + 'bloom.upstreamtype "{0}"'.format(upstream_repo_type)
    execute_command(cmd)
    cmd = 'git config -f bloom.conf ' \
        + 'bloom.upstreambranch "{0}"'.format(upstream_repo_branch)
    execute_command(cmd)

    execute_command('git add bloom.conf')
    if has_changes():
        cmd = 'git commit -m "bloom branch update by git-bloom-config"'
        execute_command(cmd)
    else:
        debug("No chages, nothing to commit.")
Пример #12
0
 def set_releaser_history(self, history):
     # Assumes that this is called in the target branch
     patches_branch = 'patches/' + get_current_branch()
     debug("Writing release history to '{0}' branch".format(patches_branch))
     with inbranch(patches_branch):
         with open('releaser_history.json', 'w') as f:
             f.write(json.dumps(history))
         execute_command('git add releaser_history.json')
         if has_changes():
             execute_command('git commit -m "Store releaser history"')
Пример #13
0
 def set_releaser_history(self, history):
     # Assumes that this is called in the target branch
     patches_branch = 'patches/' + get_current_branch()
     debug("Writing release history to '{0}' branch".format(patches_branch))
     with inbranch(patches_branch):
         with open('releaser_history.json', 'w') as f:
             f.write(json.dumps(history))
         execute_command('git add releaser_history.json')
         if has_changes():
             execute_command('git commit -m "Store releaser history"')
Пример #14
0
def export_patches(directory=None):
    ### Ensure a clean/valid working environment
    ensure_clean_working_env(git_status=True, directory=directory)
    # Get current branch
    current_branch = get_current_branch(directory)
    if current_branch is None:
        error("Could not determine current branch.", exit=True)
    # Construct the patches branch name
    patches_branch = 'patches/' + current_branch
    # Ensure the patches branch exists
    if not branch_exists(patches_branch, False, directory=directory):
        error("The patches branch ({0}) does not ".format(patches_branch) +
              "exist, did you use git-bloom-branch?",
              exit=True)
    try:
        # Get parent branch and base commit from patches branch
        config = get_patch_config(patches_branch, directory)
        if config is None:
            error("Failed to get patches information.", exit=True)
        # Checkout to the patches branch
        checkout(patches_branch, directory=directory)
        # Notify the user
        debug("Exporting patches from "
              "{0}...{1}".format(config['base'], current_branch))
        # Remove all the old patches
        if len(list_patches(directory)) > 0:
            cmd = 'git rm ./*.patch'
            execute_command(cmd, cwd=directory)
        # Create the patches using git format-patch
        cmd = "git format-patch -M -B " \
              "{0}...{1}".format(config['base'], current_branch)
        execute_command(cmd, cwd=directory)
        # Report of the number of patches created
        patches_list = list_patches(directory)
        debug("Created {0} patches".format(len(patches_list)))
        # Clean up and commit
        if len(patches_list) > 0:
            cmd = 'git add ./*.patch'
            execute_command(cmd, cwd=directory)
        if has_changes(directory):
            cmd = 'git commit -m "Updating patches."'
            execute_command(cmd, cwd=directory)
    finally:
        if current_branch:
            checkout(current_branch, directory=directory)
Пример #15
0
def export_patches(directory=None):
    ### Ensure a clean/valid working environment
    ensure_clean_working_env(git_status=True, directory=directory)
    # Get current branch
    current_branch = get_current_branch(directory)
    if current_branch is None:
        error("Could not determine current branch.", exit=True)
    # Construct the patches branch name
    patches_branch = 'patches/' + current_branch
    # Ensure the patches branch exists
    if not branch_exists(patches_branch, False, directory=directory):
        error("The patches branch ({0}) does not ".format(patches_branch) +
              "exist, did you use git-bloom-branch?", exit=True)
    try:
        # Get parent branch and base commit from patches branch
        config = get_patch_config(patches_branch, directory)
        if config is None:
            error("Failed to get patches information.", exit=True)
        # Checkout to the patches branch
        checkout(patches_branch, directory=directory)
        # Notify the user
        debug("Exporting patches from "
              "{0}...{1}".format(config['base'], current_branch))
        # Remove all the old patches
        if len(list_patches(directory)) > 0:
            cmd = 'git rm ./*.patch'
            execute_command(cmd, cwd=directory)
        # Create the patches using git format-patch
        cmd = "git format-patch -M -B " \
              "{0}...{1}".format(config['base'], current_branch)
        execute_command(cmd, cwd=directory)
        # Report of the number of patches created
        patches_list = list_patches(directory)
        debug("Created {0} patches".format(len(patches_list)))
        # Clean up and commit
        if len(patches_list) > 0:
            cmd = 'git add ./*.patch'
            execute_command(cmd, cwd=directory)
        if has_changes(directory):
            cmd = 'git commit -m "Updating patches."'
            execute_command(cmd, cwd=directory)
    finally:
        if current_branch:
            checkout(current_branch, directory=directory)
Пример #16
0
def import_tarball(tarball_path, target_branch, version, name):
    if tarball_path.endswith('.zip'):
        error("Zip archives are not yet supported.", exit=True)
    # Create the tarfile handle
    targz = tarfile.open(tarball_path, 'r:gz')
    with inbranch(target_branch):
        # Prepare list of members to extract, ignoring some
        ignores = ('.git', '.gitignore', '.svn', '.hgignore', '.hg', 'CVS')
        members = targz.getmembers()
        members = [m for m in members if m.name.split('/')[-1] not in ignores]

        # Clear out the local branch
        items = []
        for item in os.listdir(os.getcwd()):
            if item in ['.git', '..', '.']:
                continue
            items.append(item)
        if len(items) > 0:
            execute_command('git rm -rf ' + ' '.join(items))
        # Clear out any untracked files
        execute_command('git clean -fdx')

        # Extract the tarball into the clean branch
        targz.extractall(os.getcwd(), members)

        # Check for folder nesting (mostly hg)
        items = []
        for item in os.listdir(os.getcwd()):
            if not item.startswith('.'):
                items.append(item)
        tarball_prefix = os.path.basename(tarball_path)[:-len('.tag.gz')]
        if tarball_prefix in items:
            debug('Removing nested tarball folder: ' + str(tarball_prefix))
            tarball_prefix_path = os.path.join(os.getcwd(), tarball_prefix)
            for item in os.listdir(tarball_prefix_path):
                if item in ['.', '..']:
                    continue
                item_path = os.path.join(os.getcwd(), tarball_prefix, item)
                debug(
                    'moving ' + str(item_path) + ' to ' +
                    str(os.path.join(os.getcwd(), item))
                )
                shutil.move(item_path, os.path.join(os.getcwd(), item))
            shutil.rmtree(tarball_prefix_path)
        else:
            debug('No nested tarball folder found.')

        # Commit changes to the repository
        items = []
        for item in os.listdir(os.getcwd()):
            if item in ['.git', '..', '.']:
                continue
            items.append(item)
        if len(items) > 0:
            execute_command('git add ' + ' '.join(items))
        # Remove any straggling untracked files
        execute_command('git clean -dXf')
        # Only if we have local changes commit
        # (not true if the upstream didn't change any files)
        if has_changes():
            msg = "Imported upstream version '{0}' of '{1}'"
            msg = msg.format(version, name or 'upstream')
            cmd = 'git commit -m "{0}"'.format(msg)
            execute_command(cmd)
Пример #17
0
execute_command('python setup.py build_sphinx')
execute_command('sphinxtogithub doc/build/html --verbose')
orig_cwd = os.getcwd()

clone = GitClone()
with clone as clone_dir:
    execute_command('git clean -fdx')
    with inbranch('gh-pages'):
        doc_dir = os.path.join('doc', ver)
        if os.path.exists(doc_dir):
            warning("Documentation for version '" + ver + "' already exists.")
            if not maybe_continue('y'):
                sys.exit(-1)
            execute_command('git rm -rf ' + doc_dir)
        shutil.copytree(os.path.join(orig_cwd, 'doc', 'build', 'html'),
                        doc_dir)
        p = re.compile('\d*[.]\d*[.]\d*')
        with open('doc/index.html', 'r') as f:
            redirect = f.read()
        redirect = p.sub(ver, redirect)
        with open('doc/index.html', 'w+') as f:
            f.write(redirect)
        execute_command('git add -f ' + os.path.join('doc', ver, '*'))
        execute_command('git add -f doc/index.html')
        if has_changes():
            execute_command('git commit -m "Uploading documentation for '
                            'version {0}"'.format(ver))
        execute_command('git clean -fdx')
clone.commit()
clone.clean_up()
Пример #18
0
def non_git_rebase(upstream_branch, directory=None):
    # Create a temporary storage directory
    tmp_dir = mkdtemp()
    # Get the root of the git repository
    git_root = get_root(directory)
    try:
        # Copy the new upstream source into the temporary directory
        with inbranch(upstream_branch):
            ignores = ('.git', '.gitignore', '.svn', '.hgignore', '.hg', 'CVS')
            parent_source = os.path.join(tmp_dir, 'parent_source')
            try:
                # Try catch this to handle dangling symbolic links
                # See: http://bugs.python.org/issue6547
                shutil.copytree(git_root, parent_source,
                                ignore=shutil.ignore_patterns(*ignores))
            except shutil.Error as e:
                for src, dst, error in e.args[0]:
                    if not os.path.islink(src):
                        raise
                    else:
                        linkto = os.readlink(src)
                        if os.path.exists(linkto):
                            raise
                    # dangling symlink found.. ignoring..

        # Clear out the local branch
        execute_command('git rm -rf *', cwd=directory)
        # Collect .* files (excluding .git)
        dot_items = []
        for item in os.listdir(git_root):
            if item in ['.git', '..', '.']:
                continue
            if item.startswith('.'):
                dot_items.append(item)
        # Remove and .* files missed by 'git rm -rf *'
        if len(dot_items) > 0:
            execute_command('git rm -rf ' + ' '.join(dot_items), cwd=directory)
        # Clear out any untracked files
        execute_command('git clean -fdx', cwd=directory)  # for good measure?

        # Copy the parent source into the newly cleaned directory
        for item in os.listdir(parent_source):
            src = os.path.join(parent_source, item)
            dst = os.path.join(git_root, item)
            if os.path.isdir(src):
                shutil.copytree(src, dst)
            else:
                shutil.copy(src, dst)

        # Commit changes to the repository
        execute_command('git add ./*', cwd=directory)
        # Collect .* files
        dot_items = []
        for item in os.listdir(git_root):
            if item in ['.git', '..', '.']:
                continue
            if item.startswith('.'):
                dot_items.append(item)
        # Add any .* files missed by 'git add ./*'
        if len(dot_items) > 0:
            execute_command('git add ' + ' '.join(dot_items), cwd=directory)
        # Remove any straggling untracked files
        execute_command('git clean -dXf', cwd=directory)
        # Only if we have local changes commit
        # (not true if the upstream didn't change any files)
        if has_changes(directory):
            cmd = 'git commit -m "Rebase from \'' + upstream_branch + "'"
            data = get_package_data(upstream_branch, quiet=True)
            if type(data) in [list, tuple]:
                cmd += " @ version '{0}'".format(data[1])
            cmd += '"'
            execute_command(cmd, cwd=directory)
    finally:
        # Clean up
        if os.path.exists(tmp_dir):
            shutil.rmtree(tmp_dir)