Question about auto-refresh and detecting manual edits to standins

Greg Ward greg-hg at gerg.ca
Sun Feb 14 11:57:27 CST 2010


[my original claim]
> First, I'm not convinced there is a problem here that needs solving.
> We've been using bfiles in production for a couple of weeks now, and
> on one or two occasions I had to manually modify a standin.  I think
> this was merge-related: since bfiles currently has no support for
> merging, you just end up merging the standins.  It all works fine, but
> you could trash your merge with a badly timed bfrefresh command.

On Tue, Feb 9, 2010 at 7:00 PM, Qi Yang <qi.yang137 at gmail.com> wrote:
> Could you please give an example of the senario: "you could trash your merge
> with a badly timed bfrefresh command." ?

Yeah, sorry. Let me try to explain in more detail.  Setup a new repo
and central store:

  hg init bftest
  mkdir bfstore
  cd bftest
  edit .hg/hgrc and configure bfiles
  echo foo > foo
  head -c100 /dev/zero > big
  hg add foo
  hg bfadd big
  hg commit -ualice -minit
  hg bfput -v

Now create a branch where alice  modifies 'big':

  hg branch 1.0
  echo -n a >> big
  hg bfrefresh -v
  hg ci -ualice -m'modify big on branch'
  hg bfput -v

Back to the trunk where bob modifies big differently:

  hg update default
  echo -n b >> big
  hg bfrefresh -v
  hg ci -ubob -m'modify big on trunk'
  hg bfput -v

Now what happens when we merge 1.0 to default?  Obviously we're going
to get a conflict:

  $ HGMERGE=internal:merge hg merge 1.0
  merging .hgbfiles/big
  warning: conflicts during merge.
  merging .hgbfiles/big failed!
  [...]

  $ cat .hgbfiles/big
  <<<<<<< local
  089b4c67f97a7f9ac1a903c306889d48f50a91d5
  =======
  52d43bae9d8071f6980fcbcf83dc5b54a22ca5f2
  >>>>>>> other

To someone who understands bfiles, this is perfectly straightforward
and simple.  To the other 99% of the world, it's incomprehensible.
Let's be optimistic and assume the user is one of the clued-in elite.
;-)  The user can either keep the trunk change, accept the change from
branch 1.0, or find a way to merge the contents.  The first two cases
are really the same: you edit .hgbfiles/big and keep one branch or the
other, then commit.  End of story.  Nothing more to do, no need to get
bfiles involved at all.

So let's say the user decides that the trunk change is useless and
they're going to keep the version from 1.0.  They edit the standin and
keep the 'other' revision ID.  *But* the copy of 'big' in the working
directory does not reflect this change!  Here's how things stand:

  $ hg diff
  diff --git a/.hgbfiles/big b/.hgbfiles/big
  --- a/.hgbfiles/big
  +++ b/.hgbfiles/big
  @@ -1,1 +1,1 @@
  -089b4c67f97a7f9ac1a903c306889d48f50a91d5
  +52d43bae9d8071f6980fcbcf83dc5b54a22ca5f2
  $ sha1sum big
  089b4c67f97a7f9ac1a903c306889d48f50a91d5  big

At this point, bfiles is irrelevant.  Its knowledge of the world is no
longer correct: the user has decided that he's keeping revision
52d43... and discarding 089b4... .  If someone or something came along
and ran

  hg bfrefresh

that could trash the user's choice of how to resolve the merge.  Not
good!  (Hmmm: I just noticed that this does not actually happen.  Not
sure why.)

In a nutshell: if someone edits a standin file behind bfiles' back, I
would give them the benefit of the doubt, assume they know what they
are doing, and give it precedence.  Two exceptions:
  1) bad syntax: if a standin contains something other than 40 hex
chars plus newline, barf
  2) bad revision ID: if a standin contains 40 hex chars, but the file
revision in question is nowhere in sight, we have a problem

Greg


More information about the Mercurial-devel mailing list