def recordfunc(ui, repo, message, match, opts): """This is generic record driver. It's job is to interactively filter local changes, and accordingly prepare working dir into a state, where the job can be delegated to non-interactive commit command such as 'commit' or 'qrefresh'. After the actual job is done by non-interactive command, working dir state is restored to original. In the end we'll record intresting changes, and everything else will be left in place, so the user can continue his work. """ if match.files(): changes = None else: changes = repo.status(match=match)[:3] modified, added, removed = changes match = cmdutil.matchfiles(repo, modified + added + removed) diffopts = mdiff.diffopts(git=True, nodates=True) chunks = patch.diff(repo, repo.dirstate.parents()[0], match=match, changes=changes, opts=diffopts) fp = cStringIO.StringIO() fp.write(''.join(chunks)) fp.seek(0) # 1. filter patch, so we have intending-to apply subset of it if changes is not None: chunks = filterpatch(opts, parsepatch(changes, fp), chunkselector) else: chgs = repo.status(match=match)[:3] chunks = filterpatch(opts, parsepatch(chgs, fp), chunkselector) del fp contenders = {} for h in chunks: try: contenders.update(dict.fromkeys(h.files())) except AttributeError: pass newfiles = [f for f in match.files() if f in contenders] if not newfiles: ui.status(_('no changes to record\n')) return 0 if changes is None: match = cmdutil.matchfiles(repo, newfiles) changes = repo.status(match=match) modified = dict.fromkeys(changes[0]) # 2. backup changed files, so we can restore them in the end backups = {} backupdir = repo.join('record-backups') try: os.mkdir(backupdir) except OSError, err: if err.errno != errno.EEXIST: raise
def recordfunc(ui, repo, message, match, opts): """This is generic record driver. Its job is to interactively filter local changes, and accordingly prepare working dir into a state, where the job can be delegated to non-interactive commit command such as 'commit' or 'qrefresh'. After the actual job is done by non-interactive command, working dir state is restored to original. In the end we'll record interesting changes, and everything else will be left in place, so the user can continue his work. """ merge = len(repo[None].parents()) > 1 if merge: raise util.Abort(_('cannot partially commit a merge ' '(use hg commit instead)')) changes = repo.status(match=match)[:3] diffopts = mdiff.diffopts(git=True, nodates=True) chunks = patch.diff(repo, changes=changes, opts=diffopts) fp = cStringIO.StringIO() fp.write(''.join(chunks)) fp.seek(0) # 1. filter patch, so we have intending-to apply subset of it chunks = crpatch.filterpatch(opts, crpatch.parsepatch(changes, fp), chunk_selector.chunkselector, ui) del fp contenders = set() for h in chunks: try: contenders.update(set(h.files())) except AttributeError: pass changed = changes[0] + changes[1] + changes[2] newfiles = [f for f in changed if f in contenders] if not newfiles: ui.status(_('no changes to record\n')) return 0 modified = set(changes[0]) # 2. backup changed files, so we can restore them in the end backups = {} backupdir = repo.join('record-backups') try: os.mkdir(backupdir) except OSError, err: if err.errno != errno.EEXIST: raise
def recordfunc(ui, repo, message, match, opts): """This is generic record driver. Its job is to interactively filter local changes, and accordingly prepare working dir into a state, where the job can be delegated to non-interactive commit command such as 'commit' or 'qrefresh'. After the actual job is done by non-interactive command, working dir state is restored to original. In the end we'll record interesting changes, and everything else will be left in place, so the user can continue his work. """ merge = len(repo[None].parents()) > 1 if merge: raise util.Abort( _('cannot partially commit a merge ' '(use hg commit instead)')) changes = repo.status(match=match)[:3] diffopts = mdiff.diffopts(git=True, nodates=True) chunks = patch.diff(repo, changes=changes, opts=diffopts) fp = cStringIO.StringIO() fp.write(''.join(chunks)) fp.seek(0) # 1. filter patch, so we have intending-to apply subset of it chunks = crpatch.filterpatch(opts, crpatch.parsepatch(changes, fp), chunk_selector.chunkselector, ui) del fp contenders = set() for h in chunks: try: contenders.update(set(h.files())) except AttributeError: pass changed = changes[0] + changes[1] + changes[2] newfiles = [f for f in changed if f in contenders] if not newfiles: ui.status(_('no changes to record\n')) return 0 modified = set(changes[0]) # 2. backup changed files, so we can restore them in the end backups = {} backupdir = repo.join('record-backups') try: os.mkdir(backupdir) except OSError, err: if err.errno != errno.EEXIST: raise
def recordfunc(ui, repo, message, match, opts): """This is generic record driver. Its job is to interactively filter local changes, and accordingly prepare working dir into a state, where the job can be delegated to non-interactive commit command such as 'commit' or 'qrefresh'. After the actual job is done by non-interactive command, working dir state is restored to original. In the end we'll record interesting changes, and everything else will be left in place, so the user can continue his work. """ git_args = ["git", "diff", "--binary"] git_base = [] if opts['cached']: git_args.append("--cached") if not opts['index']: git_base.append("HEAD") p = subprocess.Popen(git_args + git_base, stdout=subprocess.PIPE, close_fds=util.closefds) fp = p.stdout # 0. parse patch fromfiles = set() tofiles = set() chunks = crpatch.parsepatch(fp) for c in chunks: if isinstance(c, crpatch.uiheader): fromfile, tofile = c.files() if fromfile is not None: fromfiles.add(fromfile) if tofile is not None: tofiles.add(tofile) added = tofiles - fromfiles removed = fromfiles - tofiles modified = tofiles - added - removed changes = [modified, added, removed] # 1. filter patch, so we have intending-to apply subset of it chunks = crpatch.filterpatch(opts, chunks, chunk_selector.chunkselector, ui) p.wait() del fp contenders = set() for h in chunks: try: contenders.update(set(h.files())) except AttributeError: pass changed = changes[0] | changes[1] | changes[2] newfiles = [f for f in changed if f in contenders] if not newfiles: ui.status(_('no changes to record\n')) return 0 # 2. backup changed files, so we can restore them in the end backups = {} newly_added_backups = {} backupdir = os.path.join(repo.controldir(), 'record-backups') try: os.mkdir(backupdir) except OSError, err: if err.errno != errno.EEXIST: raise