Merge lp:~andrewfenn/bzr-upload/force-option into lp:bzr-upload

Proposed by Andrew Fenn
Status: Work in progress
Proposed branch: lp:~andrewfenn/bzr-upload/force-option
Merge into: lp:bzr-upload
Diff against target: 141 lines (+48/-9)
2 files modified
__init__.py (+46/-8)
auto_upload_hook.py (+2/-1)
To merge this branch: bzr merge lp:~andrewfenn/bzr-upload/force-option
Reviewer Review Type Date Requested Status
Vincent Ladeuil Needs Fixing
Review via email: mp+15998@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) wrote :

I'm not a bzr-upload dev, but this looks unusual to me. Do you mean to ignore *all* errors on the target and just keep trying? That seems fragile to me; what if the fs is readonly, or if the failure is a rename and so on - wouldn't it be better to handle an error by resetting the entire tree to a known good state?

Revision history for this message
Andrew Fenn (andrewfenn) wrote :

I've been using my fork at the office without issue. If you want to
re-upload 2 gigs worth of data simply because one folder or file is
missing on the target machine then be my guest.

On Mon, Jun 21, 2010 at 7:30 AM, Robert Collins
<email address hidden> wrote:
> I'm not a bzr-upload dev, but this looks unusual to me. Do you mean to ignore *all* errors on the target and just keep trying? That seems fragile to me; what if the fs is readonly, or if the failure is a rename and so on - wouldn't it be better to handle an error by resetting the entire tree to a known good state?
> --
> https://code.launchpad.net/~andrewfenn/bzr-upload/force-option/+merge/15998
> You are the owner of lp:~andrewfenn/bzr-upload/force-option.
>

Revision history for this message
Robert Collins (lifeless) wrote :

No, I don't want to upload 2G of data, I was merely seeking to
understand more of the intent of your patch, hopefully to make it
clearer to the bzr-upload devs whom are the only ones that can merge
the patch to trunk.

-Rob

Revision history for this message
Andrew Fenn (andrewfenn) wrote :

Hi Robert,

Basically it fixes this bug..
https://bugs.launchpad.net/bzr-upload/+bug/215612

I submitted a patch and was told to make this branch by the bzr-upload devs. It has since been left ignored. I'm not bitter about this but I don't understand sure why they would make me go to such efforts only to then not even review the patch.

I believe this stems from simply disagreement with the main developers. If I am correct in saying I do not think they want such a feature and (as you can read in the bug) think it is better for a user to completely upload the entire contents of a bazaar repo again if it becomes out of sync; hence my comment about uploading the 2GB of data. :)

Since submitting this patch I've noticed some other things that bzr-plugin does wrong which I have already forked. An example of this being if moving renamed files errors out, it creates problems because the temporary name given while moving is random so there is no way to recover from such an error.

I'd be happy to share such fixes if it hasn't already been fixed upstream of course.

Revision history for this message
Martin Pool (mbp) wrote :

To me, this seems basically plausible, except that the bare 'except:' would be better off catching FileExists, which may have been Robert's original point.

This might be better described as 'ignore errors' rather than 'force', which to me would imply specifically deleting things that don't match.

It might be nice to use a higher order function for the 'ignore' behaviour and it would be good to have tests (if upload has tests at the moment.)

On the whole this would be better in than out, though.

Revision history for this message
Vincent Ladeuil (vila) wrote :

> Hi Robert,
>
> Basically it fixes this bug..
> https://bugs.launchpad.net/bzr-upload/+bug/215612
>
> I submitted a patch and was told to make this branch by the bzr-upload devs.
> It has since been left ignored.

Sorry about that, dunno why it get lost. In case it occurs again, don't hesitate to ping us via the review comments (and adding a description for the merge proposal also helps getting it reviewed faster).

> I believe this stems from simply disagreement with the main developers.

I don't think so, your patch address *part* of the problems raised in the bug report and as such will not fully fix it, but the part you address is fine.

> If I
> am correct in saying I do not think they want such a feature and (as you can
> read in the bug) think it is better for a user to completely upload the entire
> contents of a bazaar repo again if it becomes out of sync; hence my comment
> about uploading the 2GB of data. :)

If a full upload is 2GB of data, I'm sure you're interested in keeping it well synchronized and to achieve this you have to make sure the remote working tree is not altered in ways that could break the mechanisms used to maintain it.

Deletions are the easy part.

>
> Since submitting this patch I've noticed some other things that bzr-plugin
> does wrong which I have already forked.

Did you file bugs for them ?

On with the review itself now:

- we need tests for this, I can help help you write them if you want,

38 +
39 + if not self.force:
40 + self.to_transport.mkdir(relpath, mode)
41 + else:
42 + try:
43 + self.to_transport.mkdir(relpath, mode)
44 + except:
45 + self.outf.write('Directory %s already exists. Ignoring.\n' % relpath)

How about using make_remote_dir_robustly() in this case which is targeted at this use case ? Or even better, add the force parameter support to make_remote_dir() and get rid of make_remote_dir_robustly() ? That would reduce code duplication.

The bug also discussed alternate names to use instead of force, why did you chose this one ?

review: Needs Fixing
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

Setting back to work in progress for now, as it has been requiring followup for > 2 years.

Unmerged revisions

69. By Andrew Fenn

- Fix for unit test

68. By Andrew Fenn

