开发者

Mercurial: Pushing a changeset without its ancestor

开发者 https://www.devze.com 2023-04-04 09:40 出处:网络
I have a \"Default\" branch that comes from another repository. I have my work in the branch \"Mytask\".

I have a "Default" branch that comes from another repository.

I have my work in the branch "Mytask".

When I was fi开发者_如何学运维nished with my work, I pull from the remote repository the revision 7. I merged from my local changesets 6 with 7 and committed to 8.

           Rev  Branch

    *      8    Default
    |\ 
    * \    7    Default
    |  |
    |  *   6    Mytask
    |  | 
    |  *   5    Mytask
    |  |
    *  |   4    Default
    |  |
    * /    3    Default
    |/
    *      2    Default
    |
    *      1    Default

Does anyone know if it is possible to only push revision 8 to the remote repository without pushing also my Mytask branch with the changesets 5 and 6?

Any feedback welcome!


Take a look at the answers to this question about squashing commits. squashing is the key word in this case.

There is a collapse extension that looks like what you want to do as well as other links on that question.


From what I understood by your question, it feels like you want to have the same state of the remote repository as that is of your local repository. Also you don't an extra branch over there, you want a linear history and also a single commit.

Let's look at two things first, merge and rebase.

Initially you cloned stable, you committed your own changesets which are x and y, you pulled changesets from the remote repository which are a,b and c. Now your history looks something like this.

stable -> a -> b -> c
        \
         \-> x -> y

Merge

You want to have your repository in such a state than you want to have a single head. You opted for merge. You did hg up -r b and hg merge -r y, resolved merge conflicts if it were there. Now your history looks like this.

 stable -> a -> b -> c -> d
        \             /
         \-> x -> y -/

Now you have a new commit d, which is a merge commit. The current state of your repo after updating to d contains changes from both the parent branches.

Rebase

Rebase is an extenison in Mercurial which you can easily use by adding a line to your .hgrc. Lets see what happens when you do hg rebase -s x -d c on the intial state we had. You history looks as follows.

stable -> a -> b -> c -> x -> y

In this case you have a linear history and both your changesets x and y are there on the stable branch.

Conclusion

A strong reason why people tend to use rebase of merge so that they can maintain a linear history, which helps a lot in sharing changes with other repositories.

In your case, you can undo your merge commit either by hg rollback or hg strip if that merge commit has no children. In case of childrens, you have to rebase them on y, then strip the merge commit, then rebase the whole chain from x onto c.

From the DAG in the rebase section(above) you can easily push x and y. If you want a single commit instead, you can use histedit extension or fold command which is part of evolve, both of which can collapse/merge/join/squash/fold those two commits into a single commit and your resulting history will be like this.

stable -> a -> b -> c -> z

Where z contains changes from both x and y changesets.

Related Links

  • Rebase Extension
  • Merge
  • Histedit Extension
  • fold command in evolve
0

精彩评论

暂无评论...
验证码 换一张
取 消