[MERGE][0.14] Allow 'bzr push' to push onto existing dir

John Arbash Meinel john at arbash-meinel.com
Wed Jan 10 20:22:28 GMT 2007


Alexander Belchenko wrote:
> John Arbash Meinel ?8H5B:
>> I'm looking into fixing:
>>   https://launchpad.net/bugs/45504
>>   https://launchpad.net/bugs/53340
>>   https://launchpad.net/bugs/30576
> 
>> By suggestion, I changed how I'm doing it. While working on this, I'm
>> concerned that our api isn't quite what we want. But since I'm trying to
>> get this merged for 0.14 I did it in a minimally invasive manner, and it
>> is set up to be refactored easily.
> 
>> Basically this code changes the 'cmd_push' logic so that if there is a
>> target BzrDir it will attempt to reuse the target repository and create
>> a Branch on demand. Note that it won't create a target WorkingTree,
>> mostly because the logic for that is quite a bit trickier. We can't just
>> use sprout() or clone() because both of those want to create the BzrDir.
>> And I don't feel like implementing 90% of them again.
> 
> I have a question: how your code differentiate between incomplete
> target standalone branch without repository and incomplete branch
> in shared repository?

I'm not sure how you are defining an "incomplete target standalone branch".

What is happening today is that we start copying the repository data
across before we create the .bzr/branch directory and supporting
information.

Which means that we have a .bzr/repository but no .bzr/branch.

So this patch changes it so that when that is seen, it will continue
copying data into .bzr/repository (using remote_repo.fetch(local_repo)),
and then create a Branch (with local_branch.clone(remote_bzrdir))

If it was an 'incomplete branch in a shared repository' then it would
find a .bzr/ directory without a .bzr/repository *or* a .bzr/branch. But
it would look in parent directories to find a .bzr/repository.

This is because we use "BzrDir.find_repository()" rather than
"BzrDir.open_repository()". find searches through parents, open will
only open one if it exists in this BzrDir.

So basically, this works very similarly to what we do now. The only
difference is that we aren't confused if the remote target has a BzrDir
without a Branch.

The old logic was (psuedocode):

try:
  remote_bzrdir = BzrDir.open(target)
  remote_branch = remote_bzrdir.open_branch()
except NotBrancherror:
  if create_prefix:
    makedirs(target)
  else:
    mkdir(target)

  local_bzrdir.clone(target)
else:
  remote_branch.pull(local_branch)

The new logic is:

try:
  remote_bzrdir = BzrDir.open(target)
except NotBranchError: # No bzrdir, create one
  try:
    if create_prefix:
      makedirs(target)
    else:
      mkdir(target)
  except FileExists:
    if not use_existing:
       raise
  local_bzrdir.clone(target)
else: # We have a remote bzrdir
  try:
    remote_branch = remote_bzrdir.open_branch():
  except NotBranchError: # No remote branch
    repo = remote_bzrdir.find_repository()
    repo.fetch(local_branch.repository)
    local_branch.clone(remote_bzrdir)
  else: # We have a remote branch
    remote_branch.pull(local_branch)

It is certainly more complex because it handles more failure
possibilities. But I think it works.



> 
>> It also changes the 'create_prefix' loop, to be (IMO) cleaner, since
>> transport.mkdir('.') works just fine rather than trying to clone to the
>> parent and pop off the child directory name, etc.
> 
>> It also adds '--use-existing' which allows you to 'bzr push' onto a
>> directory that already exists, but that has no control directory
>> already. (I also thought to call it --use-existing-dir).
> 
> --use-existing-dir is longer but more clear, IMO.

If others agree, I'm fine with that.

> 
>> This should reduce a lot of the errors reported by users of Launchpad.
>> Since the changes should allow resuming a push if it gets ^C in the
>> middle of transfer.
> 
>> There still is a small need for a command that can move the remote
>> directory out of the way, or that can nuke the remote .bzr (or rename
>> it) and then push over what used to be there. Because there are still
>> potential race conditions that can leave something that isn't
>> recognizable by bzr. (If you ^C after .bzr/branch is made but before
>> ..bzr/branch/format is written, etc)
> 
>> I'd like to get feedback on this, since it would be really nice to get
>> this into 0.14, and that means getting quick feedback.
> 
> +0: I read your patch carefully but I'd like to test it in my real tasks.
> 
>> Since it only adds functionality (nothing is deprecated), I think it can
>> still qualify as bug-fixes and get merged after the freeze.
> 

Sure. Let me know if it works for you.

John
=:->



More information about the bazaar mailing list