Branches without working trees

John A Meinel john at arbash-meinel.com
Sun Oct 30 17:51:51 GMT 2005


Robert Collins wrote:
> On Sun, 2005-10-30 at 10:50 -0600, John A Meinel wrote:
>> Robert Collins wrote:
>>  
>>> I agree that you may wish to update the tree, or not. I suggest that the
>>> right way to do this is to use 'tree.pull()' on the tree you want to
>>> update - all the code is there. To do this in cmd_push, its as simple as
>>> trying to get the working tree for the branch, and falling back to the
>>> branch. This will need your heuristic for having the tree accessible or
>>> not. 
>> Sure. I was doing that inside Branch, but I suppose you could do it
>> outside of it as well.
> 
> Doing it inside Branch gives Branch more responsibilities - we already
> have trouble with a vague focus in Branch, so I'm being quite aggressive
> about only adding clearly-Branch-responsibility stuff to Branch.

Sure. I'm fine having working tree keep itself updated. I suppose a
small question is whether it should be branch calling working tree, or
working tree calling branch.
I still think of a working tree as part of a branch (especially because
you can have a branch without a working tree, but not the other way
around, unless you consider a non-controlled tree a working tree.)

> 
>>> To be clear - I'm not claiming that the code I wrote was fully
>>> correct with respect to the working tree management. Not having the tree
>>> has a number of negatives - it may confuse people, .bzr is hidden, there
>>> is no README etc. But it also has a number of positives - its faster, we
>>> dont need to worry about differences in capability, and I hope that most
>>> folk that need the branch to be accessible over the web will install
>>> bzrweb or some such.
>> I'm not sure I follow all of your arguments here, we are talking about
>> *not* having a working tree, right? Which means that:
>> .bzr is not hidden, it just doesn't exist. My implementation of branches
>> without working trees is to just put "branch-format" into the main
>> directory. That way nothing is hidden (especially considering I never
>> figured out how to get apache to show .bzr)
>> I agree having 2 formats may confuse people.
>> The README is also directly exposed.
>> I'm not sure what you mean by "need the branch to be accessible over the
>> web". Are you talking about the content?
> 
> Ah. So one of the problems related to this is other folk pulling from
> the branch.
> If you have '/foo/bar/branch-format' one day, and
> '/foo/bar/.bzr/branch-format' the next, then you need to teach Branch
> that it can connect to '/foo/bar' as the branch in both cases.
> 
> Unfortunately, that also means that 'bzr branch /foo/bar/.bzr' will work
> - and if the branch then switches to the '/foo/bar' layout, the user
> pulling from /foo/bar/.bzr will suddenly stop working :[.

I made a comment about this in my changes. I see 2 ways to do it. One,
just see if the last portion of your path is ".bzr" if it is, then move
up a step, and consider that to be the true branch root.
The second is to use a new control file something like
"without-working-tree". Then when you connect to the branch, you can
check if this file exists. If it does, then you know you are at the top
level. If it does not, then move up a level.

I think this problem very simple to solve.

> 
>>>> "bzr revert" will change the working tree into the last revision, which
>>>> is close to correct, but if there were any uncommitted changes, they
>>>> would be lost (and you can't just commit, because that would revert all
>>>> of the other changes). The best you could do is a "bzr diff -r ???"
>>>> where you have to remember what ??? the tree was before it was pushed into.
>>> ?! I dont get this. bzrtools push command does not preserve uncommitted
>>> changes either - the branch that is pushed too may have the working tree
>>> not match the last commit, but it is not used in 'bzr branch.'
>> That is because bzrtools push (and my rpush) just use rsync to mirror
>> the current working directory. That (in my mind) was a limitation of the
>> implementation. I believe for both of them, if you had uncommitted
>> changes, they would get pushed up (except they both check for a clean
>> tree first).
> 
> Yes, they did do that, and I considered it a bug too.
> 
>>>> I'm not sure that "bzr push" should create the remote directory if it
>>>> doesn't exist. Maybe. It can be nice as a first step for publishing
>>>> things. But it also means a typo could go wrong. Perhaps it could do it
>>>> if you supply a flag. "bzr push --create".
>>> 'rmdir' is quite easy :). I've added a --create-prefix flag though, to
>>> allow creating much deeper paths. I create the final path always,
>>> because it seems nicer to me - much the way that 'branch' creates its
>>> output dir.
>> I think this is one of the differences in our thinking. I think of push
>>  as though it should be like pull, you think of it more that it should
>> be like branch.
>>
>> I would rather see branch get remote working-tree-less support. So that
>> you could do:
>> bzr branch --no-working-tree here sftp://published/
>> And from then on, you would be able to push into that branch.
>> But it is arguable as to which command has this function. push is
>> certainly one of the possibilities.
> 
> This is an interesting possibility. I'm not sure which way will be
> clearer for users. Well, perhaps I think that 'branch' should be a DWIM
> command, and 'pull' should be taught how to create a branch on the fly
> (bzr pull source new-branch), pull would always work with working trees,
> and push could (perhaps) never work with them.

Well, "branch" is a strong term, "get" is a nicer one for this type of
action. However, "branch" makes it obvious that the local thing is a
separate entity from the remote one. (ie committing in the local one
does not commit to the remote one).

In my head, pull is usually a fast operation, because it only pulls a
few things, while branch takes a long time, because it has to grab
everything.
I was very surprised when I did "pull --overwrite" in the wrong
directory and it started pulling 2k changes. I would have preferred it
to fail. (Though it might have been my fault for having a bogus tree
lying around).

> 
>>>> It looks like you merged in the diff changes, as well as the
>>>> set_user_option changes all into one patch. Not a big deal, but its nice
>>>> when changes are focused on a single change.
>>> Indeed. However, I started with a test for push, and recursed back from
>>> there writing tests and code until I had the feature working - I didn't
>>> really know just what would be needed until I was done - and committing
>>> a hunk or two randomly would not have reflected what I actually had
>>> tested.
>> I suppose it is arguable whether each commit should pass the test cases,
>> or whether it should be a self-contained change.
>> I feel like a mainline (and maybe an integration branch) should act like
>> the former. But for a development branch, I prefer the latter. That way
>> the actual changes are obvious, and you can revert specific changes,
>> without accidentally reverting the wrong thing.
> 
> Agreed. Foolishly, I did this in my integration working tree :).
> 
> Rob
> 

John
=:->


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 249 bytes
Desc: OpenPGP digital signature
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20051030/7dc36ab4/attachment.pgp 


More information about the bazaar mailing list