import patchstate as ps import io, os, sys def lcs(a, b, *, key): a = [*a] b = [*b] if not a or not b: return [] kas = [*map(key, a)] m = [(0,)] for v in a: m.append((m[-1][0] + 1, v, None, m[-1])) for v in b: kb = key(v) mi = iter(m) mv = next(mi) m2 = [(mv[0] + 1, None, v, mv)] for ia,mv in enumerate(mi): if kas[ia] == kb: mv = m[ia] m2.append((mv[0], a[ia], v, mv)) continue mv1 = m2[-1] if mv[0] <= mv1[0]: m2.append((mv[0] + 1, None, v, mv)) else: m2.append((mv1[0] + 1, a[ia], None, mv1)) del mv1 del ia del mi, mv m = m2 m = m[-1] del v, a, b, kas m2 = [] while len(m) == 4: _,a,b,m = m m2.append((a,b)) assert m == (0,) m2.reverse() return m2 def main(args): args = iter(args) arg0 = next(args) @ps.argparse_all(args) def path(arg): raise RuntimeError(f'Invalid argument: {arg!r}') [repo_path, import_path] = path repo = ps.Repository(repo_path) pnew = repo.import_dir(import_path) with io.open(os.path.join(repo.path, 'series'), 'r') as f: pcur = ps.Series.parse(f.read()) r = [] for p1,p2 in lcs(pcur.info, pnew.info, key=lambda p: p.patch_id): if p1 is None: r.append(p2) continue if p2 is None: r.append(p1.update(new_mode='gone')) continue r.append(p2.update(mode=p1.mode, info=p1.info)) pnew.info = r pnew_data = pnew.fmt() with io.open(os.path.join(repo.path, 'series'), 'w') as f: f.write(pnew_data) repo.gc({p.patch_hash for p in pnew.info}) return 0 if __name__ == '__main__': sys.exit(main(sys.argv))