Mercurial branched revision history, two remote heads when pushing - mercurial

I committed a bunch of changesets locally (23-28) and then I realized that I wanted to go back to revision 25, so I ran "hg up -r 25" to go back. Then I started working from there and committed a few changesets. Now I'm ready to push my changes to the server, but when I try to do that it complains with "abort: push creates new remote heads on branch 'default'!". I thought someone else may have committed to the repository so I did a hg pull, but did not get any changes.
Here is the revision tree that I am working with
23
|
24
|
25
/ \
26 29
| |
27 30
| |
28 31
|
32
|
33
|
34
|
35
Is it possible to remove revisions 26,27, and 28? How can I fix things so that I can run "hg push" without errors? Should I have used a different command to go back to revision 25?

Let me just throw in a voice of dissent on Lasse's answer. Mercurial is a system about building an immutable history. Think of a scientist working in his or her lab book on numbered pages in pen. Everything is important, even the stuff you wish you didn't write and don't want at this second. The strip command isn't enabled by default for a reason -- it violates the immutability that is a mercurial goal.
The more "Mercurial" way to address this would be to merge 26 into 35, selecting entirely the options from 35, so you're back down to one head. Then your push will still have only one head, but all of history is preserved.
Alternately you had the option to 'hg push -r 35' which would have given you no warning or error nor required -f because you'd be leaving the repo repo with only one head.
There's nothing wrong with strip, but it's not part of the traditional toolset or mindset in Mercurial.

Well, there's two ways I know of.
Note: Please make a backup, or a clone to experiment on, I do not take responsibility for any lost work
First, if you got MQ extension enabled, you can strip those off. I only know how to do that using TortoiseHg, but I'll find the right commands after posting here.
To do this, you would execute this command:
hg strip 26
Secondly, you can create a new clone locally of only some of the changesets, again I only know how to do that using TortoiseHg.
To do this, you would execute this command:
hg clone SOURCEDIRECTORY CLONEDIRECTORY -r35
Then, from your clone, after verifying that it contains the changesets you want, you push against the target repository.
As for answering what you should've done instead, you could've deleted your original clone and re-cloned from the server to get a clean clone only containing up to changeset 25, but of course you could use the strip command to get rid of the excess changesets then as well.

There's nothing inherently wrong with having multiple heads - Mercurial is just checking it's what you want. In this case, you might want to keep the abandoned development path for future reference. If so, just force the push (with hg -f push) and create the abandoned branch. If you just want to forget everything about it, #Lasse's answer is just fine.

Related

Unexpected new head created

I am working with Hg and TortoiseHg on a project and pushing every couple of days to a remote repo on Bitbucket. When I tried to push changes today, I got an error saying that I was trying to create a new head. I thought this was odd since I am definitely the only person working on the project and I work from one PC.
I pulled to see what was going on on the remote repo and after pulling the local repo tree looks like so:
At the bitbucket end the repo looks like this:
Can someone help me understand why I got two heads if I'm the only one working on the project and why Hg is not recognising that Rev.40 and Rev.36 are the same revision?
How do I fix this now? If I strip 40 locally, what will happen when I try to push changes to the remote repo? Will it strip the revision at the remote repo too?
you can try this (on a clone repo if you prefer to be sure)
having a clean workgin directory
hg co 40
hg backout -r 40
hg merge 39
hg push
revision 40 would be the one that exists in the remote repo, before the amendment
so, you check it out, you back it out (put the inverse on top of it) then you merge your ongoing work (left at 39) and there should be no merge conflicts at all, since all changes are incoming
then, when satisfied, you push
===
why I got two heads
this part was already addressed in the comments, you realized you amended the commit after pushing it, thus the apparent duplicate of it
How do I fix this now?
you do a merge on your local repo, to get rid of the two heads, so having only one the remote repo won't complain about it
if you like, you can backout the before-amendment commit to be safe (or not, if you really know how to merge the conflicts making your local prevail)
but in both these cases, the non-amended commit survives, therefore it'll show up in your history, beware
If I strip 40 locally, what will happen when I try to push changes to the remote repo?
is gonna be there unless you strip it there (directly on the remote repo)
Will it strip the revision at the remote repo too?
no, it won't
As commit r40 is only present locally, there is no drawback in stripping it from your local repository - IF you are sure that it doesn't contain changes you want to keep. It won't propagate to your bitbucket repo then.
However, the two commits are not the same in the sense of the repo - they probably differ at least by a small time difference (if not some content, e.g. white space) - thus they are unique; only you can tell how they came into existence.

restarting a closed branch creates two heads, how to push that?

