~bzr-pqm/bzr/bzr.dev

6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1
# Copyright (C) 2007-2011, 2016 Canonical Ltd
2220.2.2 by Martin Pool
Add tag command and basic implementation
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2220.2.2 by Martin Pool
Add tag command and basic implementation
16
17
"""Tests for commands related to tags"""
18
5086.4.2 by Jelmer Vernooij
Tag names can now be determined automatically by hooks if they are
19
from bzrlib import (
6165.3.1 by Jelmer Vernooij
Support running 'bzr tags' against remote repositories without revision graph access.
20
    errors,
5086.4.2 by Jelmer Vernooij
Tag names can now be determined automatically by hooks if they are
21
    tag,
5954.2.4 by Aaron Bentley
Fix broken tests.
22
    transform,
5086.4.2 by Jelmer Vernooij
Tag names can now be determined automatically by hooks if they are
23
    )
2220.2.11 by mbp at sourcefrog
Get tag tests working again, stored in the Branch
24
from bzrlib.branch import (
25
    Branch,
26
    )
5050.52.2 by Andrew Bennetts
Add failing test using run_script.
27
from bzrlib.tests import (
28
    script,
29
    TestCaseWithTransport,
30
    )
6352.2.3 by Jelmer Vernooij
s/NoVfsCalls/ContainsNoVfsCalls/.
31
from bzrlib.tests.matchers import ContainsNoVfsCalls
2220.2.8 by Martin Pool
Add -d option to push, pull, merge commands.
32
from bzrlib.workingtree import WorkingTree
2220.2.2 by Martin Pool
Add tag command and basic implementation
33
34
35
class TestTagging(TestCaseWithTransport):
36
37
    def test_tag_command_help(self):
2552.2.2 by Vincent Ladeuil
Enforce run_bzr(string) where possible.
38
        out, err = self.run_bzr('help tag')
2664.1.2 by Joachim Nilsson
Update tag test to match new description.
39
        self.assertContainsRe(out, 'Create, remove or modify a tag')
2220.2.2 by Martin Pool
Add tag command and basic implementation
40
2220.2.6 by Martin Pool
Add tag -r option
41
    def test_cannot_tag_range(self):
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
42
        out, err = self.run_bzr('tag -r1..10 name', retcode=3)
2220.2.6 by Martin Pool
Add tag -r option
43
        self.assertContainsRe(err,
44
            "Tags can only be placed on a single revision")
45
5086.4.3 by Jelmer Vernooij
Add extra test.
46
    def test_no_tag_name(self):
47
        out, err = self.run_bzr('tag -d branch', retcode=3)
48
        self.assertContainsRe(err, 'Please specify a tag name.')
49
5086.4.2 by Jelmer Vernooij
Tag names can now be determined automatically by hooks if they are
50
    def test_automatic_tag_name(self):
51
        def get_tag_name(branch, revid):
52
            return "mytag"
5086.4.5 by Jelmer Vernooij
Make automatic_tag_name a hook on Branch.
53
        Branch.hooks.install_named_hook('automatic_tag_name',
54
            get_tag_name, 'get tag name')
5086.4.2 by Jelmer Vernooij
Tag names can now be determined automatically by hooks if they are
55
        out, err = self.run_bzr('tag -d branch')
5459.7.1 by Neil Martinsen-Burrell
make "bzr tag --quiet" really quiet
56
        self.assertContainsRe(err, 'Created tag mytag.')
5086.4.2 by Jelmer Vernooij
Tag names can now be determined automatically by hooks if they are
57
2220.2.2 by Martin Pool
Add tag command and basic implementation
58
    def test_tag_current_rev(self):
59
        t = self.make_branch_and_tree('branch')
60
        t.commit(allow_pointless=True, message='initial commit',
61
            rev_id='first-revid')
62
        # make a tag through the command line
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
63
        out, err = self.run_bzr('tag -d branch NEWTAG')
5459.7.1 by Neil Martinsen-Burrell
make "bzr tag --quiet" really quiet
64
        self.assertContainsRe(err, 'Created tag NEWTAG.')
2220.2.2 by Martin Pool
Add tag command and basic implementation
65
        # tag should be observable through the api
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
66
        self.assertEqual(t.branch.tags.get_tag_dict(),
2220.2.20 by Martin Pool
Tag methods now available through Branch.tags.add_tag, etc
67
                dict(NEWTAG='first-revid'))
