views:

721

answers:

2

We are using Scott Hansleman's suggestion for multiple web.configs from his post here. The problem we have is that we have to check out the Web.Config. If we remove it from the project, when we publish, no web.config is pushed. So we need to remove the source control bindings just from the web.config, but leave it in the project, and have the rest of the project still held under source control.

The issue is that source control makes the file read only until you check it out. We need to be able ot overwrite it with the prebuild events, preferably without having to check it out. Is there a way to remove the bindings from that file only, and still leave it as part of the project?

Thanks.

+2  A: 

By adding a new file to solution explorer, you will get the little plus sign indicating it is due to be added to source control. Then, right-click and choose "undo pending changes". This will cancel the add but leave the file in your project.

If that doesn't work I suggest one of the following methods:

apathetic
so, I need to delete the file, check it in, add a new web.config, and then undo?
Josh
Yeah, I would suggest deleting the file from source control first.
apathetic
Don't do this. It defeats the whole point.
Richard Berg
Actually, it's irrelevant whether the file is in source control because a script is being run to create the file. The files that are being put in place by the script will still be fully versioned.
apathetic
+2  A: 

You should leave the file in source control. Otherwise you'll run into several issues:

  • changes won't be versioned. 'nuf said.
  • it can't be branched or merged, even though web.config is one of the files that's most likely to vary between parallel dev/test/production environments
  • changes you make locally won't propagate to coworkers without manual workarounds
  • developers setting up an environment for the first time won't get the file at all
  • Team Builds won't contain the file, so neither will your deployments. (surely you're not deploying directly from the desktop?!)

Note that the state of individual files is stored entirely on the TFS server. ('tf properties' dumps this metadata if you're curious) Only projects & solutions have bindings actually written into the file. And even those are dummy entries that tell VS "don't worry about me, just ask TFSProvider, it'll know who I am and where I'm supposed to be." While there are many other quirks in the VS project system that give me endless headaches, in this case it's your friend. Don't circumvent it.

Best options:

  1. Edit your build script to toggle the read-only attribute before/after modification. If you're using the "copyifnewer.bat" script from the linked blog post, it should literally be one extra line. Even if you want to keep things entirely declarative within the MSBuild makefile, it's barely any work with the help of 3rd party tasks.

  2. Use the File -> Source Control -> Exclude feature. After applying this setting, the file remains under source control, but will no longer be subject to automatic checkouts/checkins by the active solution. In other words, you can edit the file locally to your heart's content without affecting anyone else, but if you want to commit (or shelve) your changes you'll need to do it from Source Control Explorer or the command line.

Option #1 has the advantage of being a very quick fix for your existing setup. The downside comes from maintaining several copies of web.config.* Same reason why copy/pasting code is bad: if you change one, you have to go change all the others -- or worse, forget and let them drift out of sync until strange bugs force you to revisit the issue. This could be improved by changing the process so that there's only 1 "master" web.config and the additional copies only contain differences (via a textual diff engine, XSLT transforms, programmatic manipulation in Powershell, etc). Of course, that's more work.

Option #2 avoids #1's problems with very little overhead. (the engineering process itself is unchanged; only difference is how the Visual Studio UI behaves) This advantage is critical if you make changes to web.config at all frequently. Downside is that there is no built-in way to track variations on the "master" file. If the only diffs are dirt simple, eg a connection string or two, you may find it easiest to stick with just one "master" and let people make ad hoc changes on their dev machines. There are even tools to do this for you, such as Web Deployment Projects (easy) and the IIS Deployment Tool (complex). In any case your actual deployment should be automated and source-controlled, of course! If heavier customizations are required than these tools are capable of, then you'll probably want the hybrid master + transform approach described earlier.

Richard Berg
I understand your point, Richard, but the web.config is merely a copy of 1 of 4 other files in the project, which are already under source control. The file is simply swapped out per environment depending on the build configuration. Having it in TFS is unnecessary because it's just a copy of what is already protected with version control, and a headache. Thanks for your input though!
Josh
No prob. I'd check out option #2 anyway -- it's one of those little known VS features that once you know it, you'll find invaluable -- even if not for web.config specifically.
Richard Berg
Exclude doesn't work, because when I publish, the web.config isn't pushed. It has to be part of the project, but not in source control so I can overwrite it.
Josh