Valerij
Valerij

Reputation: 27738

switch branches in hg while preserving files

While developing my software i create a set of test-cases which an be automatically done via make tests. To keep things organized i put those in a sub-directory tests. To keep my commits organized as well and not to clutter my development branches, i created an extra branch tests where i commit the test units.

My problem is: when i commit the units to the test branch and switch back to development, said tests are deleted

D:\Project>hg branch test
D:\Project>edit...
D:\Project>hg add
D:\Project>hg commit
D:\Project>hg up dev
2 files updated, 0 files merged, 3 files removed, 0 files unresolved

How can i preserve those files? (i tried the solution for Mercurial: Switch working directory to branch without losing changes? but it still deletes the files)

EDIT See my own answer below

Upvotes: 0

Views: 888

Answers (3)

Lazy Badger
Lazy Badger

Reputation: 97270

when i commit the units to the test branch and switch back to development, said tests are deleted

It's expected and correct result: branches store diverged lines of development, you add something only in test branch, before merge this data will exist only in branch on creation

In order "To keep my commits organized as well and not to clutter my development branches...", but have tests in development branch you can use at least two ways:

  • Periodically merge tests branch to development (all changes in tests will appear in development), but use log only for changesets in development branch, maybe without mergesets from tests. It's rather simply revset, you can even write log command with revset into aliases and use aliased command when needed
  • As Ry4an mention, you can instead of branch-separtion, perform repository-separation with subrepo|guestrepo technique - if tests are stored in subdir of main repo, convert /tests into nested repository -> subrepository and have two independent, but linked repos (future reading: Subrepository in Mercurial wiki and Subrepositories in Mercurial Kick Start Exercises)

Upvotes: 2

Ry4an Brase
Ry4an Brase

Reputation: 78330

Those test files don't exist in your development branch, so when you check out the development branch they won't be in the working directory. DVCSs like Mercurial and git don't let you have one directory checked out at one revision/branch and another one at another revision/branch.

The answers to which you linked are for bringing the changed and their files over into another branch, they're not what you're asking for.

So the way you want to do it (separate branches) isn't going to work, but there are plenty of other/better options

One choice would be to make your tests a patch that's managed by a mq (Mercurial Queues) repository, which can itself be versioned. Then when you where in your dev branch and wanted to run the tests you'd do:

hg qpush # tests show up
... run tests, edit tests ..
hg qrefresh  # save the changes you made to the test
hg qpop  # tests vanish again

MQ is poweful, but sometimes a little hard to wrap your head around.

Another choice would be to make your tests a parent repository and your actual code a child repository of that parent. Your disk layout would look like:

parent/
   tests/
   existingrepo/   # <-- the repo you already have w/o tests

Then people could clone and you could push the existingrepo w/o tests, but the outer repo would include a pointer to it and the two would be versioned in lockstep. Again, sort of tricky, but has some nice results.

The third option, and my preferences is to get over the "To keep my commits organized as well and not to clutter my development branches" mentality. Tests are just as important as the primary code, they should be versioned with the code, and they're not cluttering anything, they're providing valuable tools to help comprehend what the code is doing. You can always use hg log --exclude tests/ to see a history that excludes them when that's convenient.

To take that plunge just do:

hg update development
hg merge tests

and you're good to go.

Upvotes: 4

Valerij
Valerij

Reputation: 27738

to achive what i wanted i eventually created a subdirectory for the repo:

project/
  main.cpp
  makefile
  .repo/
    .hg/

and created a new make target:

REPO := .repo

init: $(REPO) $(REPO)/.hg

$(REPO):
    mkdir -p $(REPO)

$(REPO)/.hg:
    hg init $(REPO)

commit : | $(REPO) $(REPO)/.hg
ifdef BRANCH
    hg -R $(REPO) update -C $(BRANCH)
endif
    find . -regex "^\./[^.].*" -exec cp --parents {} ./$(REPO) \;
# the regex prevents "hidden" dot-folder from copying
# one could use --link to save time and drive usage/space
# but i am concerned about hg auto merging and overriding (per hardlink)
# my actual changes
    hg -R $(REPO) commit $(EXTRA)

so i could just issue make commit BRANCH=tests to commit to arbitrary branch without losing all changes not relevant to the branch. Implementing of hg add as wipe .repo, copy file there hg -R .repo add $(filename) is left as exerciser for the reader

Upvotes: 0

Related Questions