D6776: bookmarks: validate changes on push (issue6193) (BC)

2020-08-06 Thread mjacob (Manuel Jacob)
mjacob added a comment.


  I agree (with some previous answers) that adding more stuff to `--force` 
should be avoided.
  
  I planned to send a proposal (and patches) after the 5.5 release for adding 
more detailed options that can be used instead of `--force`. However, due to 
unexpected reasons, I don’t know whether I’ll have the time for doing that.

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

To: idlsoft, #hg-reviewers, durin42, baymax
Cc: mjacob, marmoute, pulkit, durin42, valentin.gatienbaron, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D6776: bookmarks: validate changes on push (issue6193) (BC)

2020-08-06 Thread idlsoft (Sandu Turcan)
idlsoft added a comment.


  As I
  
  In D6776#133068 , @marmoute 
wrote:
  
  > As @valentin.gatienbaron pointed out, the now avoid adding more semantic to 
bare `--force` with an associated `--force-bookmark` especially because we want 
to be able to select the bookmarks that get force pushed here.
  
  I've expressed my concerns about that earlier, but ultimately it's a debate 
for core maintainers, we'll use whatever they decide.
  Without a clear decision it didn't make much sense to modify the PR.
  I'm not sure if I'll have the bandwith to resume working on this, but glad to 
see it getting renewed attention.

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

To: idlsoft, #hg-reviewers, durin42, baymax
Cc: marmoute, pulkit, durin42, valentin.gatienbaron, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D6776: bookmarks: validate changes on push (issue6193) (BC)

2020-08-06 Thread marmoute (Pierre-Yves David)
marmoute added a comment.


  As @valentin.gatienbaron pointed out, the now avoid adding more semantic to 
bare `--force` with an associated `--force-bookmark` especially because we want 
to be able to select the bookmarks that get force pushed here.

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

To: idlsoft, #hg-reviewers, durin42, baymax
Cc: marmoute, pulkit, durin42, valentin.gatienbaron, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D6776: bookmarks: validate changes on push (issue6193) (BC)

2020-01-24 Thread baymax (Baymax, Your Personal Patch-care Companion)
This revision now requires changes to proceed.
baymax added a comment.
baymax requested changes to this revision.


  There seems to have been no activities on this Diff for the past 3 Months.
  
  By policy, we are automatically moving it out of the `need-review` state.
  
  Please, move it back to `need-review` without hesitation if this diff should 
still be discussed.
  
  :baymax:need-review-idle:

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

To: idlsoft, #hg-reviewers, durin42, baymax
Cc: pulkit, durin42, valentin.gatienbaron, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D6776: bookmarks: validate changes on push (issue6193) (BC)

2019-09-13 Thread valentin.gatienbaron (Valentin Gatien-Baron)
valentin.gatienbaron added a comment.


  In D6776#100506 , @durin42 wrote:
  
  > In D6776#100487 , 
@valentin.gatienbaron wrote:
  >
  >> I showed in D6847  the same change 
but implemented in exchange._processcompared. Tests pass.
  >> I think it'd make for a simpler final state: with the current change, the 
client sees that the bookmark is going to move sideways, decides this is fine, 
requests that the server validates that the bookmark is indeed moving sideways 
(which it does), but in the end the server rejects the move. In the suggested 
change, the client sees that the bookmark is going sideways and rejects it. 
This should be consistent with the way new heads or new branches or diverging 
rewrites are prevented.
  >
  > Isn't that a client-side change only though, so we still need functionality 
on the server to reject bad pushes? (I could be missing something.)
  
  If you mean "reject bad pushes as long as people don't push -f", both 
versions implement this (the client-side check is not racy thanks to these 
check:bookmark bundle parts).
  If you mean "reject bad pushes, push -f or not", a server-side hook is 
necessary for that, and hook.pretxnclose-bookmark should be able to do the job 
without any server code change. Server code change can certainly simplify 
writing such checks, but passing the force parameter on the procol is not 
needed.

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

To: idlsoft, #hg-reviewers, durin42
Cc: pulkit, durin42, valentin.gatienbaron, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D6776: bookmarks: validate changes on push (issue6193) (BC)

2019-09-13 Thread idlsoft (Sandu Turcan)
idlsoft updated this revision to Diff 16534.

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D6776?vs=16533=16534

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

AFFECTED FILES
  mercurial/bundle2.py
  mercurial/exchange.py
  mercurial/localrepo.py
  mercurial/repository.py
  mercurial/wireprotov1peer.py
  mercurial/wireprotov1server.py
  tests/test-bookmarks-conflict.t
  tests/test-bookmarks-pushpull.t
  tests/test-hook.t

CHANGE DETAILS

diff --git a/tests/test-hook.t b/tests/test-hook.t
--- a/tests/test-hook.t
+++ b/tests/test-hook.t
@@ -545,6 +545,7 @@
   HG_URL=file:$TESTTMP/a
   
   pushkey hook: HG_BUNDLE2=1
+  HG_FORCE=0
   HG_HOOKNAME=pushkey
   HG_HOOKTYPE=pushkey
   HG_KEY=foo
@@ -632,6 +633,7 @@
   HG_TXNNAME=push
   
   prepushkey.forbid hook: HG_BUNDLE2=1
+  HG_FORCE=0
   HG_HOOKNAME=prepushkey
   HG_HOOKTYPE=prepushkey
   HG_KEY=baz
diff --git a/tests/test-bookmarks-pushpull.t b/tests/test-bookmarks-pushpull.t
--- a/tests/test-bookmarks-pushpull.t
+++ b/tests/test-bookmarks-pushpull.t
@@ -813,7 +813,7 @@
  Z 0d2164f0ce0d
  foo   
  foobar