2220.2.6 by Martin Pool
Add tag -r option
68
        # can also create tags using -r
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
69
        self.run_bzr('tag -d branch tag2 -r1')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
70
        self.assertEqual(t.branch.tags.lookup_tag('tag2'), 'first-revid')
2325.2.2 by Marien Zwart
Make the revid RevisionSpec always return a str object, not a unicode object.
71
        # regression test: make sure a unicode revision from the user
72
        # gets turned into a str object properly. The use of a unicode
73
        # object for the revid is intentional.
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
74
        self.run_bzr(['tag', '-d', 'branch', 'tag3', u'-rrevid:first-revid'])
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
75
        self.assertEqual(t.branch.tags.lookup_tag('tag3'), 'first-revid')
2220.2.21 by Martin Pool
Add tag --delete command and implementation
76
        # can also delete an existing tag
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
77
        out, err = self.run_bzr('tag --delete -d branch tag2')
2220.2.42 by Martin Pool
Tag command refuses to replace existing tags unless you force it.
78
        # cannot replace an existing tag normally
6111.2.1 by Jelmer Vernooij
``bzr tag`` no longer errors if a tag already exists but refers to the
79
        out, err = self.run_bzr('tag -d branch NEWTAG -r0', retcode=3)
2220.2.42 by Martin Pool
Tag command refuses to replace existing tags unless you force it.
80
        self.assertContainsRe(err, 'Tag NEWTAG already exists\\.')
81
        # ... but can if you use --force
6123.5.1 by Jelmer Vernooij
Mention when a tag has been updated vs created.
82
        out, err = self.run_bzr('tag -d branch NEWTAG --force -r0')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
83
        self.assertEqual("Updated tag NEWTAG.\n", err)
2220.2.8 by Martin Pool
Add -d option to push, pull, merge commands.
84
6111.2.1 by Jelmer Vernooij
``bzr tag`` no longer errors if a tag already exists but refers to the
85
    def test_tag_same_revision(self):
86
        t = self.make_branch_and_tree('branch')
87
        t.commit(allow_pointless=True, message='initial commit',
88
            rev_id='first-revid')
89
        t.commit(allow_pointless=True, message='second commit',
90
            rev_id='second-revid')
91
        out, err = self.run_bzr('tag -rrevid:first-revid -d branch NEWTAG')
92
        out, err = self.run_bzr('tag -rrevid:first-revid -d branch NEWTAG')
93
        self.assertContainsRe(err,
94
            'Tag NEWTAG already exists for that revision\\.')
95
        out, err = self.run_bzr('tag -rrevid:second-revid -d branch NEWTAG',
96
            retcode=3)
97
        self.assertContainsRe(err, 'Tag NEWTAG already exists\\.')
98
5086.4.2 by Jelmer Vernooij
Tag names can now be determined automatically by hooks if they are
99
    def test_tag_delete_requires_name(self):
100
        out, err = self.run_bzr('tag -d branch', retcode=3)
101
        self.assertContainsRe(err, 'Please specify a tag name\\.')
102
2220.2.8 by Martin Pool
Add -d option to push, pull, merge commands.
103
    def test_branch_push_pull_merge_copies_tags(self):
104
        t = self.make_branch_and_tree('branch1')
105
        t.commit(allow_pointless=True, message='initial commit',
106
            rev_id='first-revid')
2220.2.11 by mbp at sourcefrog
Get tag tests working again, stored in the Branch
107
        b1 = t.branch
2220.2.20 by Martin Pool
Tag methods now available through Branch.tags.add_tag, etc
108
        b1.tags.set_tag('tag1', 'first-revid')
2220.2.8 by Martin Pool
Add -d option to push, pull, merge commands.
109
        # branching copies the tag across
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
110
        self.run_bzr('branch branch1 branch2')
2220.2.11 by mbp at sourcefrog
Get tag tests working again, stored in the Branch
111
        b2 = Branch.open('branch2')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
112
        self.assertEqual(b2.tags.lookup_tag('tag1'), 'first-revid')
2220.2.8 by Martin Pool
Add -d option to push, pull, merge commands.
113
        # make a new tag and pull it
2220.2.20 by Martin Pool
Tag methods now available through Branch.tags.add_tag, etc
114
        b1.tags.set_tag('tag2', 'twa')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
115
        self.run_bzr('pull -d branch2 branch1')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