I created various branches which I closed as they were leading to nowhere. One of these branches is called v2. It was closed at some time in the past.
When developing further, I created another branch also called v2. Tortoise Hg warned me that this branch already exists and whether I would like to "restart it" or "commit to current branch". I asked to restart it.
More dev happens on v2 (several commits) and I decide to push to a remote repository which already has my project (including the previously closed v2). I then get the message
abort: push creates new remote head fce4441f5150 on branch 'v2'!
hint: merge or see "hg help push" for details about pushing new heads
I do not really want to merge (I assume that the message means "merge the old v2 with the new v2") as these branches do not have much in common. I closed v2 as opposed to leaving it hanging because I was not expecting to use it anymore. (the self whipping about reusing names comes later in the question, no worries about that)
This leaves me with new heads. hg outgoing shows me what I expected to happen ...
# this is the first commit for the new v2
changeset: 221:ba47b76010ef
branch: v2
user: w <w#home>
date: Fri Jul 18 14:42:08 2014 +0200
summary: New version: all frames are subclasses, frames are organiz
# some more commits for the new v2
# last commit for the new v2
changeset: 225:fce4441f5150
branch: v2
tag: tip
user: w <w#home>
date: Wed Jul 23 13:17:19 2014 +0200
summary: added manualstart.sh
... but v2 (the old one, closed) is already present in the repository:
Where should I go from now?
Should I force the creation of a new head on the remote repository? I do not like the --force parameter as it costed me a lot of cursing in the past. I want to make sure that it is OK this time.
or something else?
Overall I learned that it is not a good thing to reuse branches previously closed, is that correct? Or is it OK provided I take some precautions?
You are right, that it isn't a good thing to reuse branch names.
I see two ways to accomplish what you need - none of them is really "nice".
1) There is the -f option you already mentioned.
If you are afraid of pushing multiple heads, try pushing in steps:
hg push -r <close commit of old branch>
hg push -r <parent of 221>
hg push -f -r 221 --new-branch
hg push
2) The other option would be to do a No-Op-Merge from the old to the new branch.
hg update -C 221
hg merge v2
hg revert -a -r 221
hg commit -m "old is marked as commited"
But be aware that this might cause problems with future merges, because all changes that are in the old v2 are marked as merged, even if they came from sidebranches or similar.
For future reference, another option is to strip the old branch out of the repo completely. Thus allowing you to push the new branch without any issues.
hg strip <start of old branch>
This is a great option if the old branch wasn't merged into anything. Only negative is that you have run the command on all of the clones.

Mercurial hg pull hg up hg merge heads blah blah the whole process not very clear

We are using Kiln as our mercurial server and I there are three developers working on the same repo and i get this issue often and I am not quite sure what is happening.
Every once in a while I will do an hg pull.
Then when I run hg up I get the following message
abort: crosses branches (use 'hg merge' to merge or use 'hg update -C'
to discard changes )
ok so I run hg merge and I get
abort: outstanding uncommitted changes (use 'hg status' to list
changes)
ok so I run hg status and I get something like this
! Safemail 3.0\CSM3.0\AddinSetup\Release\AddinSetup.tmp
! Safemail 3.0\CSM3.0\Outlook2007Addin\Outlook2007Addin_TemporaryKey.pfx
no idea what to do with that.
If I run hg commit again it says no changes.
Finally if i run hg heads I get
changeset: 51:daea74a29d5c
tag: tip
parent: 49:b88e6e522672
user: Rahul Chandran
date: Mon Jan 23 13:30:54 2012 -0800
summary: added login code
changeset: 50:cb6f6e1eec5e
parent: 46:d83431c322ad
user: dthompson#Jabberwock.lan
date: Mon Jan 16 22:10:11 2012 -0600
summary: Adjusted Email-PDF formatting
Clearly I do not come from a DSCS background and I am probably missing some basic understanding of what is going on . Any help appreciated.
What I do know is that the code that my co worker checked in via a push has like no files in common with my changes. I would not expect like a merge conflict or some such in a non distributed source control system . essentially I am having some trouble understanding what is happening here exactly
Check out the help for hg status. It will tell you that ! means:
! = missing (deleted by non-hg command, but still tracked)
So you deleted some files that are tracked in your repository. If you didn't mean to track them in the first place (they look like good .hgignore candidates) you can hg forget FILENAMES; hg commit them. If, instead, you do mean to track them you can hg revert FILENAMES them (to get them back into your working dir from your repository.
Once hg status agrees you have no uncommitted changes you'll be able to hg merge.
Consider taking a little time to read the first few chapters of the (free) Mercurial book. These basic concepts are easy when presented well and in order, but horribly frustrating when you try to pick them up piecemeal from google searches and Stack Overflow questions. It's worth the 30 minutes to save you hours.

Mercurial merge branches? (abort: push creates new remote branches)

