1054
by Martin Pool
- merge john's "missing" command |
1 |
#!/usr/bin/env python
|
2 |
"""\
|
|
3 |
A plugin for displaying what revisions are in 'other' but not in local.
|
|
4 |
"""
|
|
5 |
||
6 |
import bzrlib |
|
7 |
||
8 |
try: |
|
9 |
set
|
|
10 |
except NameError: |
|
11 |
from sets import Set as set |
|
12 |
||
13 |
||
14 |
def get_parent(branch): |
|
15 |
"""Get the last pull/push location.
|
|
16 |
||
17 |
TODO: This should probably be part of a Branch object.
|
|
18 |
"""
|
|
19 |
import errno |
|
20 |
_locs = ['parent', 'pull', 'x-pull'] |
|
21 |
loc = None |
|
22 |
for l in _locs: |
|
23 |
try: |
|
24 |
stored_loc = branch.controlfile(l, 'rb').read().strip('\n') |
|
25 |
except IOError, e: |
|
26 |
if e.errno != errno.ENOENT: |
|
27 |
raise
|
|
28 |
else: |
|
29 |
return stored_loc |
|
30 |
||
31 |
||
32 |
def show_missing(br_local, br_remote, verbose=False, quiet=False): |
|
33 |
"""Show the revisions which exist in br_remote, that
|
|
34 |
do not exist in br_local.
|
|
35 |
"""
|
|
36 |
from bzrlib.log import show_one_log |
|
37 |
import sys |
|
38 |
local_history = br_local.revision_history() |
|
39 |
remote_history = br_remote.revision_history() |
|
40 |
if local_history == remote_history: |
|
41 |
if not quiet: |
|
42 |
print 'Trees are identical.' |
|
43 |
return 0 |
|
44 |
if local_history[:len(remote_history)] == remote_history: |
|
45 |
# Local is not missing anything from remote, so consider it
|
|
46 |
# up-to-date
|
|
47 |
if not quiet: |
|
48 |
print 'Local tree has all of remote revisions (remote is missing local)' |
|
49 |
return 0 |
|
50 |
if quiet: |
|
51 |
return 1 |
|
52 |
||
53 |
# Check for divergence
|
|
54 |
common_idx = min(len(local_history), len(remote_history)) - 1 |
|
55 |
if common_idx >= 0 and local_history[common_idx] != remote_history[common_idx]: |
|
56 |
print 'Trees have diverged' |
|
57 |
||
58 |
local_rev_set = set(local_history) |
|
59 |
||
60 |
# Find the last common revision between the two trees
|
|
61 |
revno = 0 |
|
62 |
for revno, (local_rev, remote_rev) in enumerate(zip(local_history, remote_history)): |
|
63 |
if local_rev != remote_rev: |
|
64 |
break
|
|
65 |
||
66 |
missing_remote = [] |
|
67 |
for rno, rev_id in enumerate(remote_history[revno:]): |
|
68 |
# This assumes that you can have a revision in the
|
|
69 |
# local history, which does not have the same ancestry
|
|
70 |
# as the remote ancestry.
|
|
71 |
# This may or may not be possible.
|
|
72 |
# In the future this should also checked for merged revisions.
|
|
73 |
if rev_id not in local_rev_set: |
|
74 |
missing_remote.append((rno+revno+1, rev_id)) |
|
75 |
||
76 |
print 'Missing %d revisions' % len(missing_remote) |
|
77 |
print
|
|
78 |
||
79 |
if verbose: |
|
80 |
from bzrlib.diff import compare_trees |
|
81 |
from bzrlib.tree import EmptyTree |
|
82 |
show_ids = True |
|
83 |
last_tree = EmptyTree |
|
84 |
last_rev_id = None |
|
85 |
else: |
|
86 |
show_ids = False |
|
87 |
for revno, rev_id in missing_remote: |
|
88 |
rev = br_remote.get_revision(rev_id) |
|
89 |
if verbose: |
|
90 |
parent_rev_id = rev.parents[0].revision_id |
|
91 |
if last_rev_id == parent_rev_id: |
|
92 |
parent_tree = last_tree |
|
93 |
else: |
|
94 |
parent_tree = br_remote.revision_tree(parent_rev_id) |
|
95 |
revision_tree = br_remote.revision_tree(rev_id) |
|
96 |
last_rev_id = rev_id |
|
97 |
last_tree = revision_tree |
|
98 |
delta = compare_trees(revision_tree, parent_tree) |
|
99 |
else: |
|
100 |
delta = None |
|
101 |
||
102 |
show_one_log(revno, rev, delta, verbose, sys.stdout, 'original') |
|
103 |
return 1 |
|
104 |