8

General question.

I'm trying to use bookmarks instead of branches in mercurial. The reason of it is that I don't want to have a lot of unnecessary fixed-named permanent items in branches.

The problem appears when I use a separate bookmark for a new feature development and I want to push it to the out repository. Well, hg doesn't allow me to push if creates 'new remote head'. What should I to to be able to make such a push as if I was creating a new branch?

Example (a way to reproduce the problem).

Alice creates repository:

C:\TestHg>mkdir Alice
C:\TestHg>cd Alice
C:\TestHg\Alice>hg init
C:\TestHg\Alice>echo line1>>file.txt
C:\TestHg\Alice>hg addremove
adding file.txt
C:\TestHg\Alice>hg commit -m "Initial commit."

Bob clones Alice's repository:

C:\TestHg\Alice>cd ..
C:\TestHg>hg clone Alice Bob
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

Alice makes some changes in the code of the project:

C:\TestHg>cd Alice
C:\TestHg\Alice>echo line2 by Alice>>file.txt
C:\TestHg\Alice>hg commit -m "Alice continues her work on the project."

Bob starts his work on New Cool Feature using a separate bookmark to identify his independent 'branch' of work:

C:\TestHg\Alice>cd ..\Bob
C:\TestHg\Bob>hg bookmarks
no bookmarks set
C:\TestHg\Bob>hg bookmark NewCoolFeature
C:\TestHg\Bob>hg bookmarks
 * NewCoolFeature            0:792db6cfc262
C:\TestHg\Bob>echo line2 by Bob (as a part of New Cool Feature implementation)>>file.txt
C:\TestHg\Bob>hg commit -m "Bob starts his work on New Cool Feature"

Bob tries to push his changes to Alice's directory:

C:\TestHg\Bob>hg push -B NewCoolFeature
pushing to C:\TestHg\Alice
searching for changes
abort: push creates new remote head 38506e28a438!
(you should pull and merge or use push -f to force)

Ok, first Bob has to pull Alice's changes to his own repository:

C:\TestHg\Bob>hg pull
pulling from C:\TestHg\Alice
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)

Well, now Bob has two heads in his repository which is fine.

C:\TestHg\Bob>hg glog
o  changeset:   2:66beef200ba4
|  tag:         tip
|  parent:      0:792db6cfc262
|  user:        Alice
|  date:        Sun May 20 13:10:04 2012 +0400
|  summary:     Alice continues her work on the project.
|
| @  changeset:   1:38506e28a438
|/   bookmark:    NewCoolFeature
|    user:        Bob
|    date:        Sun May 20 13:12:26 2012 +0400
|    summary:     Bob starts his work on New Cool Feature
|
o  changeset:   0:792db6cfc262
   user:        Alice
   date:        Sun May 20 13:08:39 2012 +0400
   summary:     Initial commit.

After trying to make one more push Bob is asked for merge. Bob doesn't want to make the merge, because his results of work on New Cool Feature are not ready yet for the merge.

C:\TestHg\Bob>hg push -B NewCoolFeature
pushing to C:\TestHg\Alice
searching for changes
abort: push creates new remote head 38506e28a438!
(did you forget to merge? use push -f to force)

Example related question.

What should Bob do to be able to push his changes to Alice's repo as if his changes are in a separate branch?

Updates

UPD1: In a real life situation Alice's repo is used as a central sync point for all members of the development team.

Igor Soloydenko
  • 11,067
  • 11
  • 47
  • 90

1 Answers1

10

He should either:

  • Not push. Why does he want his unfinished changes on someone else's machine?
  • Force it. He was asked if he forgot to merge. He didn't. He wants a new head, so force it.

The message is there because often it's easy to create a new head without realising. However sometimes it's exactly what you want, and so there's the override switch.

