How to remove accidental branch in TortoiseHg?
Asked Answered
M

5

22

(I am a relative newcomer to TortoiseHg, so bear with me :-) I use TortoiseHg on two machines to talk to my remote source repository. I made changes on one machine, committed them, and attempted to push them to the remote repository BUT I forgot to first do a pull to get the latest code first. The push gave me a few lines of output, suggesting I may have forgotten to pull first (true!) and mentioned something like "abort: push creates new remote branches...".

So I did a pull, which added several nodes to the head of my graph in the repository explorer. The problem is that the push I tried to do is now showing as a branch in the repository explorer. Looking from the server side (codeplex), it shows no sign of my attempted push, indicating this accidental branch is still local on my machine.

How could I remove this accidental branch? I tried selecting that node in the graph then doing "revert" but it did not seem to do anything. I am wondering if it would be simplest to just discard my directory tree on my local machine and do a completely new, clean pull from the server...?

Medicable answered 3/6, 2010 at 4:3 Comment(0)
D
18

First make sure you have committed all your local changes. Then merge the branches by calling hg merge and commit the result.

This should bring you back to a single branch, reuniting the two heads.

Downstage answered 3/6, 2010 at 4:17 Comment(8)
That sounds like the branch will still be there, yes? I am hoping to completely remove the branch, since I have not yet made it permanent on the server.Medicable
@msorens: The two changesets that were committed "in parallel" will remain that way, but does it matter? With the merge, the two branches will be joined together in a single top revision. From then on there will again be only a single newest revision, even though it has a short fork into two branches in its predecessors.Downstage
@msorens: I agree with sth. After a while using Mercurial, you realize that trying to keep your revision history squeaky-clean just isn't worth the trouble. It doesn't matter that the changesets are out of sequence between your server and your local repos or that you've got a short-lived anonymous branch (both of which are to be expected if you have more than one person working on a project).Virescent
I agree with what you are saying but, yes, I think it does matter--in this case. Again I am new to TortoiseHg so correct me if I am wrong: Right now, this branch is only on my local repository. Why pollute the permanent record (on the server) with this superfluous branch? It just adds "noise" for no reason. So if there is no command within Mercurial to prune the branch it still seems to me that I should just discard my local directory and do a fresh pull. Is there any disadvantage to doing this?Medicable
@msorens: the only disadvantage is that it's more work for you, including having to manually merge the changes into the fresh local repo.Virescent
@msorens: I agree with the guys, just leave it. :) I'm sure, however, that a lot of folks will chime in with other answers suggesting you use 'hg strip' or 'hg clone -r' or histedit or mercurial queues. Any of those will do, but when you see what a hassle they are you'll invariably say, "I can't believe there isn't an easier way to do this," and everyone will chime in with "that's because it isn't supposed to be easy." That's the usual pattern any way, and we all went through it. Philosophically mercurial is about an indelible record of work, sort of like scientists always writing in pen.Blotter
Points noted; thanks to all for your feedback, and I will be more careful with my "pen" ! :-)Medicable
We've done some pretty crazy stuff with branches we abandoned but the important thing to realise is that after just a few commits on the branches you wish to keep alive, the 'messy' history falls away and isn't really an issue! Embrace it, ha ha!Opening
T
7

I had a branch I didn't want, but found I could not merge the branch (or it was very difficult for me to figure out how to merge) because it contained a conflict based on a file name case change.

Ultimately, I decided to hg commit --close-branch. Since the branch had existed only on my local repo, and not the repo I had cloned from, the subsequent hg push didn't even bother to push the closed branch out to the master repo! Very convenient. At that point, all I had to do to eliminate it entirely was delete my local repo and re-clone from the "master".

Trainload answered 2/10, 2012 at 19:46 Comment(0)
A
5

Do a "Merge With" and check "Discard all changes from merge target (other) revision". Of course you should make sure that the target shown as the merge target is really the one you want to throw away before you click the Merge button.

Adabelle answered 22/9, 2010 at 3:1 Comment(2)
This would throw away the questioner's edits, which I don't think was the intention of the question.Skinny
thats what i thought to, but look at the revision code references, the discard is done to the one you select to mergeHawes
S
2

In the Repository explorer, choose the first rev of your local changes, then right click on the tip of the branch you just pulled and choose "Rebase on top of selected" or "Modify history->Rebase on top of selected" depending upon your client version. This will "re-base" your revs on the pulled ones.

Additionally, to help avoid it in the future...

In Repository Explorer, choose Tools->Settings. In the top left drop-down, choose "User global settings", so this applies to all repositories. Then choose Synchronize on the left. In "After Pull Operation" choose "rebase". This will cause your local revisions to be "rebased" upon the revisions you just pulled, rather than leaving them in a different branch.

This is how I do it and is probably what you typically want.

For more info, see the rebase project and the rebase extension.

