0

I have done some local commits.

But I want to push the most recent ones like 4977 and 4978 excluding the previous ones.

4948 local commit 1 is the ancestor of all commits

Can some one tell how do we do that in HG

4978 local commit 4
  |
  |
  |
4977 local commit 3
  |
  |
  |
4976 local commit 2
  |
  |
  |
4948  local commit 1
Patan
  • 17,073
  • 36
  • 124
  • 198

2 Answers2

2

Mercurial repositories are intended to have immutable histories, so out of the box this is not possible. However, there are workarounds for this.

Possibly the easiest way to achieve this would be with the histedit extension. You would need to enable it by modifying your .hgrc (or mercurial.ini) with the following

[extensions]
histedit = 

Then you can run the histedit subcommand from the command line and tell it to look back as far as the changeset you're concerned about...

hg histedit 4948

This will pop up a text editor with the word pick next to each changeset. Change pick to drop for the changeset you don't want any more, save, and exit, and the problem changeset will be gone.

Note that this will remove the changeset from your local repo, in addition to prevent it being pushed to the remote!

mo.
  • 4,165
  • 3
  • 34
  • 45
  • +1 Nice complete answer. I would not call histedit a "workaround", it's just another tool in the Mercurial toolbox. – Martin Geisler Mar 13 '14 at 14:22
  • Thanks, that means a lot coming from you! And you're right... but, hmmm, could I get away with saying that technically I never actually called histedit a workaround? ;) – mo. Mar 13 '14 at 15:16
  • Yeah, reading it again, I think your answer is fine! I felt that "workaround" implied a problem, but I see that you didn't mean it like that. – Martin Geisler Mar 14 '14 at 13:32
1

You cannot push a commit with out pushing all the ancestor commits as well. However, you can "fold"/"collapse"/"squash" commits together to get rid of the ancestor commits you don't like. You use the standard histedit extension for this.

Simply run

$ histedit 4948

and you will see an editor open up. That edit contains a file that will serve as the instructions for histedit. By default all changesets are left unchanged, but you can change the keyword at the beginning of the lines to change this. Also, you can reorder the lines to reorder the corresponding commits.

Changing the keyword in the beginning of a line to fold will tell histedit to combine the commit with the previous commit. That way you can change your history to

4978 local commit 4
  |
  |
  |
4977 local commit 3
  |
  |
  |
4948  local commit 1

and thus "fold" the changes you made in your local commit 2 into local commit 3.

Martin Geisler
  • 72,968
  • 25
  • 171
  • 229
  • I don't think `fold` will achieve the result the asker is looking for. The changes originally in the folded changeset will still exist and will still be pushed. Also, I think just deleting the line containing a changeset in the text editor won't tell histedit to delete the changeset (that's what `drop` is for), but instead will tell histedit not to modify that changeset in any way. See my answer. – mo. Mar 12 '14 at 13:35
  • 1
    @mo. Thanks for the reminder about `drop`! You're right that `fold` might not be what the OP wants, but that depends on what you mean when you want to push a commit without the ancestors. Commits are *states*, so pushing a state without the ancestor states make no sense :-) – Martin Geisler Mar 13 '14 at 14:21