-  $ hg push -B Z http://localhost:$HGPORT/
+  $ hg push -B Z http://localhost:$HGPORT/ --force
   pushing to http://localhost:$HGPORT/
   searching for changes
   no changes found
diff --git a/tests/test-bookmarks-conflict.t b/tests/test-bookmarks-conflict.t
new file mode 100644
--- /dev/null
+++ b/tests/test-bookmarks-conflict.t
@@ -0,0 +1,142 @@
+initialize
+  $ make_changes() {
+  > d=`pwd`
+  > [ ! -z $1 ] && cd $1
+  > echo "test `basename \`pwd\``" >> test
+  > hg commit -Am"${2:-test}"
+  > r=$?
+  > cd $d
+  > return $r
+  > }
+  $ ls -1a
+  .
+  ..
+  $ hg init a
+  $ cd a
+  $ echo 'test' > test; hg commit -Am'test'
+  adding test
+  $ hg book @
+
+clone to b
+
+  $ mkdir ../b
+  $ cd ../b
+  $ hg clone ../a .
+  updating to bookmark @
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ make_changes
+  $ hg book bk_b
+
+clone to c
+  $ mkdir ../c
+  $ cd ../c
+  $ hg clone ../a .
+  updating to bookmark @
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ make_changes
+  $ hg book bk_c
+
+push from b
+  $ cd ../b
+  $ hg push -B .
+  pushing to $TESTTMP/a
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  updating bookmark @
+  exporting bookmark bk_b
+  $ hg -R ../a id -r @
+  e11a942451be tip @/bk_b
+
+push from c
+  $ cd ../c
+  $ hg push -B .
+  pushing to $TESTTMP/a
+  searching for changes
+  remote has heads on branch 'default' that are not known locally: e11a942451be
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  exporting bookmark bk_c
+  $ hg push -B @
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  abort: push rejected: bookmark "@" has changed
+  (run 'hg pull', resolve conflicts, and push again)
+  [255]
+  $ hg -R ../a log -G -T '{rev} {bookmarks}'
+  o  2 bk_c
+  |
+  | o  1 @ bk_b
+  |/
+  @  0
+  
+
+  $ hg push -B @ --force
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  updating bookmark @
+  [1]
+  $ hg -R ../a log -G -T '{rev} {bookmarks}'
+  o  2 @ bk_c
+  |
+  | o  1 bk_b
+  |/
+  @  0
+  
+
+## push using ssh  
+  $ hg -R ../b push -B @ --force
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  updating bookmark @
+  [1]
+  $ hg push -B @ ssh://user@dummy/a -e"$PYTHON $TESTDIR/dummyssh"
+  pushing to ssh://user@dummy/a
+  searching for changes
+  no changes found
+  remote: push rejected: bookmark "@" has changed
+  remote: (run 'hg pull', resolve conflicts, and push again)
+  abort: push failed on remote
+  [255]
+  $ hg push --force -B @ ssh://user@dummy/a -e"$PYTHON $TESTDIR/dummyssh"
+  pushing to ssh://user@dummy/a
+  searching for changes
+  no changes found
+  updating bookmark @
+  [1]
+
+# push using http
+  $ cat < ../a/.hg/hgrc
+  > [web]
+  > push_ssl = false
+  > allow_push = *
+  > EOF
+  $ hg serve -R ../a -p $HGPORT -d --pid-file=../hg.pid
+  $ cat ../hg.pid >> $DAEMON_PIDS
+  $ hg -R ../b push -B @ --force
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  updating bookmark @
+  [1]
+  $ hg push -B @ http://localhost:$HGPORT
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  remote: push rejected: bookmark "@" has changed
+  remote: (run 'hg pull', resolve conflicts, and push again)
+  abort: push failed on remote
+  [255]
+  $ hg push --force -B @ http://localhost:$HGPORT
+  pushing to http://localhost:$HGPORT/
+  searching for changes
+  no changes found
+  updating bookmark @
+  [1]
diff --git a/mercurial/wireprotov1server.py 

D6776: bookmarks: validate changes on push (issue6193) (BC)

2019-09-13 Thread idlsoft (Sandu Turcan)
idlsoft updated this revision to Diff 16533.

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D6776?vs=16531=16533

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

AFFECTED FILES
  mercurial/bundle2.py
  mercurial/exchange.py
  mercurial/localrepo.py
  mercurial/repository.py
  mercurial/wireprotov1peer.py
  mercurial/wireprotov1server.py
  tests/test-bookmarks-conflict.t
  tests/test-bookmarks-pushpull.t
  tests/test-hook.t

CHANGE DETAILS

diff --git a/tests/test-hook.t b/tests/test-hook.t
--- a/tests/test-hook.t
+++ b/tests/test-hook.t
@@ -545,6 +545,7 @@
   HG_URL=file:$TESTTMP/a

   pushkey hook: HG_BUNDLE2=1
+  HG_FORCE=0
   HG_HOOKNAME=pushkey
   HG_HOOKTYPE=pushkey
   HG_KEY=foo
@@ -632,6 +633,7 @@
   HG_TXNNAME=push

   prepushkey.forbid hook: HG_BUNDLE2=1
+  HG_FORCE=0
   HG_HOOKNAME=prepushkey
   HG_HOOKTYPE=prepushkey
   HG_KEY=baz
diff --git a/tests/test-bookmarks-pushpull.t b/tests/test-bookmarks-pushpull.t
--- a/tests/test-bookmarks-pushpull.t
+++ b/tests/test-bookmarks-pushpull.t
@@ -813,7 +813,7 @@
  Z 0d2164f0ce0d
  foo
  foobar
-  $ hg push -B Z http://localhost:$HGPORT/
+  $ hg push -B Z http://localhost:$HGPORT/ --force
   pushing to http://localhost:$HGPORT/
   searching for changes
   no changes found