Selfabsorbed answered 4/6, 2010 at 13:44 Comment(6)
[I am splitting this in 2 comments due to SO restrictions.] I like the notion of this. Just a couple things: First, no such option on my context menu. The RebaseExtension page provided the answer--enable it by putting a couple lines in the configuration file, which can be found by referring to section 5 of the Mercurial manual. I did that and than ran a rebase: it complained about unsupported file types for two files ending in .orig which were created by the rebase operation itself! It then indicated it aborted so I could fix the conflicts, and said to run "hg rebase --continue" when done...Medicable
[Part 2 of my split comment] But since I am running in TortoiseHg not the cmd line, not sure how I would do the "rebase -- continue" operation... Lastly, the confirmation says, in my case, "rebase 14 on top of 6?". That seems backward to me: 14 is the pulled main branch; 6 is my local branch.Medicable
@msorens re: Context Menu - It's kind of awkward. You must first choose one rev by left clicking, causing it to be highlighted. Then choose the next by right-clicking, which should then show both revs highlighted and give you the rebase option. If it's not showing up for you, sounds like maybe another question.Selfabsorbed
@msorens re: backwards - I told you the wrong order. I have now corrected by answer. Sorry. I'm not sure what to do about continue. For this one time, you can run the Windows command line. I believe TortoiseHg installs this as well. (If not, you should install it anyway. It comes in handy sometimes.)Selfabsorbed
kyle: you misunderstood my comment on the context menu not appearing--I tried to explain that it was a problem but that I fixed it by enabling it in the configuration file.Medicable
In TortoiseHg 2.4.1 I cannot see a "Rebase on top of selected." option. When you right-click on a revision, there is "Modify history" -> "Rebase..."Skinny
C
0

This is how to do it with the command-line tool. I guess it can be easily mapped to TortoiseHg (although I'm not sure, since I never use it...) Anyway, since it should be done just once in a while, I think there is no problem on using the terminal here.

An example setup

Suppose your remote repository is something like this:

@  changeset:   3:a4c18a1fba12
|  tag:         tip
|  summary:     commit 4
|
o  changeset:   2:91c5dbfba15c
|  summary:     commit 3
|
o  changeset:   1:4c77cb7952ea
|  summary:     commit 2
|
o  changeset:   0:085dae46f27e
   summary:     commit 1

Locally, you did not have commit 4, so you committed something directly over commit 3:

@  changeset:   3:39526003350f
|  tag:         tip
|  summary:     commit 4 made locally
|
o  changeset:   2:91c5dbfba15c
|  summary:     commit 3
|
o  changeset:   1:4c77cb7952ea
|  summary:     commit 2
|
o  changeset:   0:085dae46f27e
   summary:     commit 1

So you try to push it, and get this message:

$ hg push
pushing to ssh://[email protected]/brandizzi/mercurial-test-repo
searching for changes
remote has heads on branch 'default' that are not known locally: a4c18a1fba12
abort: push creates new remote head 39526003350f!
(pull and merge or see "hg help push" for details about pushing new heads)

As requested, you pull it:

$ hg pull
pulling from ssh://[email protected]/brandizzi/mercurial-test-repo
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)

You have it now...

o  changeset:   4:a4c18a1fba12
|  summary:     commit 4
|
| @  changeset:   3:39526003350f
|/   summary:     commit 4 made locally
|
o  changeset:   2:91c5dbfba15c
|  summary:     commit 3
|
o  changeset:   1:4c77cb7952ea
|  summary:     commit 2
|
o  changeset:   0:085dae46f27e
   summary:     commit 1

... but you would rather not merge as requested. You want to have this instead:

o  changeset:   4:a4c18a1fba12
|  summary:     commit 4 made locally
|
o  changeset:   3:a4c18a1fba12
|  summary:     commit 4
|
o  changeset:   2:91c5dbfba15c
|  summary:     commit 3
|
o  changeset:   1:4c77cb7952ea
|  summary:     commit 2
|
o  changeset:   0:085dae46f27e
   summary:     commit 1

And then you want to push it to the remote repo.

How do you get that?

Solving it

To get that, you cannot have pushed the "commit 4 made locally". Also, there is no way to put it after the new remote commits. Said that, we can get what we asked.

Said that, you just need to rebase your local commit onto the new remote commit:

$ hg rebase --source 3 --dest 4

If you are lucky, that will be enough.

Handling conflicts

If you are unlucky, you may have some conflicts:

$ hg rebase --source 3 --dest 4
rebasing 3:39526003350f "commit 4 made locally"
merging test.txt
warning: conflicts while merging test.txt! (edit, then use 'hg resolve --mark')
unresolved conflicts (see hg resolve, then hg rebase --continue)

Then, just resolve the conflicts (by manually editing them):

$ hg st
M test.txt
$ nano test.txt # Edit and save

...mark the file as resolved...

$ hg resolve --mark
(no more unresolved files)
continue: hg rebase --continue

...and proceed with the rebase:

 $ hg rebase --continue
rebasing 3:39526003350f "commit 4 made locally"
saved backup bundle to /home/adam/software/mercurial-test-repo/.hg/strip-backup/39526003350f-64863882-backup.hg

Here is your new history:

@  changeset:   4:ca31fe8a15f0
|  summary:     commit 4 made locally
|
o  changeset:   3:a4c18a1fba12
|  summary:     commit 4
|
o  changeset:   2:91c5dbfba15c
|  summary:     commit 3
|
o  changeset:   1:4c77cb7952ea
|  summary:     commit 2
|
o  changeset:   0:085dae46f27e
   summary:     commit 1

Now, push it:

$ hg push
pushing to ssh://[email protected]/brandizzi/mercurial-test-repo
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files

Those days, it is not as complex as it used to be, right? :)

Cornelie answered 11/11, 2016 at 9:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.