116
        self.assertEqual(b2.tags.lookup_tag('tag2'), 'twa')
2220.2.8 by Martin Pool
Add -d option to push, pull, merge commands.
117
        # make a new tag and push it
2220.2.20 by Martin Pool
Tag methods now available through Branch.tags.add_tag, etc
118
        b1.tags.set_tag('tag3', 'san')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
119
        self.run_bzr('push -d branch1 branch2')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
120
        self.assertEqual(b2.tags.lookup_tag('tag3'), 'san')
2220.2.8 by Martin Pool
Add -d option to push, pull, merge commands.
121
        # make a new tag and merge it
122
        t.commit(allow_pointless=True, message='second commit',
123
            rev_id='second-revid')
124
        t2 = WorkingTree.open('branch2')
125
        t2.commit(allow_pointless=True, message='commit in second')
2220.2.20 by Martin Pool
Tag methods now available through Branch.tags.add_tag, etc
126
        b1.tags.set_tag('tag4', 'second-revid')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
127
        self.run_bzr('merge -d branch2 branch1')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
128
        self.assertEqual(b2.tags.lookup_tag('tag4'), 'second-revid')
2348.2.1 by Marien Zwart
Properly push tags if push creates a new branch.
129
        # pushing to a new location copies the tag across
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
130
        self.run_bzr('push -d branch1 branch3')
2348.2.1 by Marien Zwart
Properly push tags if push creates a new branch.
131
        b3 = Branch.open('branch3')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
132
        self.assertEqual(b3.tags.lookup_tag('tag1'), 'first-revid')
2220.2.24 by Martin Pool
Add tags command
133
5050.52.4 by Andrew Bennetts
Use run_script more sparingly.
134
    def make_master_and_checkout(self):
135
        builder = self.make_branch_builder('master')
136
        builder.build_commit(message='Initial commit.', rev_id='rev-1')
137
        master = builder.get_branch()
138
        child = master.create_checkout(self.get_url('child'))
139
        return master, child
140
141
    def make_fork(self, branch):
142
        fork = branch.create_clone_on_transport(self.get_transport('fork'))
5954.2.7 by Aaron Bentley
New-style locking.
143
        self.addCleanup(fork.lock_write().unlock)
5954.2.4 by Aaron Bentley
Fix broken tests.
144
        with transform.TransformPreview(fork.basis_tree()) as tt:
145
            tt.commit(fork, message='Commit in fork.', revision_id='fork-0')
146
        with transform.TransformPreview(fork.basis_tree()) as tt:
147
            tt.commit(fork, message='Commit in fork.', revision_id='fork-1')
5050.52.4 by Andrew Bennetts
Use run_script more sparingly.
148
        return fork
149
5050.53.7 by Andrew Bennetts
Move new test to bb.test_tag, to avoid repeating test infrastructure.
150
    def test_merge_without_commit_does_not_propagate_tags_to_master(self):
151
        """'bzr merge' alone does not propagate tags to a master branch.
152
5050.53.10 by Andrew Bennetts
Add unit test for ignore_master=True, and improve other test comments.
153
        (If the user runs 'bzr commit', then that is when the tags from the
154
        merge are propagated.)
5050.53.7 by Andrew Bennetts
Move new test to bb.test_tag, to avoid repeating test infrastructure.
155
        """
156
        master, child = self.make_master_and_checkout()
157
        fork = self.make_fork(master)
158
        fork.tags.set_tag('new-tag', fork.last_revision())
159
        self.run_bzr(['merge', '../fork'], working_dir='child')
160
        self.assertEqual({}, master.tags.get_tag_dict())
161
5050.52.2 by Andrew Bennetts
Add failing test using run_script.
162
    def test_commit_in_heavyweight_checkout_copies_tags_to_master(self):
5050.52.4 by Andrew Bennetts
Use run_script more sparingly.
163
        master, child = self.make_master_and_checkout()
164
        fork = self.make_fork(master)
165
        fork.tags.set_tag('new-tag', fork.last_revision())
5535.3.31 by Andrew Bennetts
Cope with tags that reference missing revisions.
166
        fork.tags.set_tag('non-ancestry-tag', 'fork-0')
5535.3.42 by Andrew Bennetts
Expand a test slightly.
167
        fork.tags.set_tag('absent-tag', 'absent-rev')
