X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=cmd%2Findex-cmd.py;h=ab97e928407bc21e081e5af5b9b64ddbe1da339d;hb=12322abaf04152a80b03ca7cf0d8f6d3bfe4bbaa;hp=7bf526443f3acb65f515b873c42b5c747beaa221;hpb=b1c766667d8dd7735ed0a2e7fa26754a9ef534ce;p=bup.git diff --git a/cmd/index-cmd.py b/cmd/index-cmd.py index 7bf5264..ab97e92 100755 --- a/cmd/index-cmd.py +++ b/cmd/index-cmd.py @@ -1,9 +1,18 @@ -#!/usr/bin/env python +#!/bin/sh +"""": # -*-python-*- +bup_python="$(dirname "$0")/bup-python" || exit $? +exec "$bup_python" "$0" ${1+"$@"} +""" +# end of bup preamble import sys, stat, time, os, errno, re + from bup import metadata, options, git, index, drecurse, hlinkdb -from bup.helpers import * +from bup.drecurse import recursive_dirlist from bup.hashsplit import GIT_MODE_TREE, GIT_MODE_FILE +from bup.helpers import (add_error, handle_ctrl_c, log, parse_excludes, parse_rx_excludes, + progress, qprogress, saved_errors) + class IterHelper: def __init__(self, l): @@ -57,12 +66,12 @@ def clear_index(indexfile): os.remove(path) if opt.verbose: log('clear: removed %s\n' % path) - except OSError, e: + except OSError as e: if e.errno != errno.ENOENT: raise -def update_index(top, excluded_paths, exclude_rxs): +def update_index(top, excluded_paths, exclude_rxs, xdev_exceptions): # tmax and start must be epoch nanoseconds. tmax = (time.time() - 1) * 10**9 ri = index.Reader(indexfile) @@ -80,16 +89,23 @@ def update_index(top, excluded_paths, exclude_rxs): total = 0 bup_dir = os.path.abspath(git.repo()) - for (path,pst) in drecurse.recursive_dirlist([top], xdev=opt.xdev, - bup_dir=bup_dir, - excluded_paths=excluded_paths, - exclude_rxs=exclude_rxs): + index_start = time.time() + for path, pst in recursive_dirlist([top], + xdev=opt.xdev, + bup_dir=bup_dir, + excluded_paths=excluded_paths, + exclude_rxs=exclude_rxs, + xdev_exceptions=xdev_exceptions): if opt.verbose>=2 or (opt.verbose==1 and stat.S_ISDIR(pst.st_mode)): sys.stdout.write('%s\n' % path) sys.stdout.flush() - qprogress('Indexing: %d\r' % total) + elapsed = time.time() - index_start + paths_per_sec = total / elapsed if elapsed else 0 + qprogress('Indexing: %d (%d paths/s)\r' % (total, paths_per_sec)) elif not (total % 128): - qprogress('Indexing: %d\r' % total) + elapsed = time.time() - index_start + paths_per_sec = total / elapsed if elapsed else 0 + qprogress('Indexing: %d (%d paths/s)\r' % (total, paths_per_sec)) total += 1 while rig.cur and rig.cur.name > path: # deleted paths if rig.cur.exists(): @@ -101,7 +117,7 @@ def update_index(top, excluded_paths, exclude_rxs): if rig.cur and rig.cur.name == path: # paths that already existed try: meta = metadata.from_path(path, statinfo=pst) - except (OSError, IOError), e: + except (OSError, IOError) as e: add_error(e) rig.next() continue @@ -136,7 +152,7 @@ def update_index(top, excluded_paths, exclude_rxs): else: # new paths try: meta = metadata.from_path(path, statinfo=pst) - except (OSError, IOError), e: + except (OSError, IOError) as e: add_error(e) continue # See same assignment to 0, above, for rationale. @@ -146,8 +162,10 @@ def update_index(top, excluded_paths, exclude_rxs): if not stat.S_ISDIR(pst.st_mode) and pst.st_nlink > 1: hlinks.add_path(path, pst.st_dev, pst.st_ino) - progress('Indexing: %d, done.\n' % total) - + elapsed = time.time() - index_start + paths_per_sec = total / elapsed if elapsed else 0 + progress('Indexing: %d, done (%d paths/s).\n' % (total, paths_per_sec)) + hlinks.prepare_save() if ri.exists(): @@ -178,7 +196,7 @@ def update_index(top, excluded_paths, exclude_rxs): optspec = """ -bup index <-p|m|s|u> [options...] +bup index <-p|-m|-s|-u|--clear|--check> [options...] -- Modes: p,print print the index entries for the given names (also works with -u) @@ -194,9 +212,10 @@ no-check-device don't invalidate an entry if the containing device changes fake-valid mark all index entries as up-to-date even if they aren't fake-invalid mark all index entries as invalid f,indexfile= the name of the index file (normally BUP_DIR/bupindex) -exclude= a path to exclude from the backup (can be used more than once) -exclude-from= a file that contains exclude paths (can be used more than once) -exclude-rx= skip paths that match the unanchored regular expression +exclude= a path to exclude from the backup (may be repeated) +exclude-from= skip --exclude paths in file (may be repeated) +exclude-rx= skip paths matching the unanchored regex (may be repeated) +exclude-rx-from= skip --exclude-rx patterns in file (may be repeated) v,verbose increase log output (can be used more than once) x,xdev,one-file-system don't cross filesystem boundaries """ @@ -237,15 +256,14 @@ if opt.clear: log('clear: clearing index.\n') clear_index(indexfile) -excluded_paths = parse_excludes(flags, o.fatal) -exclude_rxs = parse_rx_excludes(flags, o.fatal) -paths = index.reduce_paths(extra) - if opt.update: if not extra: o.fatal('update mode (-u) requested but no paths given') - for (rp,path) in paths: - update_index(rp, excluded_paths, exclude_rxs) + excluded_paths = parse_excludes(flags, o.fatal) + exclude_rxs = parse_rx_excludes(flags, o.fatal) + xexcept = index.unique_resolved_paths(extra) + for rp, path in index.reduce_paths(extra): + update_index(rp, excluded_paths, exclude_rxs, xdev_exceptions=xexcept) if opt['print'] or opt.status or opt.modified: for (name, ent) in index.Reader(indexfile).filter(extra or ['']):