]> arthur.barton.de Git - bup.git/blob - cmd/split-cmd.py
Merge branch 'maint'
[bup.git] / cmd / split-cmd.py
1 #!/usr/bin/env python
2 import sys, time
3 from bup import hashsplit, git, options, client
4 from bup.helpers import *
5
6
7 optspec = """
8 bup split [-tcb] [-n name] [--bench] [filenames...]
9 --
10 r,remote=  remote repository path
11 b,blobs    output a series of blob ids
12 t,tree     output a tree id
13 c,commit   output a commit id
14 n,name=    name of backup set to update (if any)
15 d,date=    date for the commit (seconds since the epoch)
16 q,quiet    don't print progress messages
17 v,verbose  increase log output (can be used more than once)
18 noop       don't actually save the data anywhere
19 copy       just copy input to output, hashsplitting along the way
20 bench      print benchmark timings to stderr
21 max-pack-size=  maximum bytes in a single pack
22 max-pack-objects=  maximum number of objects in a single pack
23 fanout=    maximum number of blobs in a single tree
24 bwlimit=   maximum bytes/sec to transmit to server
25 """
26 o = options.Options('bup split', optspec)
27 (opt, flags, extra) = o.parse(sys.argv[1:])
28
29 handle_ctrl_c()
30 git.check_repo_or_die()
31 if not (opt.blobs or opt.tree or opt.commit or opt.name or
32         opt.noop or opt.copy):
33     o.fatal("use one or more of -b, -t, -c, -n, -N, --copy")
34 if (opt.noop or opt.copy) and (opt.blobs or opt.tree or 
35                                opt.commit or opt.name):
36     o.fatal('-N and --copy are incompatible with -b, -t, -c, -n')
37
38 if opt.verbose >= 2:
39     git.verbose = opt.verbose - 1
40     opt.bench = 1
41 if opt.max_pack_size:
42     hashsplit.max_pack_size = parse_num(opt.max_pack_size)
43 if opt.max_pack_objects:
44     hashsplit.max_pack_objects = parse_num(opt.max_pack_objects)
45 if opt.fanout:
46     hashsplit.fanout = parse_num(opt.fanout)
47 if opt.blobs:
48     hashsplit.fanout = 0
49 if opt.bwlimit:
50     client.bwlimit = parse_num(opt.bwlimit)
51 if opt.date:
52     date = parse_date_or_fatal(opt.date, o.fatal)
53 else:
54     date = time.time()
55
56
57 is_reverse = os.environ.get('BUP_SERVER_REVERSE')
58 if is_reverse and opt.remote:
59     o.fatal("don't use -r in reverse mode; it's automatic")
60 start_time = time.time()
61
62 refname = opt.name and 'refs/heads/%s' % opt.name or None
63 if opt.noop or opt.copy:
64     cli = pack_writer = oldref = None
65 elif opt.remote or is_reverse:
66     if opt.remote and opt.remote.find(":") == -1:
67         o.fatal("--remote argument must contain a colon")
68     try:
69         cli = client.Client(opt.remote)
70     except client.ClientError:
71         o.fatal("server exited unexpectedly; see errors above")
72     oldref = refname and cli.read_ref(refname) or None
73     pack_writer = cli.new_packwriter()
74 else:
75     cli = None
76     oldref = refname and git.read_ref(refname) or None
77     pack_writer = git.PackWriter()
78
79 files = extra and (open(fn) for fn in extra) or [sys.stdin]
80 if pack_writer:
81     shalist = hashsplit.split_to_shalist(pack_writer, files)
82     tree = pack_writer.new_tree(shalist)
83 else:
84     last = 0
85     for (blob, bits) in hashsplit.hashsplit_iter(files):
86         hashsplit.total_split += len(blob)
87         if opt.copy:
88             sys.stdout.write(str(blob))
89         megs = hashsplit.total_split/1024/1024
90         if not opt.quiet and last != megs:
91             progress('%d Mbytes read\r' % megs)
92             last = megs
93     progress('%d Mbytes read, done.\n' % megs)
94
95 if opt.verbose:
96     log('\n')
97 if opt.blobs:
98     for (mode,name,bin) in shalist:
99         print bin.encode('hex')
100 if opt.tree:
101     print tree.encode('hex')
102 if opt.commit or opt.name:
103     msg = 'bup split\n\nGenerated by command:\n%r' % sys.argv
104     ref = opt.name and ('refs/heads/%s' % opt.name) or None
105     commit = pack_writer.new_commit(oldref, tree, date, msg)
106     if opt.commit:
107         print commit.encode('hex')
108
109 if pack_writer:
110     pack_writer.close()  # must close before we can update the ref
111
112 if opt.name:
113     if cli:
114         cli.update_ref(refname, commit, oldref)
115     else:
116         git.update_ref(refname, commit, oldref)
117
118 if cli:
119     cli.close()
120
121 secs = time.time() - start_time
122 size = hashsplit.total_split
123 if opt.bench:
124     log('\nbup: %.2fkbytes in %.2f secs = %.2f kbytes/sec\n'
125         % (size/1024., secs, size/1024./secs))