5050.52.2 by Andrew Bennetts
Add failing test using run_script.
168
        script.run_script(self, """
5050.52.4 by Andrew Bennetts
Use run_script more sparingly.
169
            $ cd child
5050.52.2 by Andrew Bennetts
Add failing test using run_script.
170
            $ bzr merge ../fork
5050.52.4 by Andrew Bennetts
Use run_script more sparingly.
171
            $ bzr commit -m "Merge fork."
172
            2>Committing to: .../master/
173
            2>Committed revision 2.
5535.1.1 by Andrew Bennetts
Merge lp:bzr/2.2, resolving run_script syntax conflicts and resyncing 2.2.2's release notes.
174
            """, null_output_matches_anything=True)
5050.52.4 by Andrew Bennetts
Use run_script more sparingly.
175
        # Merge copied the tag to child and commit propagated it to master
5535.3.31 by Andrew Bennetts
Cope with tags that reference missing revisions.
176
        expected_tag_dict = {
177
            'new-tag': fork.last_revision(),
178
            'non-ancestry-tag': 'fork-0',
5535.3.42 by Andrew Bennetts
Expand a test slightly.
179
            'absent-tag': 'absent-rev',
5535.3.31 by Andrew Bennetts
Cope with tags that reference missing revisions.
180
            }
181
        self.assertEqual(expected_tag_dict, child.branch.tags.get_tag_dict())
182
        self.assertEqual(expected_tag_dict, master.tags.get_tag_dict())
183
        # Revisions not in ancestry but named in tags are present
184
        child.branch.repository.get_revision('fork-0')
185
        master.repository.get_revision('fork-0')
5050.52.2 by Andrew Bennetts
Add failing test using run_script.
186
5050.52.3 by Andrew Bennetts
Merge tags from local to master when committing in a bound branch.
187
    def test_commit_in_heavyweight_checkout_reports_tag_conflict(self):
5050.52.4 by Andrew Bennetts
Use run_script more sparingly.
188
        master, child = self.make_master_and_checkout()
189
        fork = self.make_fork(master)
190
        fork.tags.set_tag('new-tag', fork.last_revision())
191
        master_r1 = master.last_revision()
192
        master.tags.set_tag('new-tag', master_r1)
5050.52.3 by Andrew Bennetts
Merge tags from local to master when committing in a bound branch.
193
        script.run_script(self, """
5050.52.4 by Andrew Bennetts
Use run_script more sparingly.
194
            $ cd child
5050.52.3 by Andrew Bennetts
Merge tags from local to master when committing in a bound branch.
195
            $ bzr merge ../fork
5050.52.4 by Andrew Bennetts
Use run_script more sparingly.
196
            $ bzr commit -m "Merge fork."
5050.52.3 by Andrew Bennetts
Merge tags from local to master when committing in a bound branch.
197
            2>Committing to: .../master/
198
            2>Conflicting tags in bound branch:
199
            2>    new-tag
200
            2>Committed revision 2.
5535.1.1 by Andrew Bennetts
Merge lp:bzr/2.2, resolving run_script syntax conflicts and resyncing 2.2.2's release notes.
201
            """, null_output_matches_anything=True)
5050.52.4 by Andrew Bennetts
Use run_script more sparingly.
202
        # Merge copied the tag to child.  master's conflicting tag is unchanged.
203
        self.assertEqual(
204
            {'new-tag': fork.last_revision()}, child.branch.tags.get_tag_dict())
205
        self.assertEqual(
206
            {'new-tag': master_r1}, master.tags.get_tag_dict())
5050.52.3 by Andrew Bennetts
Merge tags from local to master when committing in a bound branch.
207
2220.2.24 by Martin Pool
Add tags command
208
    def test_list_tags(self):
2805.8.3 by Adeodato Simó
Show dotted revnos, and revids only with --show-ids.
209
        tree1 = self.make_branch_and_tree('branch1')
210
        tree1.commit(allow_pointless=True, message='revision 1',
2805.8.6 by Adeodato Simó
Don't sort by revno; only by time if --sort=time is passed.
211
                rev_id='revid-1', timestamp=10)
212
        tree1.commit(allow_pointless=True, message='revision 2',
213
                rev_id='revid-2', timestamp=15)
214
2805.8.3 by Adeodato Simó
Show dotted revnos, and revids only with --show-ids.
215
        b1 = tree1.branch
