Check out only a directory from mercurial? - mercurial

How can i check out only a sub directory from mercurial repository? It seems i can only check out the whole repository.

No, you cannot. See the discussion here:
https://www.mercurial-scm.org/wiki/PartialClone

You can't do it. The feature is planned, but not implemented. The previous person gave a nice link to where you can read a discussion about the partial clone feature.
For now, you should just be really careful to divide things up so a repository is a fairly small unit that makes logical sense to manage in one piece. The existence of the ability to have subrepos might help you organize and manage things until that feature exists.

The next best thing is using the Convert extension as discussed here:
https://www.mercurial-scm.org/wiki/ConvertExtension
It's also useful to filter Mercurial repositories to get subsets of an existing one. For example to transform a subdirectory subfoo of a repository foo into a repository with its own life (while keeping its full history), do the following:
echo include subfoo > /tmp/myfilemap
echo rename subfoo . >> /tmp/myfilemap
hg convert --filemap /tmp/myfilemap /path/to/repo/foo /tmp/mysubfoo-repo

This is the same question as How do I clone a sub-folder of a repository in Mercurial? so the answers there and here are going to be same. I'll summarize them:
"It's not possible".
"Convert the original repository to only contain the directory you're interested in" (but it will no longer be possible to push changes from it into the original repository).
"Convert your main repository into several repositories (using the above) and use Mercurial's subrepository feature to make them act like one" (having to use subrepsitories is considered a Mercurial feature of last resort though).
"Clone the whole repo but do a narrow checkout of only a directory" (needs Facebook's sparse.py third-party extension installed).
"Clone only the history (and by extension the contents) of a specified directory" (needs Google's third-party NarrowHG extension on the client and server).
Terminology notwithstanding (the original question was asking about only "check out" which can only happen after cloning in Mercurial but Subversion doesn't really have the concept of cloning) the NarrowHG solution is arguably the closest to what was desired.

Related

Automatic shelve before pulling in Mercurial (with TortoiseHG)?

I have some changed files I don't want to commit (e.g. web.config). Before I pull and update to new changesets, I have to shelve them. After the pull & update, I have to unshelve them.
I'm currently using TortoiseHG. Is there any extension which can do this automatically?
I'd suggest something else: instead of always shelving and unshelving, you could use two different config files: one which is part of the repository and contains dummy/example data, and another one which each user really uses locally, which is ignored by Mercurial.
Check out this answer for a more detailed explanation what I mean.
The example I'm giving there is for Visual Studio, and I see from your other questions and answers that you're apparently using .net and Visual Studio, so you can just use my example exactly as written.
In Mercurial, just hg pull -u. Uncommitted changes are merged with the tip. Same result as shelve, pull/update, unshelve. With TortoiseHg a dialog will come up prompting for discard/shelve/merge.
You may get a merge dialog this way but that would be true with the shelving approach because unshelve may have to merge as well. From the command line you won't get a prompt if there are no conflicts. TortoiseHg may have an option to suppress the dialog if there are no conflicts, but I haven't checked.
I would try a few different things with this.
Regarding the Web.config file in particular, you might want to look at using local configuration files for overrides instead of leaving local changes uncommitted. (e.g. referencing an separate file that is in .hgignore). Projects I've worked on in the past did this to separate test/prod configurations from the settings for development, or vice-versa.
I don't think there is any extension which will do this for you, but you might be better off writing a quick batch or powershell script to do this workflow for you. On previous projects, I had a script which would do something similar in that it would do a pull/update/rebase to keep my changes at the tip (I was working with hg against an SVN server which made that important.)
I know I didn't answer your question directly, but I hope this helps!
Direct answer: https://pypi.org/project/hg-autoshelve/
But a dedicated repository for configuration files seems a better idea as suggested by
Christian Specht there

mercurial temporarily ignore versioned files

My question is essentially the same as here but applies to mercurial. I have a set of files that are under version control, and one save operation changes quite a lot of files. Some of the resulting changes are important for revision control, and some of the changes are just junk. I can "partition" off the junk into separate files. These junk files need to be part of a basic checkout in order for it to work, but their contents (and changes over time) aren't that important for revision control. Right now I just tell all our developers not to commit these files, but we all forget and it creates a lot of extra baggage in the repository. I don't really like the svn solution proposed because there are quite a lot of files and I want a simple clone to just work without all this extra manual work, so I was wondering if mercurial has a better alternative. It's kind of like hg shelve but not quite, and kind of like ignore, but not quite. Is there some hg extension that allows for this? Can git do it?
Mercurial doesn't support this. The correct way to do it is to commit thefile.sample and then have your developers (or better you deploy script) do a copy from thefile.sample to thefile if thefile doesn't exist. That way anyone can update the example file, but there's no risk of them committing their local changes (say their personal database connect string).
Aha! So TortoiseHG's repository and global settings have an Auto Exclude List where you can define a list of files that will be unchecked by default when the status, commit, and shelve dialogs open. So they still show up, but the user has to check them in order to actually do a commit. The setting is stored in hgrc, but it's under the [tortoisehg] heading so it's not supported by mercurial per se. Nevertheless, it fits my needs.
One solution to this is to use nested tree support (submodule in git), where the "junk" would be put in a different repository (to avoid cluttering the main repo), while enabling checking out the whole thing out in a consistent manner (right version of both repos in sync).
https://www.mercurial-scm.org/wiki/Subrepository?action=show&redirect=subrepos
In git, submodules are one solution to this issue - but they are not that great UI-wise. What I do instead is to keep two completely independent repositories, and using the subtree merge strategy when I need to update the main repo with the junk repo: http://progit.org/book/ch6-7.html

mercurial: "Cloning" just one file from one repository into another one?

I've got a perl project's mercurial/hg repository here with a lot of modules. Now, I've realized that some of the modules, a branch of modules, does not fit into this project anymore but would be better suited in another project.
So, is it possible to "clone" these modules from repository1 into my other repository2 while keeping these modules's revision history and at the same time flagging the modules in repository1 as "removed"?
I think it is possible with a number of steps. But I think cloning the whole repo1 and then removing all the unnecessary files would clutter my new repo2 with a lot of unrelated revision history. Still, as I understand the "clone" and "pull" commands neither of them is suited to clone just a slice of another repository, right?
Or is it possible to "move" a file from one repository into another? As I see it that's the analogy of what I want to do..
Absolutely! Take a look at the Convert extension, specifically the Mercurial-to-Mercurial section which should do exactly what you want.
After you've split off those modules, you can use hg forget, hg remove to remove them from your original repository, or even use hg convert again to create a new repository without them.

How do I permanently remove (obliterate) files from history?

I commited (not pushed) a lot of files locally (including binary files removing & adding...) and now when I try to push it takes a lot of time. Actually I messed up my local repo history.
How could I avoid this mistake in the future ? Can I transform a set of local revision 1->2->3->4 to 1->2 with 2 being the final revision of the local clone ?
edit: since I was in hurry I started a new remote repo from scratch with revision 4. In the future I will go with the marked answer as it seems easier but I will dig other solutions to see the truth. Thx for your support.
It's not clear from your question whether those changes got pushed. If they're still local, you can more or less get rid of them easily. convert is one option. You can also use MQ (mercurial queues). Check the EditingHistory wiki article for a detailed explanation. It recommends MQ being the simplest approach.
To prevent that kind of mistakes, you should probably add a hook to reject 'bad' commits, given that you can describe them programatically ;)
Mercurial history is immutable, you can't delete using the normal tools. You can, however, create a new repo without those files:
$ hg clone -r 1 repo-with-too-much new-repo
that takes only revisions zero and one from the old repo and puts them into a new repo. Now copy the files from revision four into the new repo and commit.
This gets rid of those interstitial changesets, but any repo you have out there in the wild still has them, so when you pull you'll get them back.
In general once you've pushed a changeset it's out there and unless you can get everyone with a clone to delete it and reclone you're out of luck.

Fetching a single file from another mercurial repository [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Mercurial: copying ONE file and its history to another repository
I have several repositories in my local machine.
One is my main code, another is an assortment of useful code/tools.
These are two fundamentally different repos. It might make sense to setup a new repo and pull these two in as sub-repos, but I want to wait until Mercurial devs mark sub-repos as non-experimental before I do that.
One of the useful code files has become so useful, I want to put it into my main code area...but I want to maintain its history. This will, of course, result in some variant of a fork, but that's acceptable. (best case would be being able to push-pull it back and forth and keep updating its history).
I'd just use the subrepo feature that came online in 1.3. It might change slightly, but you won't be left high and dry backwards compatibility wise.
If you can't bring yourself to so, then what you need to do is:
use hg convert with a filemap that deletes all files except the one you want and convert from the repo with the single useful file to a new repo containing only that file and all its history
then hg pull from the new single-file-full-history repo into the target repo
hg merge in the target repo and you'll have that file with all it's history
The other option would be to hg export the entire tools repo, use grepdiff (part of difftools) to limit to only one file, and then import into the target repo, but that's crazy.
The short answer is you can't copy a file and its history simply, as stated in this thread:
https://www.mercurial-scm.org/pipermail/mercurial/2009-April/025105.html
I'm relatively new to DVCS and you really have to think of each repo as a self contained package. Not like svn or p4, where you can hang different projects off the root and configure it how you like and do partial repo checkouts. (That said, I really like the flexibility of being able to clone repos quickly to try things out. And being able to commit on a local machine.)
I'm just looking at a similar problem. I've branched a repo to make changes and I only want one file out of one changeset. And it is nice to have the history.
You could look at:
hg cat
This would probably involve writing a script to transfer history, i.e. commit N changesets in the target repo with the hg cat results from the source. Wonder if there is an extension to do this?
You could get the log of the file you want to copy and paste that into a commit comment. It's not in the metadata, but you do have a record and all the hashes etc.
may be
hg export
also can help you.