6

I'm new to DVCS so I'm probably misunderstanding some concepts and terminology, but this is the idea of what I'm trying to achieve, and I'm trying to find out if either Bazaar or Mercurial supports this in a straightforward manner:

There is main repository with well-tested code. Say I clone (or pull or branch or whatever the terminology is) from that into a local repository, then every day as I work on the code I commit changes locally, sometimes multiple times a day.

After I'm done with all my changes and testing, I want to get only the latest (locally) committed version of every file put into the main repository, without the dozens of intermediate versions that I committed locally during debugging and unit testing.

From what I've been reading, apparently the entire history of those half-baked versions would get reflected in the main repository if I push to it. Some internet articles seem to suggest that rebase might address that issue if it's handled right, but it's not so clear if/how that can be done, as it seems like rebase is more for avoiding a bifurcated branch/merge history than for avoiding the committing of a large set of intermediate versions.

Martin Geisler
  • 72,968
  • 25
  • 171
  • 229
Gigatron
  • 1,995
  • 6
  • 20
  • 27

3 Answers3

5

The keywords you're looking for are collapse or fold (Mercurial) or squash (Git). I'm afraid I don't know what the usual term is for this in Bazaar.

In Mercurial you can use the histedit extension (a bundled extension since Mercurial 2.3) to fold a series of changesets into a single changeset. It provides a superset of the functionality in the third-party collapse extension.

The rebase extension (another standard extension) has the same functionality with the --collapse flag. You're completely right that rebasing is normally done to avoid unnecessary merges, but it somehow also got to be used for collapsing (and editing) changesets in Git. The histedit extension for Mercurial is modeled after the interactive rebase commmand in Git.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Martin Geisler
  • 72,968
  • 25
  • 171
  • 229
  • Unfortunately many of the Mercurial history editing extensions have problems if you have done things like merge from the mainline into your branch along the way. – Krazy Glew Jul 21 '12 at 04:09
  • Unfortunately as well, folding changesets in Mercurial with `hg histedit` or `hg collapse` looses information about file renames, and therefore the edit history of a renamed file. (It appears like a new file with the whole content as recently being added). – Iodnas Dec 10 '12 at 17:21
  • @lodnas: I'm unable to reproduce this with `hg histedit` -- please file a bug report with instructions for how to trigger this: http://bz.selenic.com/ (I haven't tested the collapse the same way, it's a third-party extension and may well be more buggy than the now standard histedit extension). – Martin Geisler Dec 11 '12 at 08:42
  • Thanks a lot! I've answered you on the bug report. – Martin Geisler Dec 11 '12 at 13:00
5

Some bazaar options.

  1. If you want to get rid of the dozens of local commits, you are actually throwing away history. One way of doing it is with the bzr uncommit command. eg.

    bzr uncommit -rbranch:https://url_to_mainrepo
    

    (Throw away rivisions until you get to the revision of the main repo. Don't worry it will show you what will be done and confirm with you before doing it)

    Then you can do a new commit with all the others collapsed into one.

  2. Bazaar normally hides merged revisions. One way for you to roll up your tiny commits into a merged revision is to keep a local branch/checkout of the main repo. Then when you are ready, bzr merge in your changes into your local main-repo-clone and then commit a merged revision.

    This way you still keep all your history but all the little revisions are neatly rolled up into a merge revision. You can then still see that history when you want.

Here is examples of how to not see merged revisions:

$ bzr log
------------------------------------------------------------
revno: 2 [merge]
message:
  summary of the things I did
------------------------------------------------------------
revno: 1
message:
  some change on the mainline
------------------------------------------------------------
Use --include-merged or -n0 to see merged revisions.

Here is examples of how to see merged revisions:

$ bzr log -n0
------------------------------------------------------------
revno: 2 [merge]
message:
  summary of the things I did
    ------------------------------------------------------------
    revno: 1.1.2
    message:
      my first step
    ------------------------------------------------------------
    revno: 1.1.1
    message:
      my second step
------------------------------------------------------------
revno: 1
message:
  some change on the mainline
AmanicA
  • 4,659
  • 1
  • 34
  • 49
  • You said it's "normally" hidden so that means not always hidden? ... with option 2, after the merge and commit to the main repository is done, will the file contents of the locally committed intermediate versions before the merge be accessible in the main repo via indirect means (e.g. log files)? – Gigatron Feb 02 '12 at 02:03
  • added examples of how to see or not see merged revisions – AmanicA Feb 02 '12 at 14:19
  • OK, so the comments and metadata can be seen in the logs, but the actual file data of the half-baked locally checked-in versions won't be visible in the main repo, correct? – Gigatron Feb 02 '12 at 20:21
  • Yes, you only send the changes when you merge it into the mainline. It will be possible to get at any of the revisions but since you send everything in one go, the mainline will remain stable. – AmanicA Feb 03 '12 at 18:45
  • Mercurial by default shows the intermediate revisions on a branch, but you can train it (or your users) to do "hg log -b default" so as not to look at the intermediate revs on branches. ("default" is Mercurial's nmae for the trunk.) //Or "hg glog -r '0..default', or the like – Krazy Glew Jul 21 '12 at 04:03
1

In Bazaar, this is handled by having a separate "clone" (i.e. bzr branch URL) of the main repo locally and then you create local feature branches from that in which you do your work with multiple commits. When you're ready to move that work into the main repo, you bzr merge the feature branch into the main branch. That leaves you with a modified working tree in the main branch which you then commit and push to your official main repo. This commit includes the revision history from your feature branch but it's normally hidden in bzr log or other log history views.

dOxxx
  • 1,540
  • 1
  • 12
  • 28
  • You can accomplish the same thing with named branches, without having to have an extra clone of the main repo locally. At least in Mercurial, and I believe git. (Also in CVS and SVN, but that's not what you were asking about.) You may just need to train the other users to do "hg log -b default", so that they only look at the history of the main branch, and not the task branch with all of your intermediate checkins. – Krazy Glew Jul 21 '12 at 04:01