Mercurial: How to ignore changes to a tracked file
Asked Answered
N

8

53

I have a file with database settings in my project which I have set to some defaults. The file is tracked by Mercurial and checked in. Since this file will be edited with different values various developer machines, is there a way I can tell Mercurial to ignore new changes to this file?

I tried adding the file to the .hgignore file, but since the file is tracked it isn't ignored. This is alright and good in other situations, but I am wondering if there is something I can do here?

Nadianadine answered 18/5, 2010 at 11:3 Comment(0)
B
29

Using a file template is definitely the best solution. For example, if you have a database.ini file, commit a database.ini.template file and ignore database.ini in .hgignore

Bellis answered 18/5, 2010 at 13:9 Comment(8)
This is what I ended up doing :)Nadianadine
I realize this is very old now, but just in case - would you then have an install script that copies all template files to their functioning filename?Musjid
That would be a good idea. Don't forget to make your script ask for the configuration values, as they may differ from the template file, which is here to show the structure of the fileBellis
The really big problem with this approach is that it can screw up build processes - for example - when using msdeploy in .net you're deploying all files listed in a csproj file. Meaning if you want your db.ini file included in the deploy it needs to be listed in the csproj. BUT if you list it in the csproj, you won't be able to build a clean clone until you create this file even if the file is actually optional for the application to runMinisterial
@GeorgeMauer So the issue is that some process is expecting to get a fully-working file set-up by being pointed to a repository and downloading the files. Ideally it (msdeploy) would have an option to run a set-up/install script on the repository before using it. Or, you'd need to set up a special repository (or a branch), which is a copy of the main repository but with the .template replaced with real files, just for use with that process. Alternatively, there's an issue with msdeploy in that it only looks at csproj to know what to deploy. Maybe you can configure it to include others.Impolitic
An opposite approach, is to have people using the repo add a .local file and update the tools/anything that uses this file [if applicable] in their local copy (and get Mercurial to ignore these changes). This only works when the stuff that uses the file is configurable (can be pointed to the new local file). If you want them to change a .template file in their local copy (but any tools/anything that use this file [if applicable] doesn't work until they do), then see the [current] answer. In the one approach, the repo anticipates the change, and in the other the user creates it later.Impolitic
Eg. If the tracked file you want to ignore is .hgignore itself, you could add a .hgignore.local and configure .hgrc so it recognises that file too. See 1, 2.Impolitic
.template is better if the file is optional since it doesn't put the file in by default, and .local is better if the file is needed by default or immediately. If there are a lot of things that are tracked and using the file, then also prefer the .template approach because this will be less stuff for the repository-user to have to change in their local copy. .local is more ideal when what uses the file is not tracked and can be configured to use a different file, or you can't anticipate which files, or there are many files, that will be changed.Impolitic
F
27

If you always want to ignore the file, you can add the -X option as a default for commit to your .hg/hgrc configuration file:

[defaults]
commit = -X program.conf
Farad answered 1/9, 2010 at 7:14 Comment(3)
This is a really great idea, until you try committing a merge. When committing a merge, you are not allowed to specify files or patterns. So with that in your .hgrc,it doesn't seem to be possible to commit a merge at all without first editing .hgrc. Does anyone have a solution to that?Dignadignified
You asked this ages ago @Dignadignified but in case its helpful, a quick and dirty fix I use is to have a quick batch script that moves the repo hgrc out the way, does the commit and moves it back. It's obviously only going to work if there's nothing else in your hgrc that needs to be there.Benetta
@yitz I wonder if the reason it didn't work for you is because the file is supposed to be called hgrc, not .hgrc?Snafu
C
12

We wrote an extension for this called exclude. It will automatically add the -X options on the commands that support them -- so hg status and hg commit wont see the modified file. It works by reading a .hgexclude file from the root of your repository, just like the .hgignore file. You add the files that you want to exclude there:

syntax: glob
db.conf

The extension works quite well, but there is a known situation where it fails: merges and the commit that follows a merge (this is documented on the wiki). It would need to be improved so that it would save the modifications away to a temporary file and then restore them afterwards. Please get in contact if you need this feature.

Calculable answered 20/7, 2011 at 8:9 Comment(0)
I
9

There is no truly automated process, but you can try (as in this SO question) the -X option on hg commit:

% hg stat
M myfile
% hg commit -X 'myfile'

(other solutions might involve shelve or hq)

However, this is not the "right" solution. I would rather recommend versioning:

  • a file template
  • a script able to generate the final file (that you modify but can ignore altogether)
Indented answered 18/5, 2010 at 11:15 Comment(0)
W
6

If you are using TortoiseHG, open the Settings for the repo, go to the Commit section (2nd icon down on the left) & add the file name(s) to the Auto Exclude list on the right (~ 3rd from the bottom in the list).

From https://tortoisehg.readthedocs.io/en/latest/settings.html#commit

Wiser answered 16/2, 2011 at 21:48 Comment(6)
When you do this and run the commit UI, then the excluded file will be unchecked in the commit file list (automatically), and the DIFF will be in dark gray. Nice.Blacktail
I can't get this to work, I'm using TortoiseHg 3.3.3. I add the filename, full path, partial filename with * - it's always checked in the commit UI?Await
If it is already tracked (previously committed) then ignoring it won't affect it, you need to "forget" it.Wiser
allright @Await the next time you try to do this again, remember that tortoisHg doesn't like backslashes in paths, i.e this works: [tortoisehg] ciexclude = build/sol.sln. However this only works to not include the sln file in future commits, you still can't merge easily with the uncommited changes to that file in the working dir. :(Await
However! If you "forget" the file in TortoiseHg after adding it to the local ignore file, so fare that seems to be enough and not affect the central repo. - Bah it just shows up as removed, I guess the working directory isn't clean with that... :(Await
This looks like it's exactly the solution I need! Production versions of config files are checked into the Repo but I need customed stuff for development. If you are using TortoiseHG (v5.0.2), open the Settings for the repo (bottom of right-click context menu), go to the Commit section (3rd icon down on left), and add the file name(s) (comma separated, include relative paths) to the Auto Exclude list on the right (7 down from top, 8 up from bottom, on the right).Stroboscope
Q
2

Typically you would check in a reference copy of the file and track it then have the developers make a copy of that for local development, you wouldn't really want developers editing the source controlled file for their own environments.

If your configuration system supports it, it's even easier if you can use an override file that simply override values in the reference copy (e.g. the database connection string). That way devs only have to keep a very minimal local set of override values.

Quilting answered 18/5, 2010 at 11:19 Comment(0)
H
2

If the file is already being tracked, you can issue the Forget command to the file. If you're using TortoiseHg just right click the file during commit and select Forget. The file must also be already in the ignore list.

I had the same problem as yours, I file keeps on appearing on every commit even-though its already in the ignore list. I tried the Forget command and it did the trick.

Heterolysis answered 10/4, 2012 at 7:28 Comment(0)
W
2

You can try hg forget. For more details, see the official manual about the same command. It worked for me.

I think, something like this is closer to a correct answer to the original question Mercurial: How to ignore changes to a tracked file, rather than the others suggesting a template, etc.

Wheatear answered 4/6, 2013 at 11:30 Comment(1)
This answer is equivalent to Irish's answer. The problem with it is that hg forget removes the existing contents of the file from the repository, which the OP didn't want.Rubel

© 2022 - 2024 — McMap. All rights reserved.