Merge lp:~abentley/bzr/branches-uncommitted into lp:bzr

Proposed by Aaron Bentley on 2013-05-08
Status: Needs review
Proposed branch: lp:~abentley/bzr/branches-uncommitted
Merge into: lp:bzr
Diff against target: 198 lines (+69/-15)
5 files modified
bzrlib/branch.py (+12/-1)
bzrlib/builtins.py (+7/-4)
bzrlib/remote.py (+4/-0)
bzrlib/tests/blackbox/test_branches.py (+37/-10)
bzrlib/tests/per_branch/test_branch.py (+9/-0)
To merge this branch: bzr merge lp:~abentley/bzr/branches-uncommitted
Reviewer Review Type Date Requested Status
John A Meinel Approve on 2013-05-09
Richard Wilbur 2013-05-08 Approve on 2013-05-08
Review via email: mp+162925@code.launchpad.net

Commit message

Show uncommitted changes in branches.

Description of the change

This branch enables showing uncommitted changes for colocated branches, similar to the display in the 'pipeline' plugin. Uncommitted changes in branches are created with switch --store, and are a good reminder of which branches are works-in-progress.

Branch.has_uncommitted is implemented because the other way of determining uncommitted changes is convoluted: call get_unshelver, providing a tree, and see whether it returns None.

To post a comment you must log in.
Richard Wilbur (richard-wilbur) wrote :

Looks like a very good thing to have. Thanks for implementing it the less convoluted way.
+1

review: Approve
John A Meinel (jameinel) wrote :

69 + prefix += 'U' if uncommitted else ' '

Given the line just before this is:

if active:
  prefix =
else:
  prefix =

I would probably follow suite here. (or change the other one to be consistent).

Otherwise seems good.

review: Approve

Unmerged revisions

6578. By Aaron Bentley on 2013-05-07

Add tests for branches command.

6577. By Aaron Bentley on 2013-05-05

Test has_uncommitted, add RemoteBranch implementation.

6576. By Aaron Bentley on 2013-05-05

Indent default branch the same as other branches.

6575. By Aaron Bentley on 2013-05-05

Fix failing tests.

6574. By Aaron Bentley on 2013-05-05

