Mercurial Conditional %include? - mercurial

I would like parent directories of projects to include an hgrc file that a repo in that folder inherits from, e.g.
~/work/
~/work/hgrc
~/work/project1/
~/work/project2/
~/personal/hgrc
~/personal/project1
~/personal/project2
~/personal/project3
Any project in work should inherit from work/hgrc, and any in personal should inherit from personal/hgrc. I was thinking of adding a script to ~/.hgrc that on clone would search for any hgrc files in parent directories and %include them if they exist, but this has the uglyness that if I add an hgrc below it after I clone it it won't be included. Only a 5% of the time consideration, but still...

How about putting:
%include ../hgrc
inside each repo's .hg/hgrc? You could even do that automatically but putting this in your systemwide /etc/mercurial/hgrc:
[hooks]
post-clone = echo '%include ../hgrc' >> .hg/hgrc
I've not tested that hook. :)

Following #Ry4an's suggestion, here is an example that works for me. I add this to my ~/.hgrc file so it works everywhere.
[hooks]
# This hook adds "%include ../.hgrc" to .hg/hgrc if the .hgrc file exists in
# the top level. This allows one to store a set of paths for example.
# See
update = if [ -e .hgrc ] && touch .hg/hgrc \
&& ! grep -q '%include \.\./\.hgrc' .hg/hgrc; then \
echo '%include ../.hgrc' >> .hg/hgrc; \
fi
This hook adds the line %include ../.hgrc to the .hg/hgrc file iff the file .hgrc exists in the top level of the repo. Note that by using the update hook, we bypass the issue of the with post-clone clone hook of having to try to figure out the directory name of the target clone from environmental variables.

Related

Mercurial how to ignore subfolder containing files already added to source control