I'm new to Mercurial, and I made the mistake of making different changes on different systems before the main repository was up to date. (I understand this is what Mercurial is built for, but my thick brain is struggling to resolve the issue.)
Now on my primary development server, everything is up to date and committed. However...
$ hg push
abort: push creates new remote branches: 4f2672f039d7!
(use 'hg push --new-branch' to create new remote branches)
I don't really want a new branch. I just want all the changes to be merged.
$ hg heads
changeset: 459:ff5f94e44aba
branch: 4f2672f039d7
tag: tip
parent: 458:e63d02baf4cf
parent: 455:267abda62069
user: mike#...
date: Tue Sep 13 14:25:16 2011 -0400
summary: Images from prof
changeset: 455:267abda62069
parent: 453:a74757e26357
user: mike#localhost.localdomain
date: Tue Sep 13 09:08:12 2011 -0400
summary: images for FLC
Point me in the right direction?
EDIT: (adding detail)
When I try to merge, I get the following result:
$ hg merge
abort: branch '4f2672f039d7' has one head - please merge with an explicit rev
(run 'hg heads' to see all heads)
I have tried hg merge ff5f94e44aba, and all of the revs listed above, and each one returns the same result:
$ hg merge 267abda62069
abort: merging with a working directory ancestor has no effect
It looks like you've accidentally created a branch with a silly name. What you most likely want to do is reapply your changes with a branch name that makes better sense. There's no totally automatic way of doing this, but you can extract each changeset as a patch, revert to the point where you messed up and reapply those changes on the proper branch.
Basically what you need to do is look at the changelog; probably by running hg out to see what's missing from the central repository. Make a note of each of the revs that you want to keep.
Next update to the last good revision. Make sure that you are on the branch you wanted your commits to be on.
Now you will apply each of the changes you made and commit each one. You can automate this process something like this:
BADREVS="123 124 125 126"
recommit() { hg di -c $1 | patch -p1; hg ci -m "$(hg log -r $1 --template '{desc}')";}
for rev in $BADREVS; do
recommit $rev
done
Now you've got your changes in your local repository twice; once as the commits on the weird branch and again on the right branch. You can push those changes to the central repo using hg push -b GOODBRANCH so that only the changes to the right branch go up; Alternatively, you can install the strip extension to remove the changes you didn't want from the local repo and then you can push as normal.
By the sound of it; you will still have to deal with the changes made to the central repository before you can push, since you pushed changes from another repo. You probably want to do this merging after you clean up the change history in the local repo.
Pull from remote and then update / merge / commit first. Then you won't make new branches.
I've had this happen when I missed a merge. I like the TortoiseHg workbench for this because it can be a little easier to find what you missed through visualization.
A good way to avoid this in the future, how I stopped getting this error, is the fetch extension. Set your post pull to fetch and it will automatically merge for you, which is very nice. If there's a conflict it brings up whatever conflict resolver you use.

How to create new head on commit?

I'm working on my thesis and storing changes in mercurial. I'm not getting an error that I've got multiple heads, which I'm confused about -- I've only got one working repository which I push occasionally to bitbucket. Here's what happened:
$ hg commit -m "Fixing up..."
abort: No such file or directory: /Users/me/Dropbox/thesis/thesis_tex/simple.pdf
$ hg commit -m "Adding in page headers"
created new head
...one more commit, not having realized that having created a new head was a problem...
$ hg push
pushing to ssh://hg#bitbucket.org/...
searching for changes
abort: push creates new remote heads!
(did you forget to merge? use push -f to force)
$ hg heads
changeset: 26:3823a395b1ce
tag: tip
user: me
date: Fri Aug 26 09:39:45 2011 -0400
summary: Adding...
changeset: 24:c7c6517d4281
user: me
date: Thu Aug 25 16:34:42 2011 -0400
summary: Fixing up...
How can I easily get rid of the other head, without messing up my working directory? Why did a second head get created? Is there a problem with keeping mercurial repositories in dropbox folders?
How can I easily get rid of the other head, without messing up my working directory?
Merge the branches with hg merge.
Is there a problem with keeping mercurial repositories in dropbox folders?
This seems redundant to me, since Dropbox keeps a 30-day history on your files. I'd choose either Hg+Bitbucket (or whatever Mercurial hosting) or Dropbox, but not both.
Edit: Why not use Mercurial and Dropbox? Here's why.
Ben Hughes said it well:
By keeping your Mercurial repo on Dropbox you’re version controlling your version control system files. If you somehow manage to cause a conflict with files in your .hg directory, things could get messy. Recoverable, but messy.
I disagree with #Matt Ball on the dropbox matter.
I think redundancy is your friend. Also the purpose of Hg and the dropbox is slightly different in your case.
Dropbox backs up for you automatically (as well as tracking file changes and letting you work on any machine with internet and making it easy to share your work.) and Hg lets you work offline and commit in logical chunks (as well as working as backup when you sync).
I have used Hg in my dropbox folder without problem for at least a year and I have not experienced any problems.
If you work on more than one machine and have the dropbox/Hg combo on all machines I suggest that you let dropbox do the syncing.