def cloned_dist_git(self, url, commit, workdir): repo = git.Repo.clone_from(url, workdir) repo.git.checkout(commit) # Configure user otherwise app.apply_changes() will fail repo.git.config('user.name', GitHelper.get_user(), local=True) repo.git.config('user.email', GitHelper.get_email(), local=True) return repo
def init_git(cls, directory): """Function initialize old and new Git repository""" repo = git.Repo.init(directory) repo.git.config('user.name', GitHelper.get_user(), local=True) repo.git.config('user.email', GitHelper.get_email(), local=True) repo.git.add(all=True) repo.index.commit('Initial commit', skip_hooks=True) return repo
def _prepare_git(cls, upstream_name): cls.git_helper.command_remote_add(upstream_name, cls.new_sources) cls.git_helper.command_fetch(upstream_name) cls.output_data = cls.git_helper.command_log(parameters='--pretty=oneline') logger.debug('Outputdata from git log %s', cls.output_data) number = 0 if cls.prep_section: number = 1 last_hash = GitHelper.get_commit_hash_log(cls.output_data, number=number) init_hash = GitHelper.get_commit_hash_log(cls.output_data, len(cls.output_data)-1) return init_hash, last_hash
def _prepare_git(cls, upstream_name): cls.git_helper.command_remote_add(upstream_name, cls.new_sources) cls.git_helper.command_fetch(upstream_name) cls.output_data = cls.git_helper.command_log( parameters='--pretty=oneline') logger.debug('Outputdata from git log %s', cls.output_data) number = 0 if cls.prep_section: number = 1 last_hash = GitHelper.get_commit_hash_log(cls.output_data, number=number) init_hash = GitHelper.get_commit_hash_log(cls.output_data, len(cls.output_data) - 1) return init_hash, last_hash
def _prepare_rebased_repository(cls, patches, rebased_sources_dir): """ Initialize git repository in the rebased directory :return: git.Repo instance of rebased_sources """ for patch in patches['applied'] + patches['not_applied']: shutil.copy(patch.path, rebased_sources_dir) repo = git.Repo.init(rebased_sources_dir) repo.git.config('user.name', GitHelper.get_user(), local=True) repo.git.config('user.email', GitHelper.get_email(), local=True) repo.git.add(all=True) repo.index.commit('Initial commit', skip_hooks=True) return repo
def test_get_user_and_email(self, config, workdir): name = 'Foo Bar' email = '*****@*****.**' env_git_config = os.environ.get('GIT_CONFIG') env_xdg_config_home = os.environ.get('XDG_CONFIG_HOME') try: if config == 'global': work_git_path = os.path.join(workdir, 'git') os.makedirs(work_git_path) config_file = os.path.join(work_git_path, 'config') self.write_config_file(config_file, name, email) os.environ['XDG_CONFIG_HOME'] = workdir elif config == 'global_include': work_git_path = os.path.join(workdir, 'git') os.makedirs(work_git_path) config_file = os.path.join(work_git_path, 'config') with open(config_file, 'w') as f: f.write('[include]\n' ' path = included_config\n') included_config_file = os.path.join(work_git_path, 'included_config') self.write_config_file(included_config_file, name, email) os.environ['XDG_CONFIG_HOME'] = workdir elif config == 'local': repo = git.Repo.init(workdir) repo.git.config('user.name', name, local=True) repo.git.config('user.email', email, local=True) elif config == 'env': config_file = os.path.join(workdir, 'git_config') os.environ['GIT_CONFIG'] = config_file self.write_config_file(config_file, name, email) else: raise RuntimeError() assert name == GitHelper.get_user() assert email == GitHelper.get_email() finally: if env_git_config: os.environ['GIT_CONFIG'] = env_git_config elif 'GIT_CONFIG' in os.environ: del os.environ['GIT_CONFIG'] if env_xdg_config_home: os.environ['XDG_CONFIG_HOME'] = env_xdg_config_home elif 'XDG_CONFIG_HOME' in os.environ: del os.environ['XDG_CONFIG_HOME']
def patch_sources(self, sources): # Patch sources git_helper = GitHelper(sources[0]) if not self.conf.non_interactive: git_helper.check_git_config() patch = Patcher(GitHelper.GIT) self.rebase_spec_file.update_changelog( self.rebase_spec_file.get_new_log(git_helper)) try: self.rebased_patches = patch.patch( sources[0], sources[1], self.old_rest_sources, git_helper, self.spec_file.get_applied_patches(), self.spec_file.get_prep_section(), **self.kwargs) except RuntimeError: raise RebaseHelperError('Patching failed') self.rebase_spec_file.write_updated_patches(self.rebased_patches) results_store.set_patches_results(self.rebased_patches)
def setup(self): super(TestGitHelper, self).setup() self.GIT_OLD_DIR = os.path.join(self.WORKING_DIR, settings.OLD_SOURCES_DIR) self.GIT_NEW_DIR = os.path.join(self.WORKING_DIR, settings.NEW_SOURCES_DIR) self.old_git_path = os.path.join(self.GIT_OLD_DIR, 'project-1.0.0') self._extract_sources(self.OLD_SOURCES, self.GIT_OLD_DIR) self._extract_sources(self.NEW_SOURCES, self.GIT_NEW_DIR) self.git_helper = GitHelper(self.old_git_path) self._init_git_repo(self.old_git_path)
def init_git(cls, directory): """ Function initialize old and new Git repository""" gh = GitHelper(directory) gh.command_init(directory) gh.command_add_files('.') gh.command_commit(message='Initial Commit')
def patch_sources(self, sources): # Patch sources git_helper = GitHelper(sources[0]) if not self.conf.non_interactive: git_helper.check_git_config() patch = Patcher(GitHelper.GIT) self.rebase_spec_file.update_changelog(self.rebase_spec_file.get_new_log(git_helper)) try: self.rebased_patches = patch.patch(sources[0], sources[1], self.old_rest_sources, git_helper, self.spec_file.get_applied_patches(), self.spec_file.get_prep_section(), **self.kwargs) except RuntimeError: raise RebaseHelperError('Patching failed') self.rebase_spec_file.write_updated_patches(self.rebased_patches) results_store.set_patches_results(self.rebased_patches)
def patch_sources(self, sources): # Patch sources git_helper = GitHelper(sources[0]) git_helper.check_git_config() patch = Patcher(self.conf.patchtool) self.rebase_spec_file.update_changelog(self.rebase_spec_file.get_new_log(git_helper)) try: self.rebased_patches = patch.patch(sources[0], sources[1], self.rest_sources, git_helper, self.spec_file.get_applied_patches(), self.spec_file.get_prep_section(), **self.kwargs) except RuntimeError as run_e: raise RebaseHelperError('Patching failed') self.rebase_spec_file.write_updated_patches(self.rebased_patches) if self.conf.non_interactive: OutputLogger.set_patch_output('Unapplied patches:', self.rebased_patches['unapplied']) OutputLogger.set_patch_output('Patches:', self.rebased_patches)
def _git_rebase(cls): """Function performs git rebase between old and new sources""" # in old_sources do. # 1) git remote add new_sources <path_to_new_sources> # 2) git fetch new_sources # 3 git rebase -i --onto new_sources/master <oldest_commit_old_source> <the_latest_commit_old_sourcese> if not cls.cont: logger.info('Git-rebase operation to %s is ongoing...', os.path.basename(cls.new_sources)) upstream = 'new_upstream' init_hash, last_hash = cls._prepare_git(upstream) ret_code = cls.git_helper.command_rebase(parameters='--onto', upstream_name=upstream, first_hash=init_hash, last_hash=last_hash) else: logger.info('Git-rebase operation continues...') ret_code = cls.git_helper.command_rebase(parameters='--skip') cls._get_git_helper_data() logger.debug(cls.output_data) patch_dictionary = {} modified_patches = [] deleted_patches = [] unapplied_patches = [] while True: log = cls.git_helper.command_log(parameters='--pretty=oneline') for patch_name in cls.git_helper.get_automerged_patches(cls.output_data): index = [i for i, l in enumerate(log) if l.endswith(patch_name)] if index: commit = GitHelper.get_commit_hash_log(log, number=index[0]) base_name = os.path.join(cls.kwargs['results_dir'], patch_name) cls.git_helper.command_diff('{}~1'.format(commit), commit, output_file=base_name) modified_patches.append(base_name) if int(ret_code) != 0: if not cls.non_interactive: patch_name = cls.git_helper.get_unapplied_patch(cls.output_data) logger.info("Git has problems with rebasing patch %s", patch_name) cls.git_helper.command_mergetool() else: # Take the patch which failed from .git/rebase-apply/next file try: with open(os.path.join(cls.old_sources, '.git', 'rebase-apply', 'next')) as f: number = '\n'.join(f.readlines()) except IOError: raise RuntimeError("Git rebase failed with unknown reason. Please check log file") # Getting the patch which failed unapplied_patches.append(cls.patches[int(number) - 1].get_patch_name()) ret_code = cls.git_helper.command_rebase('--skip') cls._get_git_helper_data() continue modified_files = cls.git_helper.command_diff_status() cls.git_helper.command_add_files(parameters=modified_files) base_name = os.path.join(cls.kwargs['results_dir'], patch_name) cls.git_helper.command_diff('HEAD', output_file=base_name) with open(base_name, "r") as f: del_patches = f.readlines() if not del_patches: deleted_patches.append(base_name) else: logger.info('Following files were modified: %s', ','.join(modified_files)) cls.git_helper.command_commit(message=patch_name) cls.git_helper.command_diff('HEAD~1', output_file=base_name) modified_patches.append(base_name) if not cls.non_interactive: if not ConsoleHelper.get_message('Do you want to continue with another patch'): raise KeyboardInterrupt ret_code = cls.git_helper.command_rebase('--skip') cls._get_git_helper_data() else: break deleted_patches = cls._update_deleted_patches(deleted_patches) if deleted_patches: patch_dictionary['deleted'] = deleted_patches if modified_patches: patch_dictionary['modified'] = modified_patches if unapplied_patches: patch_dictionary['unapplied'] = unapplied_patches #TODO correct settings for merge tool in ~/.gitconfig # currently now meld is not started return patch_dictionary
def _git_rebase(cls): """Function performs git rebase between old and new sources""" # in old_sources do: # 1) git remote add new_sources <path_to_new_sources> # 2) git fetch new_sources # 3) git rebase --onto new_sources/master <root_commit_old_sources> <last_commit_old_sources> if not cls.cont: logger.info('git-rebase operation to %s is ongoing...', os.path.basename(cls.new_sources)) upstream = 'new_upstream' cls.old_repo.create_remote(upstream, url=cls.new_sources).fetch() root_commit = cls.old_repo.git.rev_list('HEAD', max_parents=0) last_commit = cls.old_repo.commit('HEAD') try: cls.output_data = cls.old_repo.git.rebase( root_commit, last_commit, onto='{}/master'.format(upstream), stdout_as_string=six.PY3) except git.GitCommandError as e: ret_code = e.status cls.output_data = e.stdout else: ret_code = 0 else: logger.info('git-rebase operation continues...') try: cls.output_data = cls.old_repo.git.rebase( skip=True, stdout_as_string=six.PY3) except git.GitCommandError as e: ret_code = e.status cls.output_data = e.stdout else: ret_code = 0 logger.debug(cls.output_data) patch_dictionary = {} modified_patches = [] inapplicable_patches = [] while True: automerged_patches = cls._get_automerged_patches(cls.output_data) for patch_name in automerged_patches: commits = [ c for c in cls.old_repo.iter_commits() if c.summary.endswith(patch_name) ] if commits: base_name = os.path.join(cls.kwargs['rebased_sources_dir'], patch_name) diff = cls.old_repo.git.diff(commits[0].parents[0], commits[0], stdout_as_string=False) with open(base_name, 'wb') as f: f.write(diff) f.write(b'\n') modified_patches.append(patch_name) if ret_code != 0: # get name of the current patch using .git/rebase-apply/next try: with open( os.path.join(cls.old_sources, '.git', 'rebase-apply', 'next')) as f: patch_name = cls.patches[int(f.readline()) - 1].get_patch_name() except IOError: raise RuntimeError( 'Git rebase failed with unknown reason. Please check log file' ) if not cls.non_interactive: logger.info("Git has problems with rebasing patch %s", patch_name) GitHelper.run_mergetool(cls.old_repo) else: inapplicable_patches.append(patch_name) try: cls.output_data = cls.old_repo.git.rebase( skip=True, stdout_as_string=six.PY3) except git.GitCommandError as e: ret_code = e.status cls.output_data = e.stdout else: ret_code = 0 continue base_name = os.path.join(cls.kwargs['rebased_sources_dir'], patch_name) # unstaged changes diff = cls.old_repo.commit().diff(None) if diff: # staged changes diff = cls.old_repo.index.diff(cls.old_repo.commit()) modified_files = [d.a_path for d in diff] logger.info('Following files were modified: %s', ', '.join(modified_files)) try: commit = cls.old_repo.index.commit(patch_name, skip_hooks=True) except git.UnmergedEntriesError: inapplicable_patches.append(patch_name) else: diff = cls.old_repo.git.diff(commit.parents[0], commit, stdout_as_string=False) with open(base_name, 'wb') as f: f.write(diff) f.write(b'\n') modified_patches.append(patch_name) if not cls.non_interactive: if not ConsoleHelper.get_message( 'Do you want to continue with another patch'): raise KeyboardInterrupt try: cls.output_data = cls.old_repo.git.rebase( skip=True, stdout_as_string=six.PY3) except git.GitCommandError as e: ret_code = e.status cls.output_data = e.stdout else: ret_code = 0 else: break deleted_patches = cls._update_deleted_patches(inapplicable_patches) if deleted_patches: patch_dictionary['deleted'] = deleted_patches if modified_patches: patch_dictionary['modified'] = modified_patches if inapplicable_patches: patch_dictionary['inapplicable'] = inapplicable_patches patches = [os.path.basename(p.path) for p in cls.patches] untouched_patches = [ p for p in patches if p not in deleted_patches + modified_patches + inapplicable_patches ] if untouched_patches: patch_dictionary['untouched'] = untouched_patches # TODO correct settings for merge tool in ~/.gitconfig # currently now meld is not started return patch_dictionary
def init_git(cls, directory): """Function initialize old and new Git repository""" gh = GitHelper(directory) gh.command_init(directory) gh.command_add_files('.') gh.command_commit(message='Initial Commit')
def _git_rebase(cls): """Function performs git rebase between old and new sources""" # in old_sources do. # 1) git remote add new_sources <path_to_new_sources> # 2) git fetch new_sources # 3 git rebase -i --onto new_sources/master <oldest_commit_old_source> <the_latest_commit_old_sourcese> if not cls.cont: logger.info('Git-rebase operation to %s is ongoing...', os.path.basename(cls.new_sources)) upstream = 'new_upstream' init_hash, last_hash = cls._prepare_git(upstream) ret_code = cls.git_helper.command_rebase(parameters='--onto', upstream_name=upstream, first_hash=init_hash, last_hash=last_hash) else: logger.info('Git-rebase operation continues...') ret_code = cls.git_helper.command_rebase(parameters='--skip') cls._get_git_helper_data() logger.debug(cls.output_data) patch_dictionary = {} modified_patches = [] deleted_patches = [] unapplied_patches = [] while True: log = cls.git_helper.command_log(parameters='--pretty=oneline') for patch_name in cls.git_helper.get_automerged_patches( cls.output_data): index = [ i for i, l in enumerate(log) if l.endswith(patch_name) ] if index: commit = GitHelper.get_commit_hash_log(log, number=index[0]) base_name = os.path.join(cls.kwargs['results_dir'], patch_name) cls.git_helper.command_diff('{}~1'.format(commit), commit, output_file=base_name) modified_patches.append(base_name) if int(ret_code) != 0: if not cls.non_interactive: patch_name = cls.git_helper.get_unapplied_patch( cls.output_data) logger.info("Git has problems with rebasing patch %s", patch_name) cls.git_helper.command_mergetool() else: # Take the patch which failed from .git/rebase-apply/next file try: with open( os.path.join(cls.old_sources, '.git', 'rebase-apply', 'next')) as f: number = '\n'.join(f.readlines()) except IOError: raise RuntimeError( "Git rebase failed with unknown reason. Please check log file" ) # Getting the patch which failed unapplied_patches.append(cls.patches[int(number) - 1].get_patch_name()) ret_code = cls.git_helper.command_rebase('--skip') cls._get_git_helper_data() continue modified_files = cls.git_helper.command_diff_status() cls.git_helper.command_add_files(parameters=modified_files) base_name = os.path.join(cls.kwargs['results_dir'], patch_name) cls.git_helper.command_diff('HEAD', output_file=base_name) with open(base_name, "r") as f: del_patches = f.readlines() if not del_patches: deleted_patches.append(base_name) else: logger.info('Following files were modified: %s', ','.join(modified_files)) cls.git_helper.command_commit(message=patch_name) cls.git_helper.command_diff('HEAD~1', output_file=base_name) modified_patches.append(base_name) if not cls.non_interactive: if not ConsoleHelper.get_message( 'Do you want to continue with another patch'): raise KeyboardInterrupt ret_code = cls.git_helper.command_rebase('--skip') cls._get_git_helper_data() else: break deleted_patches = cls._update_deleted_patches(deleted_patches, unapplied_patches) if deleted_patches: patch_dictionary['deleted'] = deleted_patches if modified_patches: patch_dictionary['modified'] = modified_patches if unapplied_patches: patch_dictionary['unapplied'] = unapplied_patches #TODO correct settings for merge tool in ~/.gitconfig # currently now meld is not started return patch_dictionary