- Adds force option that ignores delete and mkdir errors.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '__init__.py'
2--- __init__.py 2009-12-02 10:02:05 +0000
3+++ __init__.py 2009-12-11 04:21:13 +0000
4@@ -244,6 +244,11 @@
5 quiet = False # Default to False if not specified
6 return quiet
7
8+def get_upload_force(branch):
9+ force = _get_branch_bool_option(branch, 'force')
10+ if force is None:
11+ force = False # Default to False if not specified
12+ return force
13
14 def set_upload_auto_quiet(branch, quiet):
15 _set_branch_option(branch, 'upload_auto_quiet', quiet)
16@@ -252,13 +257,15 @@
17 class BzrUploader(object):
18
19 def __init__(self, branch, to_transport, outf, tree, rev_id,
20- quiet=False):
21+ quiet=False,
22+ force=False):
23 self.branch = branch
24 self.to_transport = to_transport
25 self.outf = outf
26 self.tree = tree
27 self.rev_id = rev_id
28 self.quiet = quiet
29+ self.force = force
30 self._pending_deletions = []
31 self._pending_renames = []
32 self._uploaded_revid = None
33@@ -325,7 +332,14 @@
34 if relpath not in ignored_files:
35 if mode is None:
36 mode = 0775
37- self.to_transport.mkdir(relpath, mode)
38+
39+ if not self.force:
40+ self.to_transport.mkdir(relpath, mode)
41+ else:
42+ try:
43+ self.to_transport.mkdir(relpath, mode)
44+ except:
45+ self.outf.write('Directory %s already exists. Ignoring.\n' % relpath)
46 else:
47 if not self.quiet:
48 self.outf.write('Ignoring %s\n' % relpath)
49@@ -353,15 +367,31 @@
50 def delete_remote_file(self, relpath):
51 if not self.quiet:
52 self.outf.write('Deleting %s\n' % relpath)
53- self.to_transport.delete(relpath)
54+
55+ if not self.force:
56+ self.to_transport.delete(relpath)
57+ else:
58+ try:
59+ self.to_transport.delete(relpath)
60+ except errors.NoSuchFile:
61+ self.outf.write('Error: %s does not exist\n' % relpath)
62
63 def delete_remote_dir(self, relpath):
64 if not self.quiet:
65 self.outf.write('Deleting %s\n' % relpath)
66- self.to_transport.rmdir(relpath)
67+
68+ if not self.force:
69+ self.to_transport.rmdir(relpath)
70+ else:
71+ try:
72+ self.to_transport.rmdir(relpath)
73+ except errors.PathError:
74+ self.outf.write('Error: %s can not be deleted\n' % relpath)
75
76 def delete_remote_dir_maybe(self, relpath):
77 """Try to delete relpath, keeping failures to retry later."""
78+ if not self.quiet:
79+ self.outf.write('Maybe deleting %s\n' % relpath)
80 try:
81 self.to_transport.rmdir(relpath)
82 # any kind of PathError would be OK, though we normally expect
83@@ -374,7 +404,13 @@
84 # Process the previously failed deletions in reverse order to
85 # delete children before parents
86 for relpath in reversed(self._pending_deletions):
87- self.to_transport.rmdir(relpath)
88+ if not self.force:
89+ self.to_transport.rmdir(relpath)
90+ else:
91+ try:
92+ self.to_transport.rmdir(relpath)
93+ except errors.PathError:
94+ self.outf.write('Error: %s can not be deleted\n' % relpath)
95 # The following shouldn't be needed since we use it once per
96 # upload, but better safe than sorry ;-)
97 self._pending_deletions = []
98@@ -545,11 +581,13 @@
99 ),
100 option.Option('auto',
101 'Trigger an upload from this branch whenever the tip '
102- 'revision changes.')
103+ 'revision changes.'),
104+ option.Option('force', 'Continues uploading even when files are out of sync.',
105+ short_name='f')
106 ]
107
108 def run(self, location=None, full=False, revision=None, remember=None,
109- directory=None, quiet=False, auto=None, overwrite=False
110+ directory=None, quiet=False, force=False, auto=None, overwrite=False
111 ):
112 if directory is None:
113 directory = u'.'
114@@ -611,7 +649,7 @@
115 tree = branch.repository.revision_tree(rev_id)
116
117 uploader = BzrUploader(branch, to_transport, self.outf, tree,
118- rev_id, quiet=quiet)
119+ rev_id, quiet=quiet, force=force)
120
121 if not overwrite:
122 prev_uploaded_rev_id = uploader.get_uploaded_revid()
123
124=== modified file 'auto_upload_hook.py'
125--- auto_upload_hook.py 2009-09-02 17:05:27 +0000
126+++ auto_upload_hook.py 2009-12-11 04:21:13 +0000
127@@ -36,6 +36,7 @@
128 if not auto_upload:
129 return
130 quiet = upload.get_upload_auto_quiet(source_branch)
131+ force = upload.get_upload_force(source_branch)
132 if not quiet:
133 display_url = urlutils.unescape_for_display(
134 destination, osutils.get_terminal_encoding())
135@@ -44,5 +45,5 @@
136 last_revision = source_branch.last_revision()
137 last_tree = source_branch.repository.revision_tree(last_revision)
138 uploader = upload.BzrUploader(source_branch, to_transport, sys.stdout,
139- last_tree, last_revision, quiet=quiet)
140+ last_tree, last_revision, quiet=quiet, force=force)
141 uploader.upload_tree()

Subscribers

People subscribed via source and target branches

to status/vote changes: