How to permanently tell Mercurial to not commit a modified versioned file? - mercurial

I have a file default.config in the root of my repository. I tweaked it for my own setup, and I do not want to commit it. Ever. What are my options other than commit -X "^default\.config$"?
I added ^default\.config$ to .hgignore, but it still shows up in the output of hg status -mard.
Edit: maybe it's possible to do this with Mercurial Queues. If I keep all my local config changes in a single patch, then I just have to remember to pop it before committing. Just thinking out loud...

Follow these steps:
Copy the file somewhere outside your working directory
Remove the file with hg rm default.config and commit the changes
Copy back your file to the working directory
As a good practice you can add a file called default.config.template or something which is committed to the repository. This file holds some kind of default values or comments on how to use it and other users/developers can copy this file to default.config if they're using your project.

Akluth has the correct answer: commit a template file to your repository and then copy that to the real name in each working copy. If the config file supports it, then use an include directive to load the template file from the real config file. Something like
// default.config
//
// load defaults from versioned template file
#include "default.config.template"
// override defaults with my settings
db_hostname = localhost
db_user = me
An alternative is to use -X with every command, as you suggest. There is an exclude extension that implements this idea. Remember to read the caveats — it doesn't work when merging because you cannot exclude files when committing a merge. The extension would need to be extended to handle that case, probably by shelving change before the merge and unshelving it afterwards.
This suggests another stragety, similar to using MQ as you suggest: use the new shelve extension in a set of pre- and post- hooks to shelve/unshelve the file before/after each operation. I think that could work, though I haven't tried it in real life.

Related

Using .gitignore file to hide appsettings.json does not actually hide it

I have a C# MVC .Net Core application I'm building, the connection string is in a file called appsettings.json so what I want to do is simply exclude this from my git repository. I have added the following line to the git ignore file:
appsettings.json
I have also tried:
**/appsettings.json
But neither seem to work, the change I've made to the appsettings.json file still appears, am I missing something fundamental here?
This is a common misunderstanding about the way .gitignore works we all met at some point when working with Git: .gitignore will ignore all files that are not being tracked yet; indeed, files that are already being tracked in your Git repository are not ignored by your .gitignore setup.
To fulfil your need, it would be sufficient to untrack the files that you desire to ignore, i.e. in your case the appsettings.json file.
As reported in your question's comments, this has been answered already here. Then, your .gitignore setup will work as you would expect.
Adding an entry to your .gitignore file won't remove any files that have already been added to your repository. You need to remove them manually. For this you can use the rm command:
git rm --cached project/appsettings.json
Every answer in this thread misses the point: Being able to ignore changes on a tracked file.
You do not want to completely untrack this file as this would make you send the deletion of the item on the remote next time you push and thus delete the file for every of your collaborators, which you obviously do not want.
What you're looking for is actually perfectly possible in git, while a bit hidden:
git update-index --assume-unchanged <file>
which will precisely ignore the changes on a tracked file.
Now you can modify your appsettings.json file all you want and git won't bother you with it, and won't upload the changes when you push to the remote.
This is the official reference of git look at here
it says:
The purpose of gitignore files is to ensure that certain files not
tracked by Git remain untracked.
To stop tracking a file that is currently tracked, use
git rm --cached

mercurial and local properties file

We just switched to Mercurial from SVN. I have some local properties file like jdbc.properties that refers to my local database and is never checked into repository. When I try to pull files Mercurial complains there are uncommited files. How to best deal with this situation
Regards
If you never want to commit jdbc.properties to your repository, you should ignore it.
Check out the link for more information - in short, you'll have to create a text file called .hgignore in your working directory, and input the files names of the files you want to ignore.
Then, you'll never see the files again when you try to commit, and Mercurial won't complain about uncommitted files anymore.
If the application won't work without the config file and you want some version of it in the repository, you might not want to ignore it.
Because if you do, you can't just clone the repository and start your app - it will complain about the missing config file.
Plus, you probably want to have your configuration files under source control as well - just without "secret" data like usernames and passwords.
Maybe this approach is something for you then.
The example shown there is in MS Visual Studio (because that's what I'm using), but you can something similar in any other stack.

How to prevent ignored files from being removed?

I version controlled a project settings folder a couple months back on my default branch, and then over time created many branches off default. Now I've decided that I'd rather not have the project settings folder version controlled as it creates a lot of problems when switching between branches.
So I've hg forget'd this project settings folder which lets me keep the files on my local machine but removes them mercurial. However, when switching from one of the old branches which still have this folder versioned back to the default branch it actually removes the files from the local machine, which is bad.
How do I prevent that?
The folder is also in .hgignore on default now.
It's impossible to do.
But the common practice is to keep config.ini.dist in your repository and build environment-specific config by some build-system right after you check source code out.
The standard way to deal with this is to version control a template config file and ignore the real config file. The real config file can then include the template file, or maybe the template file is copied over once in a while.
The underlying reason for your problems is that running:
$ hg forget config.ini
is exactly the same as running:
$ hg remove config.ini
$ hg cat config.ini > config.ini
The forget command leaves the file behind in your working directory, but what you commit is still a file removal. This means that afterwards, Mercurial cannot distinguish between "file was forgotten" and "file was removed" — only the removal is committed, so the two commands look exactly the same.

How do I make files with a specific extension be added to a commit automatically?

I'm trying to figure out how to automatically add all files of a certain extension (for example *.tex) to the commit dialogue (the checkbox should already be checked! I don't want to search for the new files every single time)
I tried adding *.tex to the auto-commit list (=comma separated list) but that doesn't do anything.
Mercurial has so called hooks to do stuff automatically on certain events. See also the hgrc documentation and the Mercurial wiki page on Hooks.
Your task can be done with a pre-commit hook, defined in your repository's hgrc file:
[hooks]
pre-commit = hg add -I "*.tex"
Before a commit, this hook automatically adds all not yet tracked tex files in the root of the repository's current working directory. Adjust the value of the -I option or add more -I options to specify more complex patterns of files to add automatically.
Note: I don't use TortoiseHG, so I cannot say if this hook causes any checkboxes to be pre-selected. Anyway, it should also work if you commit with TortoiseHG.
In hg as console application this very simple solution works, too:
hg add "*.tex"

hg convert - trying to move a directory from one repo to another

So I have a directory called flash. I'd like to move it totally from an existing Mercurial repo located at ~/wdm to another existing Mercurial repo, located at ~/wdm-js.
I've been told this is possible with hg convert, but I don't really know how this works. I have tried the following, but think I may have got something wrong.
Having read up on the hg convert for Mercurial docs, I've created a filemap, which reads as follows:
include flash
Then I've gone to ~/wdm and run the following command:
$ hg convert . ~/wdm-js --filemap ~/filemap.txt
I've seen a load of output as follows:
scanning source...
sorting...
converting...
413 [doc/design][m]: first stab at a design doc for model (sent to list).
[412 more history items]
So this looks fairly promising. But when I look at wdm-js there is no flash directory there. And none of the flash directory files have moved from the wdm directory. And the hg status of both repos looks no different.
Do I still have to copy the flash directory across manually, and hg add/hg remove all the files manually to both repos?
Or... should this have been done for me, meaning that I have messed up in some way?
hg convert doesn't update the working directory in the destination repository (it leaves it at the original null revision), so do a hg update there to see the files. Also, the way you ran it, it copies the files; you can either delete them from the original repository via hg forget or hg remove, or use hg convert again using a filemap with the line:
exclude flash
To copy into existing repository you need first copy flash folder into new repository as you did it with convert command and then push the changes from new repository into existing target repository.