2805.8.6 by Adeodato Simó
Don't sort by revno; only by time if --sort=time is passed.
216
        # note how the tag for revid-1 sorts after the one for revid-2
5459.2.2 by Neil Martinsen-Burrell
redo tests to check natural sort order
217
        b1.tags.set_tag(u'tag1\u30d0', 'revid-2')
218
        b1.tags.set_tag(u'tag10\u30d0', 'missing') # not present in repository
219
        b1.tags.set_tag(u'tag2\u30d0', 'revid-1')
220
221
        # natural order
222
        out, err = self.run_bzr('tags -d branch1',
223
                                encoding='utf-8')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
224
        self.assertEqual(err, '')
5459.2.2 by Neil Martinsen-Burrell
redo tests to check natural sort order
225
        self.assertContainsRe(out, (u'^tag1\u30d0  *2\ntag2\u30d0  *1\n' +
226
            u'tag10\u30d0 *\\?\n').encode('utf-8'))
2805.8.6 by Adeodato Simó
Don't sort by revno; only by time if --sort=time is passed.
227
228
        # lexicographical order
5459.2.2 by Neil Martinsen-Burrell
redo tests to check natural sort order
229
        out, err = self.run_bzr('tags --sort=alpha -d branch1',
230
                                encoding='utf-8')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
231
        self.assertEqual(err, '')
5459.2.2 by Neil Martinsen-Burrell
redo tests to check natural sort order
232
        self.assertContainsRe(out, (u'^tag10\u30d0  *\\?\ntag1\u30d0  *2\n' +
233
            u'tag2\u30d0 *1\n').encode('utf-8'))
2805.8.6 by Adeodato Simó
Don't sort by revno; only by time if --sort=time is passed.
234
5459.2.2 by Neil Martinsen-Burrell
redo tests to check natural sort order
235
        out, err = self.run_bzr('tags --sort=alpha --show-ids -d branch1',
236
                                encoding='utf-8')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
237
        self.assertEqual(err, '')
5459.2.2 by Neil Martinsen-Burrell
redo tests to check natural sort order
238
        self.assertContainsRe(out, (u'^tag10\u30d0  *missing\n' +
239
            u'tag1\u30d0  *revid-2\ntag2\u30d0 *revid-1\n').encode('utf-8'))
2805.8.6 by Adeodato Simó
Don't sort by revno; only by time if --sort=time is passed.
240
241
        # chronological order
242
        out, err = self.run_bzr('tags --sort=time -d branch1',
243
                encoding='utf-8')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
244
        self.assertEqual(err, '')
5459.2.2 by Neil Martinsen-Burrell
redo tests to check natural sort order
245
        self.assertContainsRe(out, (u'^tag2\u30d0  *1\ntag1\u30d0  *2\n' +
246
            u'tag10\u30d0 *\\?\n').encode('utf-8'))
2805.8.6 by Adeodato Simó
Don't sort by revno; only by time if --sort=time is passed.
247
248
        out, err = self.run_bzr('tags --sort=time --show-ids -d branch1',
249
                encoding='utf-8')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
250
        self.assertEqual(err, '')
5459.2.2 by Neil Martinsen-Burrell
redo tests to check natural sort order
251
        self.assertContainsRe(out, (u'^tag2\u30d0  *revid-1\n' +
252
            u'tag1\u30d0  *revid-2\ntag10\u30d0 *missing\n').encode('utf-8'))
2805.8.3 by Adeodato Simó
Show dotted revnos, and revids only with --show-ids.
253
254
        # now test dotted revnos
255
        tree2 = tree1.bzrdir.sprout('branch2').open_workingtree()
2805.8.6 by Adeodato Simó
Don't sort by revno; only by time if --sort=time is passed.
256
        tree1.commit(allow_pointless=True, message='revision 3 in branch1',
257
                rev_id='revid-3a')
258
        tree2.commit(allow_pointless=True, message='revision 3 in branch2',
259
                rev_id='revid-3b')
260
2805.8.3 by Adeodato Simó
Show dotted revnos, and revids only with --show-ids.
261
        b2 = tree2.branch
2805.8.6 by Adeodato Simó
Don't sort by revno; only by time if --sort=time is passed.
262
        b2.tags.set_tag('tagD', 'revid-3b')
2805.8.3 by Adeodato Simó
Show dotted revnos, and revids only with --show-ids.
263
        self.run_bzr('merge -d branch1 branch2')