List uncommitted branches.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'bzrlib/branch.py'
--- bzrlib/branch.py 2012-07-19 18:28:25 +0000
+++ bzrlib/branch.py 2013-05-08 04:37:28 +0000
@@ -261,6 +261,9 @@
261 """261 """
262 raise NotImplementedError(self.store_uncommitted)262 raise NotImplementedError(self.store_uncommitted)
263263
264 def has_uncommitted(self):
265 return False
266
264 def get_unshelver(self, tree):267 def get_unshelver(self, tree):
265 """Return a shelf.Unshelver for this branch and tree.268 """Return a shelf.Unshelver for this branch and tree.
266269
@@ -2412,6 +2415,10 @@
2412 else:2415 else:
2413 return self2416 return self
24142417
2418 @staticmethod
2419 def _has_uncommitted(branch):
2420 return branch._transport.has('stored-transform')
2421
2415 def store_uncommitted(self, creator):2422 def store_uncommitted(self, creator):
2416 """Store uncommitted changes from a ShelfCreator.2423 """Store uncommitted changes from a ShelfCreator.
24172424
@@ -2423,13 +2430,17 @@
2423 if creator is None:2430 if creator is None:
2424 branch._transport.delete('stored-transform')2431 branch._transport.delete('stored-transform')
2425 return2432 return
2426 if branch._transport.has('stored-transform'):2433 if self._has_uncommitted(branch):
2427 raise errors.ChangesAlreadyStored2434 raise errors.ChangesAlreadyStored
2428 transform = StringIO()2435 transform = StringIO()
2429 creator.write_shelf(transform)2436 creator.write_shelf(transform)
2430 transform.seek(0)2437 transform.seek(0)
2431 branch._transport.put_file('stored-transform', transform)2438 branch._transport.put_file('stored-transform', transform)
24322439
2440 def has_uncommitted(self):
2441 branch = self._uncommitted_branch()
2442 return self._has_uncommitted(branch)
2443
2433 def get_unshelver(self, tree):2444 def get_unshelver(self, tree):
2434 """Return a shelf.Unshelver for this branch and tree.2445 """Return a shelf.Unshelver for this branch and tree.
24352446
24362447
=== modified file 'bzrlib/builtins.py'
--- bzrlib/builtins.py 2012-09-27 17:41:19 +0000
+++ bzrlib/builtins.py 2013-05-08 04:37:28 +0000
@@ -1578,17 +1578,20 @@
1578 continue1578 continue
1579 active = (active_branch is not None and1579 active = (active_branch is not None and
1580 active_branch.base == branch.base)1580 active_branch.base == branch.base)
1581 names[name] = active1581 names[name] = active, branch.has_uncommitted()
1582 branch_list = sorted(names.items())
1582 # Only mention the current branch explicitly if it's not1583 # Only mention the current branch explicitly if it's not
1583 # one of the colocated branches1584 # one of the colocated branches
1584 if not any(names.values()) and active_branch is not None:1585 if not any(names.values()) and active_branch is not None:
1585 self.outf.write("* %s\n" % gettext("(default)"))1586 branch_list.insert(0,
1586 for name in sorted(names.keys()):1587 (gettext("(default)"),
1587 active = names[name]1588 (True, active_branch.has_uncommitted())))
1589 for name, (active, uncommitted) in branch_list:
1588 if active:1590 if active:
1589 prefix = "*"1591 prefix = "*"
1590 else:1592 else:
1591 prefix = " "1593 prefix = " "
1594 prefix += 'U' if uncommitted else ' '
1592 self.outf.write("%s %s\n" % (1595 self.outf.write("%s %s\n" % (
1593 prefix, name.encode(self.outf.encoding)))1596 prefix, name.encode(self.outf.encoding)))
15941597
15951598
=== modified file 'bzrlib/remote.py'
--- bzrlib/remote.py 2012-09-19 07:58:27 +0000
+++ bzrlib/remote.py 2013-05-08 04:37:28 +0000
@@ -3403,6 +3403,10 @@
3403 self._ensure_real()3403 self._ensure_real()
3404 return self._real_branch.store_uncommitted(creator)3404 return self._real_branch.store_uncommitted(creator)
34053405
3406 def has_uncommitted(self):
3407 self._ensure_real()
3408 return self._real_branch.has_uncommitted()
3409
3406 def get_unshelver(self, tree):3410 def get_unshelver(self, tree):
3407 self._ensure_real()3411 self._ensure_real()
3408 return self._real_branch.get_unshelver(tree)3412 return self._real_branch.get_unshelver(tree)
34093413
=== modified file 'bzrlib/tests/blackbox/test_branches.py'
--- bzrlib/tests/blackbox/test_branches.py 2012-02-13 17:34:46 +0000
+++ bzrlib/tests/blackbox/test_branches.py 2013-05-08 04:37:28 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2011 Canonical Ltd1# Copyright (C) 2011-2013 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# 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 by4# it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
1919
20from bzrlib.bzrdir import BzrDir20from bzrlib.bzrdir import BzrDir
21from bzrlib.tests import TestCaseWithTransport21from bzrlib.tests import TestCaseWithTransport
22from bzrlib.tests.per_branch.test_branch import FakeShelfCreator
2223
2324
24class TestBranches(TestCaseWithTransport):25class TestBranches(TestCaseWithTransport):
@@ -28,7 +29,7 @@
28 # support.29 # support.
29 self.run_bzr('init a')30 self.run_bzr('init a')
30 out, err = self.run_bzr('branches a')31 out, err = self.run_bzr('branches a')
31 self.assertEquals(out, "* (default)\n")32 self.assertEquals(out, "* (default)\n")
3233
33 def test_no_branch(self):34 def test_no_branch(self):
34 # Listing the branches in a control directory without branches.35 # Listing the branches in a control directory without branches.
@@ -65,9 +66,9 @@
65 t.bzrdir.create_branch(name='another')66 t.bzrdir.create_branch(name='another')
66 t.bzrdir.create_branch(name='colocated')67 t.bzrdir.create_branch(name='colocated')
67 out, err = self.run_bzr('branches a')68 out, err = self.run_bzr('branches a')
68 self.assertEquals(out, "* (default)\n"69 self.assertEquals(out, "* (default)\n"
69 " another\n"70 " another\n"
70 " colocated\n")71 " colocated\n")
7172
72 def test_indicates_branch(self):73 def test_indicates_branch(self):
73 t = self.make_repository('a', format='development-colo')74 t = self.make_repository('a', format='development-colo')
@@ -75,8 +76,18 @@
75 branch = t.bzrdir.create_branch(name='colocated')76 branch = t.bzrdir.create_branch(name='colocated')
76 t.bzrdir.set_branch_reference(target_branch=branch)77 t.bzrdir.set_branch_reference(target_branch=branch)
77 out, err = self.run_bzr('branches a')78 out, err = self.run_bzr('branches a')
78 self.assertEquals(out, " another\n"79 self.assertEquals(out, " another\n"
79 "* colocated\n")80 "* colocated\n")
81
82 def test_indicates_uncommitted(self):
83 t = self.make_repository('a', format='development-colo')
84 t.bzrdir.create_branch(name='another')
85 branch = t.bzrdir.create_branch(name='colocated')
86 branch.store_uncommitted(FakeShelfCreator(branch))
87 t.bzrdir.set_branch_reference(target_branch=branch)
88 out, err = self.run_bzr('branches a')
89 self.assertEquals(out, " another\n"
90 "*U colocated\n")
8091
81 def test_shared_repos(self):92 def test_shared_repos(self):
82 self.make_repository('a', shared=True)93 self.make_repository('a', shared=True)
@@ -84,10 +95,26 @@
84 b = BzrDir.create_branch_convenience('a/branch2')95 b = BzrDir.create_branch_convenience('a/branch2')
85 b.create_checkout(lightweight=True, to_location='b')96 b.create_checkout(lightweight=True, to_location='b')
86 out, err = self.run_bzr('branches b')97 out, err = self.run_bzr('branches b')
87 self.assertEquals(out, " branch1\n"98 self.assertEquals(out, " branch1\n"
88 "* branch2\n")99 "* branch2\n")
100
101 def test_shared_repos_uncommitted(self):
102 self.make_repository('a', shared=True)
103 BzrDir.create_branch_convenience('a/branch1')
104 b = BzrDir.create_branch_convenience('a/branch2')
105 b.create_checkout(lightweight=True, to_location='b')
106 b.store_uncommitted(FakeShelfCreator(b))
107 out, err = self.run_bzr('branches b')
108 self.assertEquals(out, " branch1\n"
109 "*U branch2\n")
89110
90 def test_standalone_branch(self):111 def test_standalone_branch(self):
91 self.make_branch('a')112 self.make_branch('a')
92 out, err = self.run_bzr('branches a')113 out, err = self.run_bzr('branches a')
93 self.assertEquals(out, "* (default)\n")114 self.assertEquals(out, "* (default)\n")
115
116 def test_standalone_branch_uncommitted(self):
117 b = self.make_branch('a')
118 b.store_uncommitted(FakeShelfCreator(b))
119 out, err = self.run_bzr('branches a')
120 self.assertEquals(out, "*U (default)\n")
94121
=== modified file 'bzrlib/tests/per_branch/test_branch.py'
--- bzrlib/tests/per_branch/test_branch.py 2012-07-19 19:27:22 +0000
+++ bzrlib/tests/per_branch/test_branch.py 2013-05-08 04:37:28 +0000
@@ -1125,6 +1125,15 @@
1125 branch.store_uncommitted(None)1125 branch.store_uncommitted(None)
1126 self.assertIs(None, branch.get_unshelver(None))1126 self.assertIs(None, branch.get_unshelver(None))
11271127
1128 def test_has_uncommitted(self):
1129 branch = self.make_branch('b')
1130 self.assertFalse(branch.has_uncommitted())
1131 with skip_if_storing_uncommitted_unsupported():
1132 branch.store_uncommitted(FakeShelfCreator(branch))
1133 self.assertTrue(branch.has_uncommitted())
1134 branch.store_uncommitted(None)
1135 self.assertFalse(branch.has_uncommitted())
1136
1128 def test_get_unshelver(self):1137 def test_get_unshelver(self):
1129 tree = self.make_branch_and_tree('tree')1138 tree = self.make_branch_and_tree('tree')
1130 tree.commit('')1139 tree.commit('')