#!/usr/bin/python # # Try to identify added, removed and moved files after applying a # regular patch to an Arch project tree. # # We take the list of added and removed files from tree-lint and then # try to identify which removed files that are mostly identical to some # added file. # # Copyright 2003 Jan Harkes # Modified 2003-2005 Walter Landry to work with ArX # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA import sys import os import re import difflib import arx apply = sys.argv[1:] and sys.argv[1] == '-f' if len(sys.argv) > 2: os.chdir(sys.argv[2]) TREELINT = os.popen("arx tree-lint 2>&1").readlines() PRISTINE = arx.find_or_make_pristine(arx.path("."), arx.path(",,temp"), arx.Parsed_Name(os.popen("arx tree-cache").readline()[:-1])) ADD_TAG = "arx add -R %s" def do(cmd): if apply: os.system(cmd) adds = [] dels = [] adding=0 deleting=0 for line in TREELINT: if line[:-1]=='WARNING: Unrecognized paths' : adding=1 deleting=0 if line[:-1]=='ERROR: Missing files' : adding=0 deleting=1 if line[:1] == '\t': line = line[1:-1] if adding : adds.append(line) elif deleting : dels.append(line) else : print "Problem parsing tree-lint output", line moved = [] for deleted in dels: file = os.path.join(PRISTINE.native_file_string(), deleted) if os.path.isdir(file): continue d = open(file).readlines() print "checking", deleted matches = [] for added in adds: if os.path.isdir(added): continue a = open(added).readlines() match = difflib.SequenceMatcher(difflib.IS_LINE_JUNK, d, a).quick_ratio() if match <= 0.60: continue print "\tfound possible match %s ~%.2f%% identical" % (added, match*100) matches.append((1 - match, added)) if not matches: continue matches.sort() match = matches[0][1] print "*** moving %s to %s" % (deleted, match) if apply: arx.atomic_move(arx.path(deleted),arx.path(match),1) moved.append(deleted) adds.remove(match) print "\nremoving tags for deleted files" for deleted in dels: if not deleted in moved: print "\t%s" % deleted if apply : arx.delete_element(arx.path(deleted),0,0,0,1) print "\ntagging new files" for added in adds: print "\t%s" % added if apply : do(ADD_TAG % added)