def remove_patch(patch, force, check, silent): try: status = True if not force and (check or files_may_have_changed(patch)): status = check_for_pending_changes(patch) if status is True: patchdir = os.path.join(patchfns.QUILT_PC, patch) try: os.remove(os.path.join(patchdir, '.timestamp')) except OSError: pass if not os.path.exists(patchdir) or not os.listdir(patchdir): output.write('Patch %s appears to be empty, removing\n' % patchfns.print_patch(patch)) try: os.rmdir(patchdir) except OSError as edata: if edata.errno != errno.ENOENT: output.error('%s: %s\n' % (patchdir, edata.errstring)) status = False else: output.write('Removing patch %s\n' % patchfns.print_patch(patch)) if not backup.restore(patchdir, touch=True, verbose=not silent): status = False patchfns.remove_from_db(patch) try: os.remove(os.path.join(patchdir + '~refresh')) except OSError as edata: if edata.errno != errno.ENOENT: output.error('%s: %s\n' % (patchdir, edata.errstring)) status = False return status except KeyboardInterrupt: return False
def run_remove(args): patchfns.chdir_to_base_dir() patch = patchfns.find_applied_patch(args.opt_patch) if not patch: return cmd_result.ERROR prpatch = patchfns.print_patch(patch) patchfn = patchfns.patch_file_name(patch) patchrefrfile = os.path.join(patchfns.QUILT_PC, patch + '~refresh') patchrefrdir = os.path.dirname(patchrefrfile) budir = patchfns.backup_dir_name(patch) is_ok = True for filename in args.file_list: if patchfns.SUBDIR: filename = os.path.join(patchfns.SUBDIR, filename) if not patchfns.file_in_patch(filename, patch): output.error('File %s is not in patch %s\n' % (filename, prpatch)) is_ok = False continue next_patch = patchfns.next_patch_for_file(patch, filename) if next_patch: output.error('File %s modified by patch %s\n' % (filename, patchfns.print_patch(next_patch))) is_ok = False continue # Restore file from backup if not backup.restore(budir, filelist=[filename], touch=True): output.error('Failed to remove file %s from patch %s\n' % (filename, prpatch)) is_ok = False continue if os.path.exists(patchrefrdir) and os.path.exists(patchfn): fsutils.touch(patchrefrfile) output.write('File %s removed from patch %s\n' % (filename, prpatch)) return cmd_result.OK if is_ok else cmd_result.ERROR
def apply_patch_temporarily(workdir, patch, files=None): patch_file = patch_file_name(patch) args = patch_args(patch) srcdir = os.path.join(QUILT_PC, patch) if not backup.restore(srcdir, to_dir=workdir, filelist=files, keep=True): output.error('Failed to copy files to temporary directory\n') return False if os.path.isfile(patch_file) and os.path.getsize(patch_file) > 0: text = fsutils.get_file_contents(patch_file) result = putils.apply_patch(indir=workdir, patch_args=' '.join(args) + ' --no-backup-if-mismatch -Ef', patch_file=patch_file) if result.eflags != 0: # Generating a relative diff for a subset of files in # the patch will fail. Also, if a patch was force # applied, we know that it won't apply cleanly. In # all other cases, print a warning. if not os.path.isfile(os.path.join(QUILT_PC, patch + '~refresh')) and len(files) == 0: output.error('Failed to patch temporary files\n') return False return True
def check_for_pending_changes(patch): patch_file = patchfns.patch_file_name(patch) workdir = patchfns.gen_tempfile(template='quilt', asdir=True) patchdir = os.path.join(patchfns.QUILT_PC, patch) if os.path.isdir(patchdir): prefix = os.path.abspath(patchdir) if not backup.restore(prefix, to_dir=workdir, keep=True): output.error('Failed to copy files to temporary directory\n') shutil.rmtree(workdir) return False if os.path.exists(patch_file) and os.path.getsize(patch_file) > 0: patch_args = '%s --no-backup-if-mismatch -E' % ' '.join(patchfns.patch_args(patch)) result = putils.apply_patch(patch_file, indir=workdir, patch_args=patch_args) if result.eflags != 0 and not os.path.exists(patchdir): output.write(result.stdout) output.error('Failed to patch temporary files\n') shutil.rmtree(workdir) return False failed = False for file_nm in patchfns.files_in_patch(patch): wfile_nm = os.path.join(workdir, file_nm) if not os.path.exists(file_nm): if os.path.exists(wfile_nm): failed = True break else: continue elif not os.path.exists(wfile_nm): failed = True break if not diff.same_contents(file_nm, wfile_nm): failed = True break shutil.rmtree(workdir) if failed: output.error('Patch %s does not remove cleanly (refresh it or enforce with -f)\n' % patchfns.print_patch(patch)) return cmd_result.ERROR_SUGGEST_FORCE return True
def rollback_patch(patch, verbose=False): backup_dir = os.path.join(patchfns.QUILT_PC, patch) return backup.restore(backup_dir, verbose=verbose)