diff --git a/tests/test-bookmarks-conflict.t b/tests/test-bookmarks-conflict.t
--- /dev/null
+++ b/tests/test-bookmarks-conflict.t
@@ -0,0 +1,91 @@
+initialize
+  $ make_changes() {
+  > d=`pwd`
+  > [ ! -z $1 ] && cd $1
+  > echo "test `basename \`pwd\``" >> test
+  > hg commit -Am"${2:-test}"
+  > r=$?
+  > cd $d
+  > return $r
+  > }
+  $ ls -1a
+  .
+  ..
+  $ hg init a
+  $ cd a
+  $ echo 'test' > test; hg commit -Am'test'
+  adding test
+  $ hg book @
+
+clone to b
+
+  $ mkdir ../b
+  $ cd ../b
+  $ hg clone ../a .
+  updating to bookmark @
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ make_changes
+  $ hg book bk_b
+
+clone to c
+  $ mkdir ../c
+  $ cd ../c
+  $ hg clone ../a .
+  updating to bookmark @
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ make_changes
+  $ hg book bk_c
+
+push from b
+  $ cd ../b
+  $ hg push -B .
+  pushing to $TESTTMP/a
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  updating bookmark @
+  exporting bookmark bk_b
+  $ hg -R ../a id -r @
+  e11a942451be tip @/bk_b
+
+push from c
+  $ cd ../c
+  $ hg push -B .
+  pushing to $TESTTMP/a
+  searching for changes
+  remote has heads on branch 'default' that are not known locally: e11a942451be
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  exporting bookmark bk_c
+  $ hg push -B @
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  abort: push rejected: bookmark "@" has changed
+  (run 'hg pull', resolve conflicts, and push again)
+  [255]
+  $ hg -R ../a log -G -T '{rev} {bookmarks}'
+  o  2 bk_c
+  |
+  | o  1 @ bk_b
+  |/
+  @  0
+
+
+  $ hg push -B @ --force
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  updating bookmark @
+  [1]
+  $ hg -R ../a log -G -T '{rev} {bookmarks}'
+  o  2 @ bk_c
+  |
+  | o  1 bk_b
+  |/
+  @  0
+
diff --git a/mercurial/wireprotov1server.py b/mercurial/wireprotov1server.py
--- a/mercurial/wireprotov1server.py
+++ b/mercurial/wireprotov1server.py
@@ -548,8 +548,8 @@
 return wireprototypes.streamreslegacy(
 streamclone.generatev1wireproto(repo))

-@wireprotocommand('unbundle', 'heads', permission='push')
-def unbundle(repo, proto, heads):
+@wireprotocommand('unbundle', 'heads *', permission='push')
+def unbundle(repo, proto, heads, others):
 their_heads = wireprototypes.decodelist(heads)

 with proto.mayberedirectstdio() as output:
@@ -594,7 +594,7 @@
   hint=bundle2requiredhint)

 r = exchange.unbundle(repo, gen, their_heads, 'serve',
-  proto.client())
+  proto.client(), others.get('force') == 
'1')
 if util.safehasattr(r, 'addpart'):
 # The return looks streamable, we are in the bundle2 case
 # and should return a stream.
diff --git a/mercurial/wireprotov1peer.py b/mercurial/wireprotov1peer.py
--- a/mercurial/wireprotov1peer.py
+++ b/mercurial/wireprotov1peer.py
@@ -445,7 +445,7 @@
 else:
 return changegroupmod.cg1unpacker(f, 'UN')

