diff --git a/README.md b/README.md index abd326d..952f42b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ p4RemoveUnversioned =================== -Removes unversioned files from perforce repository. Script is in beta, though it works. It's a little slow due to the way fstat is used, but that will be changed soon, so the speed up should be enormous once that's done, up to 100x or more. +Removes unversioned files from perforce repository. Script is in beta, works well, but still going through continued testing. There are a few stats at the end, will be putting in more, like number of files/directories checked, so you have an idea how much work was required. + +Concerning benchmarks: I used to have a HDD, now a SSD. So I can't provide valid comparisons to the old numbers until I do them on a computer with a HDD. That said, this single worker implementation runs faster than the old multi-threaded version. Can't wait to further update it, will only continue to get faster. + This script does parse __.p4ignore__ ignore files, compiles the fields as regex, and scans every directory and file against the local and parent __.p4ignore__ files. This is my first time doing something like this, and I just realized this isn't actually correct; I need to update how things are ignored to follow the [spec](http://www.perforce.com/perforce/r12.1/manuals/cmdref/env.P4IGNORE.html), since it's not straight up regex. diff --git a/p4RemoveUnversioned.py b/p4RemoveUnversioned.py index 28bae51..06c8d8f 100644 --- a/p4RemoveUnversioned.py +++ b/p4RemoveUnversioned.py @@ -237,8 +237,8 @@ class Console( threading.Thread ): self.buffer_write_times.clear( ) self.queue.task_done( ) - print(self.queue.qsize()) - print(self.queue.empty()) + #print(self.queue.qsize()) + #print(self.queue.empty()) break elif event == Console.MSG.WRITE: @@ -347,7 +347,7 @@ def main( args ): client_root = get_client_root() ldirectory = directory.lower() workspace_name = None - if not ldirectory.startswith(client_root.lower()): + if client_root is None or not ldirectory.startswith(client_root.lower()): print("\nCurrent directory not in client view, checking other workspaces for user '" + username + "' ...") workspace_name = parse_info_from_command('p4 info', 'Client name: ') @@ -386,6 +386,9 @@ def main( args ): # Key is the file root, the value is the table of file regexes for that directory. files_to_ignore = PDict() + processed_file_count = 0 + processed_directory_count = 0 + remove_file_count = 0 remove_dir_count = 0 warning_count = 0 @@ -414,18 +417,21 @@ def main( args ): ignore_list = get_ignore_list( root, files_to_ignore ) if not options.quiet: - c.write( "|Checking " + root ) + c.write( "|Checking " + os.path.relpath( root, directory ) ) for d in dirs: + processed_directory_count += 1 path = join( root, d ) + rel_path = os.path.relpath( path, directory ) if match_in_ignore_list( path, ignore_list ): # add option of using send2trash if not options.quiet: - c.write( "| ignoring " + d ) + c.write( "| ignoring " + rel_path ) dirs.remove( d ) for f in files: + processed_file_count += 1 path = normpath( join( root, f ) ) if path not in files_in_depot: @@ -451,18 +457,20 @@ def main( args ): ignore_list = get_ignore_list( root, files_to_ignore ) for d in dirs: + processed_directory_count += 1 path = os.path.join( root, d ) + rel_path = os.path.relpath( path, directory ) if match_in_ignore_list( path, ignore_list ): # add option of using send2trash if not options.quiet: - c.write( "| ignoring " + path ) + c.write( "| ignoring " + rel_path ) dirs.remove( d ) try: os.rmdir(path) remove_dir_count += 1 if not options.quiet: - c.write( "| " + path + " was removed." ) + c.write( "| " + rel_path + " was removed." ) except OSError: # Fails on non-empty directory pass @@ -484,7 +492,10 @@ def main( args ): c.write("|Done.") if not options.quiet: - output = "\n[ Removed " + str( remove_file_count ) + singular_pulural( remove_file_count, " file, ", " files, " ) + output = "\nChecked " + str( processed_file_count ) + singular_pulural( processed_file_count, " file, ", " files, " ) + output += str( processed_directory_count ) + singular_pulural( processed_directory_count, " directory", " directories") + + output += "\nRemoved " + str( remove_file_count ) + singular_pulural( remove_file_count, " file, ", " files, " ) output += str( remove_dir_count ) + singular_pulural( remove_dir_count, " directory", " directories") if warning_count > 0: @@ -494,9 +505,9 @@ def main( args ): end = time.clock() delta = end - start - output += ", and finished in " + str(delta) + "s" + output += "\nFinished in " + str(delta) + "s" - c.write( output + " ]" ) + c.write( output ) if __name__ == "__main__": try: diff --git a/python2.7.exe.stackdump b/python2.7.exe.stackdump deleted file mode 100644 index 2050f78..0000000 --- a/python2.7.exe.stackdump +++ /dev/null @@ -1,16 +0,0 @@ -Stack trace: -Frame Function Args -000FD4FC6C0 0018006F733 (FFFFFFFFFFFFFFFF, 006002C2510, 005CCDD1850, 005CCDD1870) -00000000006 00180070C6A (000FD4FC8A0, 00000000000, 0000000035C, 00000000000) -000FD4FC8A0 00180118778 (00000000000, 00000000000, 000FD4FCA20, 00600000003) -00000000041 0018011587E (00180133B2D, 000000002CC, 00000000000, 00000000000) -00000000000 00180115D4B (001801362C0, 006002C2270, 000775D19A1, 00000000006) -00000000000 00180115F1C (00000000000, 0008FB10544, 7FEFD6464DA, 006002C2318) -00000000000 001801161DF (0018013B2FB, 00600000001, 001801CA2C0, 000FD4FD640) -00000000000 00180144816 (00180135C7F, 006002C2270, 006002C2270, 006002C2270) -00000000000 001800BFCE3 (0018013460D, 00000000000, 005CCDB7127, 006002C2318) -00000000000 001801629FC (00000000000, 00000000000, 00000000000, 006002C2270) -00000000000 00180136AEF (00000000000, 00000000000, 00000000000, 00000000000) -00000000000 00180136334 (000003A0000, 00000000000, 00000000000, 00000000000) -00000000000 001800C373B (000003A0000, 00000000000, 00000000000, 00000000000) -End of stack trace