2805.8.6 by Adeodato Simó
Don't sort by revno; only by time if --sort=time is passed.
264
        tree1.commit('merge', rev_id='revid-4')
265
2805.8.3 by Adeodato Simó
Show dotted revnos, and revids only with --show-ids.
266
        out, err = self.run_bzr('tags -d branch1', encoding='utf-8')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
267
        self.assertEqual(err, '')
2805.8.6 by Adeodato Simó
Don't sort by revno; only by time if --sort=time is passed.
268
        self.assertContainsRe(out, r'tagD  *2\.1\.1\n')
2805.8.3 by Adeodato Simó
Show dotted revnos, and revids only with --show-ids.
269
        out, err = self.run_bzr('tags -d branch2', encoding='utf-8')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
270
        self.assertEqual(err, '')
2805.8.6 by Adeodato Simó
Don't sort by revno; only by time if --sort=time is passed.
271
        self.assertContainsRe(out, r'tagD  *3\n')
2220.2.24 by Martin Pool
Add tags command
272
6165.3.1 by Jelmer Vernooij
Support running 'bzr tags' against remote repositories without revision graph access.
273
    def test_list_tags_dotted_revnos_unsupported(self):
274
        tree = self.make_branch_and_tree('branch')
275
        rev1 = tree.commit("rev1")
276
        tree.branch.tags.set_tag("mytag", rev1)
277
        def revision_id_to_dotted_revno(self, revid):
278
            raise errors.UnsupportedOperation(revision_id_to_dotted_revno, self)
279
        self.overrideAttr(Branch, "revision_id_to_dotted_revno",
280
            revision_id_to_dotted_revno)
281
        out, err = self.run_bzr('tags -d branch', encoding='utf-8')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
282
        self.assertEqual(out, 'mytag                ?\n')
6165.3.1 by Jelmer Vernooij
Support running 'bzr tags' against remote repositories without revision graph access.
283
3904.2.2 by Marius Kruger
add test_list_tags_revision_filtering
284
    def test_list_tags_revision_filtering(self):
285
        tree1 = self.make_branch_and_tree('.')
286
        tree1.commit(allow_pointless=True, message='revision 1',
287
                rev_id='revid-1')
288
        tree1.commit(allow_pointless=True, message='revision 2',
289
                rev_id='revid-2')
290
        tree1.commit(allow_pointless=True, message='revision 3',
291
                rev_id='revid-3')
292
        tree1.commit(allow_pointless=True, message='revision 4',
293
                rev_id='revid-4')
294
        b1 = tree1.branch
295
        b1.tags.set_tag(u'tag 1', 'revid-1')
296
        b1.tags.set_tag(u'tag 2', 'revid-2')
297
        b1.tags.set_tag(u'tag 3', 'revid-3')
298
        b1.tags.set_tag(u'tag 4', 'revid-4')
299
        self._check_tag_filter('', (1, 2, 3, 4))
300
        self._check_tag_filter('-r ..', (1, 2, 3, 4))
301
        self._check_tag_filter('-r ..2', (1, 2))
302
        self._check_tag_filter('-r 2..', (2, 3, 4))
303
        self._check_tag_filter('-r 2..3', (2, 3))
304
        self._check_tag_filter('-r 3..2', ())
305
        self.run_bzr_error(args="tags -r 123",
5105.1.4 by Vincent Ladeuil
Use single quotes so that no test need to be updated.
306
            error_regexes=["bzr: ERROR: Requested revision: '123' "
3904.2.2 by Marius Kruger
add test_list_tags_revision_filtering
307
                "does not exist in branch:"])
308
        self.run_bzr_error(args="tags -r ..123",
5105.1.4 by Vincent Ladeuil
Use single quotes so that no test need to be updated.
309
            error_regexes=["bzr: ERROR: Requested revision: '123' "
3904.2.2 by Marius Kruger
add test_list_tags_revision_filtering
310
                "does not exist in branch:"])
311
        self.run_bzr_error(args="tags -r 123.123",
5105.1.4 by Vincent Ladeuil
Use single quotes so that no test need to be updated.
312
            error_regexes=["bzr: ERROR: Requested revision: '123.123' "
3904.2.2 by Marius Kruger
add test_list_tags_revision_filtering
313
                "does not exist in branch:"])