Paul S
  • 7,645
  • 2
  • 24
  • 36
  • 1
    Thank you for reply! I forgot about the -f option! :) In this case it is exactly what I need. Bob's changes are correct. He may want to push his changes to Alice's repo in order to ask her for help wiht a New Cool Feature. In this case his force push would be Ok. – Igor Soloydenko May 20 '12 at 12:16
  • @keykeeper: I believe the workflow described in the question is quite strange. Bob shouldn't force push a new head to Alice's repo, if this is what Alice wants, then she should pull from Bob, i.e., the other other way around. – Helgi May 20 '12 at 15:28
  • @Helgi: Yes, the description may be a bit strange. I agree with that. Actually, in my real life situation I work with a 'central' repo instead Alice's repo. I mean, that 'central' repo is not controlled or used by any project member. The 'central' repo is a sync point. That's why in my real situation Bob's force push is Ok. – Igor Soloydenko May 20 '12 at 15:46
  • @keykeeper: Well then, I'd hate to have divergent heads in my central repo: this means I wouldn't know which head to update to after cloning. Which kind of branch do use bookmarks on: `default`/`stable` or feature development branches? Do you have a default-like bookmark meaning _this is not a dev bookmark?_ Do you merge or rebase after a bookmarked ‘branch’ is done with? – Helgi May 20 '12 at 15:50
  • @keykeeper: Ah, and I really, really hate `push -f`, it's too easy to screw up using it. I'd avoid it at all costs at my workflow. – Helgi May 20 '12 at 15:51
  • @Helgi: One head is marked as a 'main' one. This branch you should deal with. As for me, it's much better to have several heads than several permanent though closed branches. What other workflow would you advice? – Igor Soloydenko May 20 '12 at 16:26
  • I'd agree on the pull vs push. If Alice is going to help with "Cool new features" better for her to pull. She's then in control of what's in her repo and no nasty surprises happen. If you're talking about central, then my original question of 'Why Push?' is still unanswered. If the answer is 'So Alice can pull' then you're "doing it wrong" and Alice should be pulling from Bob directly. – Paul S May 20 '12 at 16:29
  • @Helgi `push -f` is there as a safe guard. Sure, you don't want to be getting into the habit of putting `-f` on every push, but there's nothing wrong with using it when you need it (which shouldn't be very often) – Paul S May 20 '12 at 16:32
  • @PaulS You said "'Why Push?' is still unanswered"... Well, Bob pushes his changes to central repo in order to provide other teammates an ability to help him without pulling directly from his machine (which can be shut-down). Actually, it doesn't matter, whether Bob pushes from his repo or manually pulls his changes being inside the central repo. – Igor Soloydenko May 20 '12 at 17:05
  • @keykeeper: I don't know such a workflow. At my day job, we have `stable`/`default`, _local_ bookmarks for everything one dev can do (basically this: http://lostechies.com/jimmybogard/2010/07/09/mercurial-workflows-local-development-work/), and for everything that requires 2+ devs, we create a named branch. If I could figure out how to replace named branches with bookmarks in an easy way, I'd do that. – Helgi May 20 '12 at 18:36
  • @PaulS: Maybe I just can't wrap my head around bookmark workflow, but I still can't see how to do it. Suppose I've taken a week off. I return to work, then what do I do? I pull, and I see lots of new heads without bookmarks (‘cause they aren't pulled by default). Maybe I should merge? Isn't that confusing? And we developers are but humans, so we'll err when confused. With branches less so. – Helgi May 20 '12 at 18:41
  • 1
    @Helgi What you say is logical, straightforward and nice, but here is one more problem. Our team agreed that none of us likes PERMANENT branches. If the branches could be completely closed and **removed** from the list of branches, we would use them. I don't want to get list in list of branches which have been closed long time ago. That's why I want to use bookmarks. – Igor Soloydenko May 20 '12 at 21:18
  • 1
    @keykeeper: Well, I don't like lots of named branches too (however, closed branches are not visible in `hg branches`, only in hgweb — by the way, which list of branches are you talking about? and see also Martin Geisler's note about topo heads here: http://stackoverflow.com/a/10508567/67988). The day I am sure my colleagues won't be confused by the bookmark-based workflow, we're ditching short-lived named branches. – Helgi May 20 '12 at 21:35
  • @Helgi I know that closed branches are not shown by `‍hg branches`‍. I don't want to see tons of already closed branches in `‍hg branches -c`‍. – Igor Soloydenko May 20 '12 at 22:02
  • @keykeeper The thing that is making me stumble is that when two developers work together on a piece of code it's rarely because Alice just decided to help without telling Bob. Bob's probably asked for help, or the boss got involved. Whatever, there's some kind of other communication. So Alice doesn't need to take code without Bob's machine being on because she's already spoken to him about it. Hence no need for a central repo with lots of branches. – Paul S May 21 '12 at 10:14
  • @keykeeper Are you aware of `hg incoming -B` which will tell you about the changes to bookmarks on another server. Including those which exist on the remote, but not locally. I'm not aware of a way of pulling all remote bookmarks though. – Paul S May 21 '12 at 10:15