How to remove accidental branch in TortoiseHg?

后端 未结 5 1495
再見小時候
再見小時候 2021-02-12 10:06

(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 th

相关标签:
5条回答
  • 2021-02-12 10:15

    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.

    0 讨论(0)
  • 2021-02-12 10:19

    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://hg@bitbucket.org/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://hg@bitbucket.org/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://hg@bitbucket.org/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? :)

    0 讨论(0)
  • 2021-02-12 10:26

    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".

    0 讨论(0)
  • 2021-02-12 10:36

    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.

    0 讨论(0)
  • 2021-02-12 10:37

    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.

    0 讨论(0)
提交回复
热议问题