Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how push a bunch on changes as single one in mercurial

As I understand one of the main advantages of distributed revision control system like Mercurial is that you should not worry about breaking something in your super-important main repo (which is used by quite a lot other developers), and do all you work and researches in your personal remote clone until you understand that everything stable and you can push your work back. And hence I got my question: if it possible to push back not all your changes history (with several revisions which you made for yourself), but only one which is actually diff between your repo and current state of master.

One example:

hg init master-repo; cd master-repo  
echo -e 'Important file\nWith Bug!' > file  
hg commit -A -m "initial commit"  
cd ..; hg clone master-repo hotfix-repo; cd hotfix-repo  
echo "fix1" >> file  
hg commit -m "first attempt to fix bug"  
echo "fix2" >> file  
hg commit -m 'Fixed it!'

Now (possibly after pull and merge with newest master-repo' changes) I want to push back only one changeset containing all changes that I've done without my local commits history. One possible solution is to create one more clone then use diff/patch between two clones to extract/apply changes from first one and commit them all at once in second repo. Then do push as in normal case. But is it possible to so using only mercurial commands?

Thanks in forward!

like image 732
east825 Avatar asked Mar 03 '12 22:03

east825


People also ask

How do I revert a committed change in Mercurial?

Reverting Local Changes If you use the TortoiseHg client to work with Mercurial from TestComplete, you can cancel all local changes not committed to the repository yet: Select File > Source Control > Revert from the TestComplete main menu.

What does hg commit do?

hg commit creates a snapshot of the changes to 1 or more files in the local repository. Always write a log message when committing changes. hg diff displays differences between revisions. hg revert recovers old versions of files.


2 Answers

Opinions differ on whether or not it's good to collapse trial-and-error changesets into a single changeset before pushing:

  • Pros: you avoid having changesets in your history where your test suite fails — those changesets are bad for hg bisect and add noise.

  • Con: you cannot collapse changesets that you have published to other repositories — doing so would only rewrite your local changesets and you would then have to clean up the other repositories manually.

Technically, it's perfectly safe to collapse a set of changesets into a single changeset before pushing. You start with

... a --- b --- c --- x --- y --- z

and you rewrite this into

... a --- b --- c --- w

where w has exactly the same repository state as z had (but a different parent changeset, obviously). There are no merges here (and hence no merge conflicts) so it cannot fail.

After rewriting, you can pull and merge with the upstream (d and e):

... a --- b --- c --- w --- v
                 \         /
                  d ----- e

You need an extension to do any kind of history rewriting. Here I would suggest one of:

  • Collapse extension: as the name implies, this extension is dedicated to collapsing changesets.

  • Histedit extension: full-fledged history editing, but the fold command let's you collapse changesets.

  • Rebase extension: this standard extension can move changesets around and collapse them at the same time. In the example above, it would move x --- y --- z after e:

    ... a --- b --- c --- d --- e --- x' --- y' --- z'
    

    You can then optionally collapse x' to z':

    ... a --- b --- c --- d --- e --- w'
    

    Compared to just collapsing x to z, rebasing does involve merges so it can fail.

like image 84
Martin Geisler Avatar answered Nov 15 '22 09:11

Martin Geisler


Intro

I think, rewrite history and send/get "polished" changesets (in Git-boys style) is, in common, bad idea - history is history, it have own value.

After all, for "mainline" branch (you use branches, isn't it), all your changes will be presented as one mergeset, regardless of changesets count in branch

Short answer

No. In Mercurial you pull/push and get&accept full set of changesets, which created difference in repo history

Long answer

Somehow you can, by rewting your history of changesets before exchange to "other side". Just remember - each changeset represent not new state of object, but diff between old and current (if describe it shortly), thus - by ordinary removing changests you can get wrong final result.

Anyway, you have a lot of ways to rewrite own history (as extensions):

  • Collapse
  • History Edit
  • MQ (with mq-patches per se, folding changesets in mq-patch and splitting the same way)
  • Maybe some others, unknown for me
like image 24
Lazy Badger Avatar answered Nov 15 '22 08:11

Lazy Badger