Launchpad Entry: https://launchpad.net/products/bazaar/+spec/lockstep-development
Created: 2005-11-04 by RobertCollins
In organisations, one often wants to run a 'mainline' where everyone that is able to commit to from their local workstations. When one user commits to this mainline, all other users need to perform a 'pull' like operation before they can perform a commit themselves.
- Fred commits a change to the shared 'Seeds' branch. Charlie also has prepared a change and tries to commit. Because of Fred's change, Charlie receives an error:
Cannot commit - you are out of date with the respository (you are at revision 100, the repository is at 102).Charlie must perform a pull and potentially resolve conflicts, before she can commit.
Note that this is independent of which files where changed in the commits, it only looks at the revisions in the repository.
Fred has a checkout of a LockStepDevelopment shared branch.
Fred creates a branch from from this checkout: bzr branch ~/checkout newbranch
- This new branch is not a lock step branch.
- Fred develops on newbranch until he is happy with his feature.
A 'bzr merge' in newbranch will merge from ~/checkout.
When Fred is happy with newbranch, he cds to ~/checkout.
Fred does a bzr merge ../newbranch and then attempts to commit.
- This commit fails because Charlie has commited a widespread Makefile syntax change.
Fred tries a bzr pull which then conflicts hugely.
- Fred resolves the conflicts, and then commits his new feature.
Fred has a checkout of a LockStepDevelopment shared branch onto his laptop. Fred then goes onto a train, where he has no network access. Fred makes changes to the local tree, and attempts to commit. Two possibilities present themselves:
- The commit fails, telling Fred
Unable to connect to shared branch at sftp://shared-foo.com/ Host unreachable. Use bzr unbind to commit locally.Note: the specific text needs to be clarified.
Fred then runs bzr unbind, and is able to commit. His local checkout is now out of sync with the shared branch. When Fred gets into the office, 3 hours later, he again has network access.
Fred then runs bzr bind to change his local checkout, back into a LockStepDevelopment branch. bzr remembers the url that the checkout used to be bound to, and attempts to rebind. If the shared branch has not been updated, Fred's changes are pushed to the shared branch, and the binding is complete. If the shared branch has been updated, the bind fails, telling Fred that the branches have diverged, he must resolve this with bzr merge. After running bzr merge against the shared branch, the local checkout is updated as usual. After resolving any conflicts, Fred can commit the merge, producing a revision which is a decendent of the shared branch tip. At this point (with no other changes), bzr bind will succeed, rewriting the local revision-history to be identical to the shared branch.
- During the commit, bzr recognizes that it is unable to connect to the shared branch. It makes a local commit. The next operation that would normally connect to the shared branch (commit, bind, pull), will attempt to reconcile the current status. If there have been no changes on the shared branch, then the changes should be simply pushed to the remote branch, and the action can proceed as normal. If branches have diverged, the action should fail, and request the user resolve the problem.
- The commit fails, telling Fred
When branch B2 is bound to B1, B2's revision history is always a prefix of B1.
To preserve this, when a commit is made in B2, the same revision must be inserted in both branches.
It is not allowed to have cycles of bound branches.
When a branch is bound to another, their revision histories remain exactly the same. To preserve this, commits made in B2 must create a revision that is inserted into both B2 and B1. It is only possible to form such a revision if B1 and B2 are on the same revision. If there is any divergence, the user is asked to merge instead.
B2 can be unbound from B1 at any time. This is done manually through a 'bzr unbind' command. It might be useful to reliably detect when a remote repository is unreachable and then unbind, but I doubt it can be done reliably and it should probably be off by default.
Binding B2 to B1 requires that the last revision in B2 must be merged into B1. The revision history of B2 is replaced by that of B1.
- Setting policy for branches - are 'lockstep branches'. Do we need a policy.
Questions and Answers
- Should it be possible to bind to a bound branch? It should not be possible to commit in this circumstance. However if you are wanting to follow an upstream, and are using the binding to help enforce it, you may not have control over the upstream branch.
RobertCollins -- I dont see any harm in allowing binding to occur, and pulling, as long as we make it clear that they will not be able to commit.
Should the bind target always be parent, or should it be possible to bind to a different branch. It seems possible that one might want to have parent be the real upstream, while the bound target is just their local public archive. However, it means that bzr pull would be more complicated, since you would not be pulling from the bound location, requiring the changes to be made in both. But since we would still support pull with any other location, we would have to deal with this anyway. Another point: If you unbind you would lose the bound target, but you wouldn't lose the parent location. So if you did not have a separate location to bind against, bzr unbind; bzr bind would be a no-op. RobertCollins -- Always the parent I think. We do have access to parent->parent to follow chains of parents, and, I think that the bound branch must be the one that 'pull' uses, for the sanity of users.
Should the bzr bind command automatically update the local tree. You can always pull to bring the local tree up-to-date. But because you won't be able to commit until the pull is done, it might be nice. Perhaps updating should be the default, with a --no-update command, indicating you will update later. RobertCollins -- After a bind, they should be synchronised.