-def unbundle(self, bundle, heads, url):
+def unbundle(self, bundle, heads, url, force=None):
 '''Send cg (a readable file-like object representing the
 changegroup to push, typically a chunkbuffer object) to the
 remote server as a bundle.
@@ -464,10 +464,12 @@
  

D6776: bookmarks: validate changes on push (issue6193) (BC)

2019-09-13 Thread idlsoft (Sandu Turcan)
idlsoft updated this revision to Diff 16531.

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D6776?vs=16524=16531

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

AFFECTED FILES
  mercurial/bundle2.py
  mercurial/exchange.py
  mercurial/localrepo.py
  mercurial/repository.py
  mercurial/wireprotov1peer.py
  mercurial/wireprotov1server.py
  tests/test-bookmarks-conflict.t
  tests/test-bookmarks-pushpull.t
  tests/test-hook.t

CHANGE DETAILS

diff --git a/tests/test-hook.t b/tests/test-hook.t
--- a/tests/test-hook.t
+++ b/tests/test-hook.t
@@ -545,6 +545,7 @@
   HG_URL=file:$TESTTMP/a
   
   pushkey hook: HG_BUNDLE2=1
+  HG_FORCE=0
   HG_HOOKNAME=pushkey
   HG_HOOKTYPE=pushkey
   HG_KEY=foo
@@ -632,6 +633,7 @@
   HG_TXNNAME=push
   
   prepushkey.forbid hook: HG_BUNDLE2=1
+  HG_FORCE=0
   HG_HOOKNAME=prepushkey
   HG_HOOKTYPE=prepushkey
   HG_KEY=baz
diff --git a/tests/test-bookmarks-pushpull.t b/tests/test-bookmarks-pushpull.t
--- a/tests/test-bookmarks-pushpull.t
+++ b/tests/test-bookmarks-pushpull.t
@@ -813,7 +813,7 @@
  Z 0d2164f0ce0d
  foo   
  foobar
-  $ hg push -B Z http://localhost:$HGPORT/
+  $ hg push -B Z http://localhost:$HGPORT/ --force
   pushing to http://localhost:$HGPORT/
   searching for changes
   no changes found
diff --git a/tests/test-bookmarks-conflict.t b/tests/test-bookmarks-conflict.t
new file mode 100644
--- /dev/null
+++ b/tests/test-bookmarks-conflict.t
@@ -0,0 +1,91 @@
+initialize
+  $ make_changes() {
+  > d=`pwd`
+  > [ ! -z $1 ] && cd $1
+  > echo "test `basename \`pwd\``" >> test
+  > hg commit -Am"${2:-test}"
+  > r=$?
+  > cd $d
+  > return $r
+  > }
+  $ ls -1a
+  .
+  ..
+  $ hg init a
+  $ cd a
+  $ echo 'test' > test; hg commit -Am'test'
+  adding test
+  $ hg book @
+
+clone to b
+
+  $ mkdir ../b
+  $ cd ../b
+  $ hg clone ../a .
+  updating to bookmark @
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ make_changes
+  $ hg book bk_b
+
+clone to c
+  $ mkdir ../c
+  $ cd ../c
+  $ hg clone ../a .
+  updating to bookmark @
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ make_changes
+  $ hg book bk_c
+
+push from b
+  $ cd ../b
+  $ hg push -B .
+  pushing to $TESTTMP/a
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  updating bookmark @
+  exporting bookmark bk_b
+  $ hg -R ../a id -r @
+  e11a942451be tip @/bk_b
+
+push from c
+  $ cd ../c
+  $ hg push -B .
+  pushing to $TESTTMP/a
+  searching for changes
+  remote has heads on branch 'default' that are not known locally: e11a942451be
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  exporting bookmark bk_c
+  $ hg push -B @
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  abort: push rejected: bookmark "@" has changed
+  (run 'hg pull', resolve conflicts, and push again)
+  [255]
+  $ hg -R ../a log -G -T '{rev} {bookmarks}'
+  o  2 bk_c
+  |
+  | o  1 @ bk_b
+  |/
+  @  0
+  
+
+  $ hg push -B @ --force
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  updating bookmark @
+  [1]
+  $ hg -R ../a log -G -T '{rev} {bookmarks}'
+  o  2 @ bk_c
+  |
+  | o  1 bk_b
+  |/
+  @  0
+  
diff --git a/mercurial/wireprotov1server.py b/mercurial/wireprotov1server.py
--- a/mercurial/wireprotov1server.py
+++ b/mercurial/wireprotov1server.py
@@ -548,8 +548,8 @@
 return wireprototypes.streamreslegacy(
 streamclone.generatev1wireproto(repo))
 
-@wireprotocommand('unbundle', 'heads', permission='push')
-def unbundle(repo, proto, heads):
+@wireprotocommand('unbundle', 'heads *', permission='push')
+def unbundle(repo, proto, heads, others):
 their_heads = wireprototypes.decodelist(heads)
 
 with proto.mayberedirectstdio() as output:
@@ -594,7 +594,7 @@
   hint=bundle2requiredhint)
 
 r = exchange.unbundle(repo, gen, their_heads, 'serve',
-  proto.client())
+  proto.client(), others.get('force') == 
'1')
 if util.safehasattr(r, 'addpart'):
 # The return looks streamable, we are in the bundle2 case
 # and should return a stream.
diff --git a/mercurial/wireprotov1peer.py b/mercurial/wireprotov1peer.py
--- a/mercurial/wireprotov1peer.py
+++ b/mercurial/wireprotov1peer.py
@@ -445,7 +445,7 @@
 else:
 return changegroupmod.cg1unpacker(f, 'UN')
 
-def unbundle(self, bundle, heads, url):
+def unbundle(self, bundle, heads, url, force=None):
 '''Send cg (a readable file-like object representing the
 changegroup to push, 

D6776: bookmarks: validate changes on push (issue6193) (BC)

2019-09-13 Thread idlsoft (Sandu Turcan)
idlsoft added a comment.


  > Isn't that a client-side change only though, so we still need functionality 
on the server to reject bad pushes? (I could be missing something.)
  
  I'm actually not sure how to make this work for http, it doesn't seem to 
propagate `--force` to `unbundle`.
  Which is why the line in **test-bookmarks-pushpull.t** is `--config 
devel.legacy.exchange=bookmarks` instead of `--force`

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

To: idlsoft, #hg-reviewers, durin42
Cc: pulkit, durin42, valentin.gatienbaron, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D6776: bookmarks: validate changes on push (issue6193) (BC)

2019-09-13 Thread durin42 (Augie Fackler)
durin42 added a comment.


  In D6776#100487 , 
@valentin.gatienbaron wrote:
  
  > I showed in D6847  the same change 
but implemented in exchange._processcompared. Tests pass.
  > I think it'd make for a simpler final state: with the current change, the 
client sees that the bookmark is going to move sideways, decides this is fine, 
requests that the server validates that the bookmark is indeed moving sideways 
(which it does), but in the end the server rejects the move. In the suggested 
change, the client sees that the bookmark is going sideways and rejects it. 
This should be consistent with the way new heads or new branches or diverging 
rewrites are prevented.
  
  Isn't that a client-side change only though, so we still need functionality 
on the server to reject bad pushes? (I could be missing something.)

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

To: idlsoft, #hg-reviewers, durin42
Cc: pulkit, durin42, valentin.gatienbaron, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D6776: bookmarks: validate changes on push (issue6193) (BC)

2019-09-12 Thread valentin.gatienbaron (Valentin Gatien-Baron)
valentin.gatienbaron added a comment.


  I showed in D6847  the same change but 
implemented in exchange._processcompared. Tests pass.
  I think it'd make for a simpler final state: with the current change, the 
client sees that the bookmark is going to move sideways, decides this is fine, 
requests that the server validates that the bookmark is indeed moving sideways 
(which it does), but in the end the server rejects the move. In the suggested 
change, the client sees that the bookmark is going sideways and rejects it. 
This should be consistent with the way new heads or new branches or diverging 
rewrites are prevented.

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

To: idlsoft, #hg-reviewers, durin42
Cc: pulkit, durin42, valentin.gatienbaron, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D6776: bookmarks: validate changes on push (issue6193) (BC)

2019-09-12 Thread idlsoft (Sandu Turcan)
idlsoft updated this revision to Diff 16524.

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D6776?vs=16519=16524

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

AFFECTED FILES
  mercurial/bundle2.py
  mercurial/exchange.py
  mercurial/localrepo.py
  mercurial/repository.py
  mercurial/wireprotov1peer.py
  tests/test-bookmarks-conflict.t
  tests/test-bookmarks-pushpull.t
  tests/test-hook.t

CHANGE DETAILS

diff --git a/tests/test-hook.t b/tests/test-hook.t
--- a/tests/test-hook.t
+++ b/tests/test-hook.t
@@ -545,6 +545,7 @@
   HG_URL=file:$TESTTMP/a
   
   pushkey hook: HG_BUNDLE2=1
+  HG_FORCE=0
   HG_HOOKNAME=pushkey
   HG_HOOKTYPE=pushkey
   HG_KEY=foo
@@ -632,6 +633,7 @@
   HG_TXNNAME=push
   
   prepushkey.forbid hook: HG_BUNDLE2=1
+  HG_FORCE=0
   HG_HOOKNAME=prepushkey
   HG_HOOKTYPE=prepushkey
   HG_KEY=baz
diff --git a/tests/test-bookmarks-pushpull.t b/tests/test-bookmarks-pushpull.t
--- a/tests/test-bookmarks-pushpull.t
+++ b/tests/test-bookmarks-pushpull.t
@@ -813,7 +813,7 @@
  Z 0d2164f0ce0d
  foo   
  foobar
-  $ hg push -B Z http://localhost:$HGPORT/
+  $ hg push -B Z http://localhost:$HGPORT/ --config 
devel.legacy.exchange=bookmarks
   pushing to http://localhost:$HGPORT/
   searching for changes
   no changes found
diff --git a/tests/test-bookmarks-conflict.t b/tests/test-bookmarks-conflict.t
new file mode 100644
--- /dev/null
+++ b/tests/test-bookmarks-conflict.t
@@ -0,0 +1,91 @@
+initialize
+  $ make_changes() {
+  > d=`pwd`
+  > [ ! -z $1 ] && cd $1
+  > echo "test `basename \`pwd\``" >> test
+  > hg commit -Am"${2:-test}"
+  > r=$?
+  > cd $d
+  > return $r
+  > }
+  $ ls -1a
+  .
+  ..
+  $ hg init a
+  $ cd a
+  $ echo 'test' > test; hg commit -Am'test'
+  adding test
+  $ hg book @
+
+clone to b
+
+  $ mkdir ../b
+  $ cd ../b
+  $ hg clone ../a .
+  updating to bookmark @
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ make_changes
+  $ hg book bk_b
+
+clone to c
+  $ mkdir ../c
+  $ cd ../c
+  $ hg clone ../a .
+  updating to bookmark @
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ make_changes
+  $ hg book bk_c
+
+push from b
+  $ cd ../b
+  $ hg push -B .
+  pushing to $TESTTMP/a
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  updating bookmark @
+  exporting bookmark bk_b
+  $ hg -R ../a id -r @
+  e11a942451be tip @/bk_b
+
+push from c
+  $ cd ../c
+  $ hg push -B .
+  pushing to $TESTTMP/a
+  searching for changes
+  remote has heads on branch 'default' that are not known locally: e11a942451be
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  exporting bookmark bk_c
+  $ hg push -B @
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  abort: push rejected: bookmark "@" has changed
+  (run 'hg pull', resolve conflicts, and push again)
+  [255]
+  $ hg -R ../a log -G -T '{rev} {bookmarks}'
+  o  2 bk_c
+  |
+  | o  1 @ bk_b
+  |/
+  @  0
+  
+
+  $ hg push -B @ --force
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  updating bookmark @
+  [1]
+  $ hg -R ../a log -G -T '{rev} {bookmarks}'
+  o  2 @ bk_c
+  |
+  | o  1 bk_b
+  |/
+  @  0
+  
diff --git a/mercurial/wireprotov1peer.py b/mercurial/wireprotov1peer.py
--- a/mercurial/wireprotov1peer.py
+++ b/mercurial/wireprotov1peer.py
@@ -445,7 +445,7 @@
 else:
 return changegroupmod.cg1unpacker(f, 'UN')
 
-def unbundle(self, bundle, heads, url):
+def unbundle(self, bundle, heads, url, force=None):
 '''Send cg (a readable file-like object representing the
 changegroup to push, typically a chunkbuffer object) to the
 remote server as a bundle.
diff --git a/mercurial/repository.py b/mercurial/repository.py
--- a/mercurial/repository.py
+++ b/mercurial/repository.py
@@ -191,7 +191,7 @@
 Successful result should be a generator of data chunks.
 """
 
-def unbundle(bundle, heads, url):
+def unbundle(bundle, heads, url, force=None):
 """Transfer repository data to the peer.
 
 This is how the bulk of data during a push is transferred.
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -306,14 +306,14 @@
 raise error.Abort(_('cannot perform stream clone against local '
 'peer'))
 
-def unbundle(self, bundle, heads, url):
+def unbundle(self, bundle, heads, url, force=None):
 """apply a bundle on a repo
 
 This function handles the repo locking itself."""
 try:
 try:
 bundle = 

D6776: bookmarks: validate changes on push (issue6193) (BC)

2019-09-12 Thread pulkit (Pulkit Goyal)
pulkit added a comment.


  I agree with @valentin.gatienbaron that `--force` is quite generic :(.  It 
may create new heads on the server even if I don't want to.

INLINE COMMENTS

> bundle2.py:2149
> +hint=
> +_("run 'hg pull', resolve conflicts, and push 
> again"))
> +hookargs = tr.hookargs.copy()

Hm, I think `conflicts` can be confusing but I don't have better suggestions 
here.

> repository.py:194
>  
> -def unbundle(bundle, heads, url):
> +def unbundle(bundle, heads, url, force=None):
>  """Transfer repository data to the peer.

It will be nice to have documentation about what `force` does in the interface.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

To: idlsoft, #hg-reviewers, durin42
Cc: pulkit, durin42, valentin.gatienbaron, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D6776: bookmarks: validate changes on push (issue6193) (BC)

2019-09-11 Thread durin42 (Augie Fackler)
durin42 added a comment.


  We're really close. I've uploaded my rebase of this to the latest dev hg 
(along with some minor test fixes). There's now only one failure:
  
--- /Users/augie/Programming/hg/crew/tests/test-bookmarks-pushpull.t
+++ 
/Users/augie/Programming/hg/crew/tests/test-bookmarks-pushpull.t#b2-binary.err
@@ -820,15 +820,17 @@
   pushing to http://localhost:$HGPORT/
   searching for changes
   no changes found
-  updating bookmark Z
-  [1]
+  remote: push rejected: bookmark "Z" has changed
+  remote: (run 'hg pull', resolve conflicts, and push again)
+  abort: push failed on remote
+  [255]
   $ hg book -d Z
   $ hg in -B http://localhost:$HGPORT/
   comparing with http://localhost:$HGPORT/
   searching for changed bookmarks
  @ 9b140be10808
  X 9b140be10808
- Z 0d2164f0ce0d
+ Z 9b140be10808
  foo   
  foobar9b140be10808
   $ hg pull -B Z http://localhost:$HGPORT/
@@ -853,7 +855,7 @@
* @ 1:9b140be10808
  X 1:9b140be10808
  Y 4:c922c0139ca0
- Z 2:0d2164f0ce0d
+ Z 1:9b140be10808
  foo   -1:
  foobar1:9b140be10808
 

ERROR: test-bookmarks-pushpull.t#b2-binary output changed
  
  My gut at this point is that we should:
  
  1. Document that legacy bookmark push behavior over pushkey is different
  2. Add a config to reject bookmark pushes over pushkey
  
  But if there's a way to fix the pushkey behavior too, I'd be interested in 
that. I'm just not sure it's worth blocking on when that should only matter 
with very old servers. Obviously if others have stronger opinions they should 
speak up.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

To: idlsoft, #hg-reviewers, durin42
Cc: durin42, valentin.gatienbaron, mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


D6776: bookmarks: validate changes on push (issue6193) (BC)

2019-09-11 Thread durin42 (Augie Fackler)
durin42 updated this revision to Diff 16519.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D6776?vs=16518=16519

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

AFFECTED FILES
  mercurial/bundle2.py
  mercurial/exchange.py
  mercurial/interfaces/repository.py
  mercurial/localrepo.py
  mercurial/wireprotov1peer.py
  tests/test-bookmarks-conflict.t
  tests/test-hook.t

CHANGE DETAILS

diff --git a/tests/test-hook.t b/tests/test-hook.t
--- a/tests/test-hook.t
+++ b/tests/test-hook.t
@@ -545,6 +545,7 @@
   HG_URL=file:$TESTTMP/a
   
   pushkey hook: HG_BUNDLE2=1
+  HG_FORCE=0
   HG_HOOKNAME=pushkey
   HG_HOOKTYPE=pushkey
   HG_KEY=foo
@@ -632,6 +633,7 @@
   HG_TXNNAME=push
   
   prepushkey.forbid hook: HG_BUNDLE2=1
+  HG_FORCE=0
   HG_HOOKNAME=prepushkey
   HG_HOOKTYPE=prepushkey
   HG_KEY=baz
diff --git a/tests/test-bookmarks-conflict.t b/tests/test-bookmarks-conflict.t
new file mode 100644
--- /dev/null
+++ b/tests/test-bookmarks-conflict.t
@@ -0,0 +1,91 @@
+initialize
+  $ make_changes() {
+  > d=`pwd`
+  > [ ! -z $1 ] && cd $1
+  > echo "test `basename \`pwd\``" >> test
+  > hg commit -Am"${2:-test}"
+  > r=$?
+  > cd $d
+  > return $r
+  > }
+  $ ls -1a
+  .
+  ..
+  $ hg init a
+  $ cd a
+  $ echo 'test' > test; hg commit -Am'test'
+  adding test
+  $ hg book @
+
+clone to b
+
+  $ mkdir ../b
+  $ cd ../b
+  $ hg clone ../a .
+  updating to bookmark @
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ make_changes
+  $ hg book bk_b
+
+clone to c
+  $ mkdir ../c
+  $ cd ../c
+  $ hg clone ../a .
+  updating to bookmark @
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ make_changes
+  $ hg book bk_c
+
+push from b
+  $ cd ../b
+  $ hg push -B .
+  pushing to $TESTTMP/a
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  updating bookmark @
+  exporting bookmark bk_b
+  $ hg -R ../a id -r @
+  e11a942451be tip @/bk_b
+
+push from c
+  $ cd ../c
+  $ hg push -B .
+  pushing to $TESTTMP/a
+  searching for changes
+  remote has heads on branch 'default' that are not known locally: e11a942451be
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  exporting bookmark bk_c
+  $ hg push -B @
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  abort: push rejected: bookmark "@" has changed
+  (run 'hg pull', resolve conflicts, and push again)
+  [255]
+  $ hg -R ../a log -G -T '{rev} {bookmarks}'
+  o  2 bk_c
+  |
+  | o  1 @ bk_b
+  |/
+  @  0
+  
+
+  $ hg push -B @ --force
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  updating bookmark @
+  [1]
+  $ hg -R ../a log -G -T '{rev} {bookmarks}'
+  o  2 @ bk_c
+  |
+  | o  1 bk_b
+  |/
+  @  0
+  
diff --git a/mercurial/wireprotov1peer.py b/mercurial/wireprotov1peer.py
--- a/mercurial/wireprotov1peer.py
+++ b/mercurial/wireprotov1peer.py
@@ -445,7 +445,7 @@
 else:
 return changegroupmod.cg1unpacker(f, 'UN')
 
-def unbundle(self, bundle, heads, url):
+def unbundle(self, bundle, heads, url, force=None):
 '''Send cg (a readable file-like object representing the
 changegroup to push, typically a chunkbuffer object) to the
 remote server as a bundle.
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -308,14 +308,15 @@
 raise error.Abort(_('cannot perform stream clone against local '
 'peer'))
 
-def unbundle(self, bundle, heads, url):
+def unbundle(self, bundle, heads, url, force=None):
 """apply a bundle on a repo
 
 This function handles the repo locking itself."""
 try:
 try:
 bundle = exchange.readbundle(self.ui, bundle, None)
-ret = exchange.unbundle(self._repo, bundle, heads, 'push', url)
+ret = exchange.unbundle(
+self._repo, bundle, heads, 'push', url, force=force)
 if util.safehasattr(ret, 'getchunks'):
 # This is a bundle20 object, turn it into an unbundler.
 # This little dance should be dropped eventually when the
diff --git a/mercurial/interfaces/repository.py 
b/mercurial/interfaces/repository.py
--- a/mercurial/interfaces/repository.py
+++ b/mercurial/interfaces/repository.py
@@ -191,7 +191,7 @@
 Successful result should be a generator of data chunks.
 """
 
-def unbundle(bundle, heads, url):
+def unbundle(bundle, heads, url, force=None):
 """Transfer repository data to the peer.
 
 This is how the bulk of data during a push is transferred.
diff --git a/mercurial/exchange.py 

D6776: bookmarks: validate changes on push (issue6193) (BC)

2019-09-11 Thread idlsoft (Sandu Turcan)
idlsoft updated this revision to Diff 16518.

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D6776?vs=16515=16518

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

AFFECTED FILES
  mercurial/bundle2.py
  mercurial/exchange.py
  mercurial/localrepo.py
  mercurial/repository.py
  mercurial/wireprotov1peer.py
  tests/test-bookmarks-conflict.t

CHANGE DETAILS

diff --git a/tests/test-bookmarks-conflict.t b/tests/test-bookmarks-conflict.t
new file mode 100644
--- /dev/null
+++ b/tests/test-bookmarks-conflict.t
@@ -0,0 +1,91 @@
+initialize
+  $ make_changes() {
+  > d=`pwd`
+  > [ ! -z $1 ] && cd $1
+  > echo "test `basename \`pwd\``" >> test
+  > hg commit -Am"${2:-test}"
+  > r=$?
+  > cd $d
+  > return $r
+  > }
+  $ ls -1a
+  .
+  ..
+  $ hg init a
+  $ cd a
+  $ echo 'test' > test; hg commit -Am'test'
+  adding test
+  $ hg book @
+
+clone to b
+
+  $ mkdir ../b
+  $ cd ../b
+  $ hg clone ../a .
+  updating to bookmark @
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ make_changes
+  $ hg book bk_b
+
+clone to c
+  $ mkdir ../c
+  $ cd ../c
+  $ hg clone ../a .
+  updating to bookmark @
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ make_changes
+  $ hg book bk_c
+
+push from b
+  $ cd ../b
+  $ hg push -B .
+  pushing to $TESTTMP/a
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  updating bookmark @
+  exporting bookmark bk_b
+  $ hg -R ../a id -r @
+  e11a942451be tip @/bk_b
+
+push from c
+  $ cd ../c
+  $ hg push -B .
+  pushing to $TESTTMP/a
+  searching for changes
+  remote has heads on branch 'default' that are not known locally: e11a942451be
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  exporting bookmark bk_c
+  $ hg push -B @
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  abort: push rejected: bookmark "@" has changed
+  (run 'hg pull', resolve conflicts, and push again)
+  [255]
+  $ hg -R ../a log -G -T '{rev} {bookmarks}'
+  o  2 bk_c
+  |
+  | o  1 @ bk_b
+  |/
+  @  0
+  
+
+  $ hg push -B @ --force
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  updating bookmark @
+  [1]
+  $ hg -R ../a log -G -T '{rev} {bookmarks}'
+  o  2 @ bk_c
+  |
+  | o  1 bk_b
+  |/
+  @  0
+  
diff --git a/mercurial/wireprotov1peer.py b/mercurial/wireprotov1peer.py
--- a/mercurial/wireprotov1peer.py
+++ b/mercurial/wireprotov1peer.py
@@ -445,7 +445,7 @@
 else:
 return changegroupmod.cg1unpacker(f, 'UN')
 
-def unbundle(self, bundle, heads, url):
+def unbundle(self, bundle, heads, url, force=None):
 '''Send cg (a readable file-like object representing the
 changegroup to push, typically a chunkbuffer object) to the
 remote server as a bundle.
diff --git a/mercurial/repository.py b/mercurial/repository.py
--- a/mercurial/repository.py
+++ b/mercurial/repository.py
@@ -191,7 +191,7 @@
 Successful result should be a generator of data chunks.
 """
 
-def unbundle(bundle, heads, url):
+def unbundle(bundle, heads, url, force=None):
 """Transfer repository data to the peer.
 
 This is how the bulk of data during a push is transferred.
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -306,14 +306,14 @@
 raise error.Abort(_('cannot perform stream clone against local '
 'peer'))
 
-def unbundle(self, bundle, heads, url):
+def unbundle(self, bundle, heads, url, force=None):
 """apply a bundle on a repo
 
 This function handles the repo locking itself."""
 try:
 try:
 bundle = exchange.readbundle(self.ui, bundle, None)
-ret = exchange.unbundle(self._repo, bundle, heads, 'push', url)
+ret = exchange.unbundle(self._repo, bundle, heads, 'push', 
url, force=force)
 if util.safehasattr(ret, 'getchunks'):
 # This is a bundle20 object, turn it into an unbundler.
 # This little dance should be dropped eventually when the
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -1159,6 +1159,7 @@
 'bundle': stream,
 'heads': ['force'],
 'url': pushop.remote.url(),
+'force': pushop.force,
 }).result()
 except error.BundleValueError as exc:
 raise error.Abort(_('missing support for %s') % exc)
@@ -2375,7 +2376,7 @@
 raise error.PushRaced('repository changed while %s - '
   'please try again' % 

D6776: bookmarks: validate changes on push (issue6193) (BC)

2019-09-11 Thread durin42 (Augie Fackler)
durin42 edited the summary of this revision.
durin42 retitled this revision from "bookmarks: validate changes on push" to 
"bookmarks: validate changes on push (issue6193) (BC)".
durin42 updated this revision to Diff 16515.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D6776?vs=16341=16515

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6776/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6776

AFFECTED FILES
  mercurial/bundle2.py
  mercurial/exchange.py
  mercurial/localrepo.py
  tests/test-bookmarksconflict.t

CHANGE DETAILS

diff --git a/tests/test-bookmarksconflict.t b/tests/test-bookmarksconflict.t
new file mode 100644
--- /dev/null
+++ b/tests/test-bookmarksconflict.t
@@ -0,0 +1,84 @@
+initialize
+  $ make_changes() {
+  > d=`pwd`
+  > [ ! -z $1 ] && cd $1
+  > echo "test `basename \`pwd\``" >> test
+  > hg commit -Am"${2:-test}"
+  > r=$?
+  > cd $d
+  > return $r
+  > }
+  $ ls -1a
+  .
+  ..
+  $ hg init a
+  $ cd a
+  $ echo 'test' > test; hg commit -Am'test'
+  adding test
+  $ hg book @
+
+clone to b
+
+  $ mkdir ../b
+  $ cd ../b
+  $ hg clone ../a .
+  updating to bookmark @
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ make_changes
+  $ hg book bk_b
+
+clone to c
+  $ mkdir ../c
+  $ cd ../c
+  $ hg clone ../a .
+  updating to bookmark @
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ make_changes
+  $ hg book bk_c
+
+push from b
+  $ cd ../b
+  $ hg push -B .
+  pushing to $TESTTMP/a
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  updating bookmark @
+  exporting bookmark bk_b
+  $ hg -R ../a id -r @
+  e11a942451be tip @/bk_b
+
+push from c
+  $ cd ../c
+  $ hg push -B .
+  pushing to $TESTTMP/a
+  searching for changes
+  remote has heads on branch 'default' that are not known locally: e11a942451be
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  exporting bookmark bk_c
+  $ hg push -B @
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  abort: push rejected: bookmark "@" has changed
+  (run 'hg pull', resolve conflicts, and push again)
+  [255]
+  $ hg -R ../a book
+   * @ 1:e11a942451be
+ bk_b  1:e11a942451be
+ bk_c  2:110743c8a16c
+  $ hg push -B @ --force
+  pushing to $TESTTMP/a
+  searching for changes
+  no changes found
+  updating bookmark @
+  [1]
+  $ hg -R ../a book
+   * @ 2:110743c8a16c
+ bk_b  1:e11a942451be
+ bk_c  2:110743c8a16c
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -308,14 +308,14 @@
 raise error.Abort(_('cannot perform stream clone against local '
 'peer'))
 
-def unbundle(self, bundle, heads, url):
+def unbundle(self, bundle, heads, url, force=None):
 """apply a bundle on a repo
 
 This function handles the repo locking itself."""
 try:
 try:
 bundle = exchange.readbundle(self.ui, bundle, None)
-ret = exchange.unbundle(self._repo, bundle, heads, 'push', url)
+ret = exchange.unbundle(self._repo, bundle, heads, 'push', 
url, force=force)
 if util.safehasattr(ret, 'getchunks'):
 # This is a bundle20 object, turn it into an unbundler.
 # This little dance should be dropped eventually when the
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -1161,6 +1161,7 @@
 'bundle': stream,
 'heads': ['force'],
 'url': pushop.remote.url(),
+'force': pushop.force,
 }).result()
 except error.BundleValueError as exc:
 raise error.Abort(_('missing support for %s') % exc)
@@ -2377,7 +2378,7 @@
 raise error.PushRaced('repository changed while %s - '
   'please try again' % context)
 
-def unbundle(repo, cg, heads, source, url):
+def unbundle(repo, cg, heads, source, url, force=None):
 """Apply a bundle to a repo.
 
 this function makes sure the repo is locked during the application and have
@@ -2426,7 +2427,8 @@
 
 op = bundle2.bundleoperation(repo, gettransaction,
  captureoutput=captureoutput,
- source='push')
+ source='push',
+ force=force)
 try:
 op = bundle2.processbundle(repo, cg, op=op)