Re-using a working tree

Very often, it can be useful to re-use a working tree to work on multiple branches.

  • If the working tree is very large, it can be a waste of disk space and difficult to have multiple working trees at the same time
  • If the project requires complicated configuration per working tree, then it can be troublesome and inefficient to repeat the setup procedure for every branch

Re-using a working tree is a matter of organizing your local branches in a certain way:

  • Configure a shared repository to not create working trees by default
  • Create only a single branch with a working tree, in other words a checkout, keeping all other branches tree-less
  • Switch the associated branch of the checkout by using bzr bind followed by bzr update and bzr revert, or by using bzr switch
  • Use a lightweight checkout for the working tree for extra safety

Setting up the example

Let's create a shared repository with no working trees by default:

$ bzr init-repo /sandbox/reusing --no-trees
Shared repository (format: 2a)
Location:
  shared repository: /sandbox/reusing

Let's create a few sample branches:

$ cd /sandbox/reusing/
$ bzr branch lp:~bzrbook/bzrbook-examples/common-two-features trunk
Branched 3 revisions.
$ bzr branch -r1.2.3 trunk/ feature1
Branched 4 revisions.                                                                                                  
$ bzr branch -r1.1.2 trunk/ bug1
Branched 3 revisions.  

Since the shared repository is configured to create no trees, we can confirm that all these branches have no working trees:

$ ls *
bug1:

feature1:

trunk:

Finally, we need to create a checkout with a working tree that we will use to switch between branches and perform version control operations:

$ bzr checkout trunk/ work 

As we can confirm, a checkout always has a working tree:

$ ls work/                       
hello.py    hello.rb    hello.sh    screenshots todo.txt

Preparing to switch branches

There is one very important precaution to take before switching branches—make sure you don't have uncommitted changes in the working tree. As the whole point of switching branches is overwriting the working tree, you should make sure to commit all the important changes before going ahead with the switch. Although the methods explained here do not destroy the uncommitted changes by default, they can get mingled with other changes in the process, making them extremely difficult to recover. A wise thing to do is to commit all the pending changes before switching branches.

Switching to another branch using core commands

The working tree we created is currently bound to the trunk:

$ cd work 
$ bzr info
Repository checkout (format: 2a)
Location:
  repository checkout root: .
        checkout of branch: /sandbox/reusing/trunk
         shared repository: /sandbox/reusing

We can switch to another branch by using bzr bind followed by bzr update, followed by bzr revert:

$ bzr bind ../bug1/
$ bzr info
Repository checkout (format: 2a)
Location:
  repository checkout root: .
        checkout of branch: /sandbox/reusing/bug1
         shared repository: /sandbox/reusing

There is no output after bzr bind, because the command doesn't change the working tree. When binding to a new location, the working tree must be updated by using bzr update to synchronize it with the repository.

$ bzr update
All changes applied successfully.                                                                                      
Updated to revision 3 of branch /sandbox/reusing/bug1
Your local commits will now show as pending merges with 'bzr status', and can be committed with 'bzr commit'.

The way update works is, if the original branch contains revisions that are not in the new target branch, then those revisions will be treated as local commits.

If there had been "real" local commits before this step, they would still be local commits, naturally following the regular commits that have been converted to local commits. However, notice the danger here—these real local commits exist only in this branch; by definition, they have not been committed in other branches. The next step in completing the switch is bzr revert, which will erase these local commits. In a realistic situation, you should not have any local commits when switching between branches, as that would risk losing work.

In our example, we are not working on local commits; we simply want to switch our working tree to another branch. So, at this point, we want to move these changes out of the way with bzr revert:

$ bzr revert
-   hello.rb                                                                                                           
 M  todo.txt
$ bzr status                                                                                                             
unknown:
  hello.rb

Although there is an unknown file left behind, because it existed in the previous branch, this is not a problem. In any case, we should move it out of the way, otherwise it might lead to conflicts when we switch to another branch later. We can remove the file manually, or by using the bzr clean-tree command:

$ bzr clean-tree
hello.rb
Are you sure you wish to delete these? ([y]es, [n]o): yes
deleting paths:
  hello.rb

As usual, Bazaar does not make irreversible changes without asking for confirmation. To skip the confirmation, you can use the --force flag.

With this last move, we have successfully switched the working tree to another branch.

Switching to another branch by using switch

The switch command is not a core feature, but is included in the loom plugin. It makes switching between branches much easier:

$ bzr info
Repository checkout (format: 2a)
Location:
  repository checkout root: .
        checkout of branch: /sandbox/reusing/trunk
         shared repository: /sandbox/reusing

$ bzr switch ../feature1/
Updated to revision 4.                                                                                                 
Switched to branch: /sandbox/reusing/feature1/
$ bzr info
Repository checkout (format: 2a)
Location:
  repository checkout root: .
        checkout of branch: /sandbox/reusing/feature1
         shared repository: /sandbox/reusing

The switch command hides most of the details involved in the process of switching branches.

An interesting difference from using the bind-update-revert method is that bzr switch will refuse to run if there are local commits in the branch. This is a good thing, because it is potentially unsafe to switch branches when there are local commits, as those commits would get lost. To switch anyway throwing away local commits, use the --force flag.

A very useful feature of the switch command is to create a new branch from the current one and switch to it immediately by using the -b or --create-branch option. For example:

$ bzr switch -b ../feature2
Tree is up to date at revision 3.                                                                                      
Switched to branch: /sandbox/reusing/feature2/

Using a lightweight checkout for switching branches

When using a shared repository, it may seem pointless at first to use a lightweight checkout locally—branches are already very cheap, as the revisions are not stored directly inside the branches but in the shared repository. Whether a checkout is lightweight or not, it makes no difference in terms of disk space, and since we are performing branch operations locally, there is also no network latency.

However, there is still a benefit of using a lightweight checkout instead of a regular one—by definition there cannot be local commits. Considering that you may inadvertently delete important local commits, there exists some amount of risk when using regular checkouts. By using lightweight checkouts, you can effectively eliminate this risk when switching branches.

You can convert your working tree by using bzr reconfigure. For example:

$ bzr reconfigure --lightweight-checkout
$ bzr info
Lightweight checkout (format: 2a)
Location:
  light checkout root: .
   checkout of branch: /sandbox/reusing/feature2
    shared repository: /sandbox/reusing
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.136.186