314
5582.2.1 by Jelmer Vernooij
support extending --sort argument to 'bzr tags'.
315
    def test_sort_tags_custom(self):
316
        def sort_by_dots(branch, tags):
317
            def sort_key((tag, revid)):
318
                return tag.count(".")
319
            tags.sort(key=sort_key)
320
321
        # Register a custom sort method
322
        tag.tag_sort_methods.register("dots", sort_by_dots, "Sort by dots.")
323
        self.addCleanup(tag.tag_sort_methods.remove, "dots")
324
325
        tree1 = self.make_branch_and_tree('branch1')
326
        tree1.commit(allow_pointless=True, message='revision 1',
327
                rev_id='revid-1', timestamp=10)
328
        tree1.commit(allow_pointless=True, message='revision 2',
329
                rev_id='revid-2', timestamp=15)
330
331
        b1 = tree1.branch
332
333
        b1.tags.set_tag(u'tag..', 'revid-2')
334
        b1.tags.set_tag(u'tag....', 'missing') # not present in repository
335
        b1.tags.set_tag(u'tag.', 'revid-1')
336
        b1.tags.set_tag(u'tag...', 'revid-1')
337
        b1.tags.set_tag(u'tag....', 'revid-1')
338
339
        # sorted by number of dots
340
        out, err = self.run_bzr('tags --sort=dots -d branch1')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
341
        self.assertEqual(err, '')
342
        self.assertEqual([
5582.2.1 by Jelmer Vernooij
support extending --sort argument to 'bzr tags'.
343
            'tag.                 1',
344
            'tag..                2',
345
            'tag...               1',
346
            'tag....              1'],
347
            out.splitlines())
348
3904.2.2 by Marius Kruger
add test_list_tags_revision_filtering
349
    def _check_tag_filter(self, argstr, expected_revnos):
350
        #upper bound of laziness
351
        out, err = self.run_bzr('tags ' + argstr)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
352
        self.assertEqual(err, '')
3904.2.2 by Marius Kruger
add test_list_tags_revision_filtering
353
        self.assertContainsRe(out, "^" + ''.join(["tag %s +%s\n" % (
354
            revno, revno) for revno in expected_revnos]) + "$")
355
2220.2.37 by Martin Pool
Report conflicting tags from push.
356
    def test_conflicting_tags(self):
2220.2.39 by Martin Pool
Pull also merges tags and warns if they conflict
357
        # setup two empty branches with different tags
2220.2.37 by Martin Pool
Report conflicting tags from push.
358
        t1 = self.make_branch_and_tree('one')
359
        t2 = self.make_branch_and_tree('two')
360
        b1 = t1.branch
361
        b2 = t2.branch
362
        tagname = u'\u30d0zaar'
363
        b1.tags.set_tag(tagname, 'revid1')
364
        b2.tags.set_tag(tagname, 'revid2')
2220.2.39 by Martin Pool
Pull also merges tags and warns if they conflict
365
        # push should give a warning about the tags
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
366
        out, err = self.run_bzr('push -d one two', encoding='utf-8')
2220.2.37 by Martin Pool
Report conflicting tags from push.
367
        self.assertContainsRe(out,
368
                'Conflicting tags:\n.*' + tagname.encode('utf-8'))
2220.2.39 by Martin Pool
Pull also merges tags and warns if they conflict
369
        # pull should give a warning about the tags
5616.6.3 by Jelmer Vernooij
Fix test.
370
        out, err = self.run_bzr('pull -d one two', encoding='utf-8',
371
            retcode=1)
2220.2.39 by Martin Pool
Pull also merges tags and warns if they conflict
372
        self.assertContainsRe(out,
373
                'Conflicting tags:\n.*' + tagname.encode('utf-8'))
2220.2.40 by Martin Pool
stubbed-out tests
374
        # merge should give a warning about the tags -- not implemented yet
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
375
        ## out, err = self.run_bzr('merge -d one two', encoding='utf-8')
2220.2.40 by Martin Pool
stubbed-out tests
376
        ## self.assertContainsRe(out,
377
        ##         'Conflicting tags:\n.*' + tagname.encode('utf-8'))
5459.7.1 by Neil Martinsen-Burrell
make "bzr tag --quiet" really quiet
378
379
    def test_tag_quiet(self):
5459.7.2 by Neil Martinsen-Burrell
test empty output directly
380
        t1 = self.make_branch_and_tree('')