I have a project with following structure
project_dir/
WebContent/
es5/
...
src/
...
.hgignore
I'm tring to ignore everithing under WebContent/es5 directory using following patterns:
syntax: glob
WebContent/es5/**
or
syntax: regexp
^WebContent/es5
or
syntax: regexp
^WebContent/es5$
but modified files in the folder are still being tracked. Could anybody please help me with it?
The clue is in the documentation for ignore files:
The Mercurial system uses a file called .hgignore in the root
directory of a repository to control its behavior when it searches for
files that it is not currently tracking.
If you've added a file in a subdirectory to the repo (either explicitly or before you added the pattern to the .hgignore file) mercurial will remember it until you hg forget it.
% hg init foo
% cd foo
% ls
% mkdir sub
% cat <<EOF > .hgignore
^sub/
EOF
% touch a
% touch sub/b sub/c
% hg st
? .hgignore
? a
% hg add sub/b
% hg st
A sub/b
? .hgignore
? a
% hg forget sub
removing sub/b
% hg st
? .hgignore
? a
There's an example given in the documentation on how to forget all files which are excluded by .hgignore:
- forget files that would be excluded by .hgignore:
hg forget "set:hgignore()"

TortoiseHG forget files in all sub folders of specific name

I have a pretty large folder (with many sub folders) on a mercurial repository. I was a bit too fast with my first commit so I added a lot of files that i now realize shouldn't be on version control. I've updated my .hgignore file accordingly but all the old files are still version controlled. Is there a command that I can write in the root directory that forgets all files that are in a folder of a specific name. These folder names exist in a lot of places and i want them all forgotten with one command since it would take a long time to go through them all manually and forget the folders/files
I guess it would maybe look something like this:
hg ignore ../folderName/
Yes... use a pattern to match them like
hg forget FOLDERNAME**
hg commit -m "Forget FOLDERNAME"
hg help forget
hg forget [OPTION]... FILE...
(...)
options ([+] can be repeated):
-I --include PATTERN [+] include names matching the given patterns
or use a one-line script:
for i in $(hg ma | grep FOLDERNAME); do hg forget $i; done
You can read hg help filesets and use one of it's samples
Forget files that are in .hgignore but are already tracked:
hg forget "set:hgignore() and not ignored()"

How to tell Mercurial not to look for root from ignored sub-directory

So here's the problem. I have my configuration file in my home directory ~ under Mercurial control. Part of the
|-~
|.hg/...
|-Dev
|-Project1/...
|-Project2/...
.hgrc
.hgignore
I have Dev directory excluded from the source control in .hgignore file.
However when I am in the directory ~/Dev/Project1 Mercurial thinks that I am in the under the source control. If I type hg root in any directory that is in the .hgignore or its sub-directory hg still considers it being a part of repository.
Is it a bug or a feature ?
UPDATE
So, here's the simple experiment one could do from the command line:
% mkdir -p /var/HgTest
% cd /var/HgTest
% hg init
% echo "this is a repository file" >> test.txt
% hg commit -Am "added repo file"
% cat <<EOT >> .hgignore
heredoc> syntax:re
heredoc>
heredoc> ^Dev
heredoc> EOT
% hg commit -Am "added .hgignore"
% echo "This is not in repository" >> Dev/notinrepo.txt
Now, Dev directory not in repository, if you type hg st anywhere under /var/HgTest it shows you that repo is clean. However if you go into Dev directory and type hg root it will output /var/HgTest. This is perhaps desired result. However, since the path should be ignored, I would think that hg root should effectively exit with -1 return code and message "not in repository" or something like that.
In my case, having HOME directory under source control effectively makes some of the tools consider every new directory (even under ignored paths) as a part of Mercurial repository located in the HOME directory.
It's a feature for when you are in ~/Dev/Project1/deeply/nested and want to keep mercurial commands within the scope of Project1.
A workaround is to hg init in ~/Dev/Project1. Part of the problem is the bad practice of putting your home directory under version control; I can see no benefit to be gained from it and much cost. As an example, almost everything you do with a browser, or music player, or many other programs is going to alter files in ~/.groovy-game/config or ~/.browser/cache-files; there is no meaningful way to choose a commit point. Because of this it would be better to establish good, incremental snapshot backups for $HOME, even if they are stored on the same machine.
This is not to say that dot-directories in your home should never be versioned. for example, suppose I hack on my ~/.vim files because I am working on the ultimate editing environment, cd ~/.vim; hg init can certainly be useful.
Put another way — so long as there is an .hg repository somewhere in the tree above you, Mercurial will seek it out and read the ignore file and not take action on ignored paths. However, hg root only looks for an .hg directory. In your case, there is always a root, you are in your ~ repository by definition. I don't see how it could be done otherwise; you can't find the ignore file until you've inspected the root.

Make .hgignore in a Mercurial repository available to all subrepos?

I have a Mercurial repository with several subrepos. Is there a possibility to only define a general .hgignore-File (e.g. to ignore object-files) both in the main repository and, optionally a specialized one in the sub-repositories?
There is not enough information in the manual. Specifying a .hgignore file with
[ui]
ignore = .hgignore
to .hgrc in my home-directory also does not work.
Any ideas?
A .hgignore file in each subrepo would serve as the specialized one for that subrepo. Then you can use the main repo's .hgignore as the main one by including this in each subrepo's hgrc file:
[ui]
ignore.main = \absolute\path\to\mainrepo\.hgignore
The reason why doing ignore = .hgignore didn't work for you in your global .hgrc (and won't in repo hgrc) is that having simply .hgignore is a relative file path and its resolution to an absolute path depends on the current working directory used when invoking hg. Examples:
If you're in \repos\main\ and invoke hg st, it will look for \repos\main\.hgignore. Same thing if you invoke hg st -R nested, because the current working directory is still the same.
But if you were in \repos\main\nested\ and then invoked hg st, the config would now be looking at \repos\main\nested\.hgignore.
If you want to specify a global .hgignore that is in your home directory, you would need to specify it with a non-relative path (or at least much less relative):
[ui]
ignore = ~\.hgignore

Can I set Mercurial config options programmatically?

I'm looking for a way to set .hgrc configuration items without actually editing the text file. I'm trying to standardize the setup of the hgrc across multiple developers and I would like a command like
hg --config ui.username=foo
but which also saves that config change into the hgrc file.
It seems like this should be something that should be supported directly in the vanilla hg command, but I can't find it anywhere.
Someone -- either you or Mercurial -- will have to edit the configuration file if you want the config change to be saved :-)
And if you can call Mercurial with
hg --config ui.username=foo
then you should also be able to do
echo '[ui]' >> ~/.hgrc
echo 'username = foo' >> ~/.hgrc
which will save the config change, not matter how the ~/.hgrc file happens to look like (it is okay to have multiple [ui] sections).
Mercurial 3.0 and later has the hg config --edit command that opens an editor with the user config file. Still not quite what you're asking for, but at least this makes it easier to edit the file interactively.
This form:
hg --config ui.username=foo
Doesn't save anything. It sets the value for just the one run.
Also you can use /etc/mercurial/hgrc for system wide settings if that helps anything.
There is an extension that helps with this, https://bitbucket.org/alu/hgconfig/wiki/Home
After installing that hgext, you can do things like this.
% hg showconfig paths
paths.default=ssh://hg#bitbucket.org/alu/hgconfig
% hg config paths.upstream $(hg showconfig paths.default)
% hg config paths.default $(hg showconfig paths.default | sed 's|/alu/|/nassrat/|')
% hg showconfig paths
paths.default=ssh://hg#bitbucket.org/nassrat/hgconfig
paths.upstream=ssh://hg#bitbucket.org/alu/hgconfig
The only gotcha is this overrides the builtin config command, you can either tweak the code to change the command name, or live with it. Fortunately, it probably would not matter if your use case is simply to set and get specific configs.