381
        out, err = self.run_bzr('tag --quiet test1')
382
        self.assertEqual('', out)
383
        self.assertEqual('', err)
5459.7.1 by Neil Martinsen-Burrell
make "bzr tag --quiet" really quiet
384
385
    def test_tag_delete_quiet(self):
5459.7.2 by Neil Martinsen-Burrell
test empty output directly
386
        t1 = self.make_branch_and_tree('')
387
        self.run_bzr('tag test1')
388
        out, err = self.run_bzr('tag --delete --quiet test1')
389
        self.assertEqual('', out)
390
        self.assertEqual('', err)
391
5689.2.2 by Jelmer Vernooij
Fix the use of "bzr tags" in branches with ghosts in their mainline /and/ tags on revisions not in the branch ancestry.
392
    def test_tags_with_mainline_ghosts(self):
393
        tree = self.make_branch_and_tree('tree1')
394
        tree.set_parent_ids(["spooky"], allow_leftmost_as_ghost=True)
395
        tree.add('')
396
        tree.commit('msg1', rev_id='rev1')
397
        tree.commit('msg2', rev_id='rev2')
398
        tree.branch.tags.set_tag('unknown', 'out-of-mainline')
399
        tree.branch.tags.set_tag('ghost', 'spooky')
400
        tree.branch.tags.set_tag('tag1', 'rev1')
401
        tree.branch.tags.set_tag('tag2', 'rev2')
402
403
        out, err = self.run_bzr('tags -d tree1', encoding='utf-8')
404
        self.assertEqual(out,
405
            'ghost                ?\n'
406
            'tag1                 1\n'
407
            'tag2                 2\n'
408
            'unknown              ?\n')
409
        self.assertEqual('', err)
6283.1.11 by Jelmer Vernooij
Add hpss call count test for 'bzr tags' and 'bzr tag'.
410
411
412
class TestSmartServerCat(TestCaseWithTransport):
413
414
    def test_set_tag(self):
415
        self.setup_smart_server_with_call_log()
416
        t = self.make_branch_and_tree('branch')
417
        self.build_tree_contents([('branch/foo', 'thecontents')])
418
        t.add("foo")
419
        t.commit("message")
420
        self.reset_smart_call_log()
421
        out, err = self.run_bzr(['tag', "-d", self.get_url('branch'), "tagname"])
422
        # This figure represent the amount of work to perform this use case. It
423
        # is entirely ok to reduce this number if a test fails due to rpc_count
424
        # being too low. If rpc_count increases, more network roundtrips have
425
        # become necessary for this use case. Please do not adjust this number
426
        # upwards without agreement from bzr's network support maintainers.
427
        self.assertLength(9, self.hpss_calls)
6366.1.4 by Jelmer Vernooij
Test connection count calls for most blackbox commands.
428
        self.assertLength(1, self.hpss_connections)
6352.2.3 by Jelmer Vernooij
s/NoVfsCalls/ContainsNoVfsCalls/.
429
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
6283.1.11 by Jelmer Vernooij
Add hpss call count test for 'bzr tags' and 'bzr tag'.
430
431
    def test_show_tags(self):
432
        self.setup_smart_server_with_call_log()
433
        t = self.make_branch_and_tree('branch')
434
        self.build_tree_contents([('branch/foo', 'thecontents')])
435
        t.add("foo")
436
        t.commit("message")
437
        t.branch.tags.set_tag("sometag", "rev1")
438
        t.branch.tags.set_tag("sometag", "rev2")
439
        self.reset_smart_call_log()
440
        out, err = self.run_bzr(['tags', "-d", self.get_url('branch')])
441
        # This figure represent the amount of work to perform this use case. It
442
        # is entirely ok to reduce this number if a test fails due to rpc_count
443
        # being too low. If rpc_count increases, more network roundtrips have
444
        # become necessary for this use case. Please do not adjust this number
445
        # upwards without agreement from bzr's network support maintainers.
6263.1.8 by Jelmer Vernooij
Merge bzr.dev, fix hpss call counts.
446
        self.assertLength(6, self.hpss_calls)
6366.1.4 by Jelmer Vernooij
Test connection count calls for most blackbox commands.
447
        self.assertLength(1, self.hpss_connections)
6352.2.3 by Jelmer Vernooij
s/NoVfsCalls/ContainsNoVfsCalls/.
448
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)