I've got a solution in which I'm trying to create a 2nd executable. These two executable share most of the same files, but have a few different ones including resources and application icon, etc.
I created the 2nd project, and added the items as links.:
Right-click "Add existing item",
Browse to it,
Click the "Add" drop-down and select "Add as link".
Adding as links means that it just references the other file in the other folder and does not copy it.
Now, when I tried to commit my project VisualSVN / SVN tried to do an SVN add on those files in the logical path they belong to resulting in lots of errors that the file was not found. It caused the entire commit to fail and was a major pain in the ass.
Is there a good way I can add links to files without side-effects? All the files I'm trying to link to are already in the same repo.
Update
Maybe I should add more information about what I'm trying to accomplish because I'm open to any suggestion which helps me accomplish it.
I have a project structure something like this... Or I want it to be like this...
MyProject
/Common
BusinessDataObjects (svn:external)
ControlsLibrary (svn:external)
OtherCommmonLib1 (svn:external)
OtherCommonLib2 (svn:external)
/Modules
Module1
Module2
Module3
...
Application1
Application2 (shares all App1's files, except different .resx, icon, name, other minor differences)
SetupProject1 (includes app1 and certain module dlls)
SetupProject2 (includes app2 and certain module dlls)
The application is basically an empty shell (using Prism) which loads the modules installed in a /modules folder. I want both applications to be almost identical, but I want them to have different names and a different icon. I thought I could accomplish this by adding the files from the first project to the second as a link, and simply swapping a resource file which included the strings for the application window title, About dialog, etc. But then VisualSVN or whatever tried to SVN Add those items which I wasn't expecting.
I need to be able to develop the modules and the application's shell project. They are not stable in any way yet. I just want them to near copies of each other but with minor naming differences. I figured with two application projects, I could have two setup projects that included the output from each application and whichever modules are supposed to be included in that version of the software program.
I was trying to make this as foolproof as possible, and I'd like to avoid having to update external references to the same project. (I'm a bit confused about that as well, would I svn:external to the same repo?) That doesn't sound good, but this was my main idea on how to create two almost identical apps. I'm not sure how else I'll do it if I can't get my version control software to behave.
I had suggested oringally we only have one version of the software and have certain modules be upgrades, but there are some good reasons they can't really do that.
When you add a file to a Visual Studio project with "Add as link" it's expected that the file is not copied to the project's folder.
VisualSVN considers status of items in your working copy, even files which are not included in the current solution. However a linked file does not exist in a working copy, thus can't be tracked. It's out of version-control.
Since the files you attempt to link are already version-controlled (i.e. they exist in the SVN repository) it makes sense to use Externals Definitions (svn:externals property) to link them.
Also see TortoiseSVN Manual; it's description of svn:externals is really good.
You don't mention your environment. However, you mention you have a Solution. I'm assuming it's VisualStudio you're using.
Have you tried AnkhSVN which is a Source Control Provider for Subversion for VisualStudio? AnknSVN integrates into VisualStudio much like Microsoft's native version control systems of Visual SourceSafe and TeamFoundation. I believe you can use AnknSVN to do the linking you want since these links are really internal VisualStudio structures and not actual symbolic or hard links like you find in a Unix system.
I usually avoid links (I believe they're called Junctions on Windows) because they simply don't work across operating systems. Instead, you can use one of the following methods:
Use your build system to copy the files, or create the required links rather than your version control system.
Use svn:externals to do the linking. Careful with this because svn:externals are pointers to a Subversion URL.
For example, if I setup http://foo.com/svn/trunk/proj1 to have a svn:externals link to the head of http://foo.com/svn/trunk/proj2, and I create a tag for Project 1 by copying http://foo.com/svn/trunk/proj1 to http://foo.com/svn/tags/REL-1.2/proj1, that project is still pointing to the head of the trunk of proj2. Changes in Project 2 will change what I thought was a stable tag. Always point your svn:external to a stable revision.
I have no experience with VisualSVN, we use Ankhsvn which does not have that problem.
http://ankhsvn.open.collab.net/
Related
I am wanting to setup a project and potentially an existing project to be SVN version controlled. I am using uberSVN for the svn server. I have installed AnkhSVN for visual studio.
Currently, the team I am working with is using visual source safe and one of the problems we have is when someone adds a reference to a DLL, it modifies the project file as you would expect, but our paths are different between different team members (XP boxes, 7, you get the idea). What I was wanting is making the project file ignored when checking in/out so that we don't mess up the references for everyone else.
Is there a way I can make SVN ignore these files within the plugin? One of the side effects of this is a person would not know if a new file has been added in the project as this modifies the project file. Other than telling everyone "hey, you need to manually add this file to your project," is there a cleaner way of doing it?
If you copy the DLL to a folder inside your VS solution folder before linking to it, I think the project link will be relative not absolute. So you can check the DLL and the updated VS project into your configuration management and everyone should be able to share it.
You should start using virtual paths for development work; that way each team member can keep work-related files at any physical location but the virtual path (the one seen by tools is always the same.
For example, my team does all work under Q:\. My physical source for work is under physical path C:\Work\<project_name> where the project_name part depends on the project. When I want to work on a given project, I map the Q:\ virtual path to the right physical path using
subst q: c:\work\project_name
When I need to switch, I run a similar command. This way there's no need to worry about different paths on different computers. This worked very well for the whole team and eliminated most issues you describe above. The only thing you need to make sure is that everyone always uses the virtual path (Q:), not the physical path when dealing with project-related files. For my team it took about a week to get used to that, after that there were no more problems.
Your project file is an important part of your project so ignoring it in the source control tool will eventually lead to problems. I recommend you don't do it (even if you can).
Edit:
If you have DLL-s in different physical folders on different machines, the best choice is to copy those DLL-s (and their dependencies) to a known location. It's fine that they can't run from there, as long as the compiler finds them.
This known location could be inside your virtual path or a common physical path (if the same DLL-s are needed for multiple projects). You can use Dependency Walker to determine what dependencies you need for native DLL-s and Reflector for .NET DLL-s.
If the size/number of DLL-s is so large that creating a copy is not an option, you can actually tell AnkhSVN to ignore certain versioned files when committing changes. Right-click the file, select Subversion > Move to Change List > ignore-on-commit. After this the file will show up in the commit dialog unselected but you can still commit it if you manually select it.
I could use some advice.
I'm in the process of adopting subversion, and I'm trying to put some existing Visual Studio 2010 projects into a repository. I have the current version of AhnkSvn.
The projects I have are organised as;
VS2010_projects\Project_A
VS2010_projects\Project_B
VS2010_projects\Project_C
VS2010_projects\Common_code
Where Project_A, Project_B and Project_C may all refer to one or more files in "Common_Code"
In visual studio, these files will have been added using "add as link".
There is no actual project in "Common_code" just a collection of useful code files, which we're likely to re-use in different projects.
(If we have a module or class which is re-used in various projects, then we often keep a single master copy in 'common-code', and link to it.)
Visual Studio has no problem with this.
When I add any of the actual projects to subversion, all of their own files are added just fine, but the linked files are ignored.
(And as a consequence, if I then get a working copy of those files, then it's just the project files which get handled, I won't get a copy of the linked files.)
If I right click on any of the linked files, I the only subversion options I get are to refresh their status or to select the working folder.
I was wondering what the correct way to handle this situation was ?
Any advice would be much appreciated
Thanks !
Robert
if I understand your question correctly then I think SVN is acting in the desired way. A linked file is merely a reference to another file. That reference exists only in the .csproj file which is checked in. It would not make sense to have two copies of the same file in source control, and it could lead to versioning issues. The first time you checkout your repository doing a build on your projects should copy the files from Common_code to the places that they're linked.
As an aside we've had alot of random issues with .csproj linked files and SVN, and so try to avoid linked files where possible. A better way to re-use files across projects is obviously just to embed them in a library and then reference that library. This should work fine with the exception of certain files like Javascript/CSS.
Also you may want to check out SVN externals, a workmate mentioned this can be used to share common libraries between multiple projects, although as a disclaimer I haven't tried this myself and can't comment on the merits or drawbacks of the approach.
Thanks for the advice, I actually did something similar to your suggestion.
I didn't want to make a full blown library, but I did make up a dummy project, and put my shared files into that.
Then I added the dummy project to the repository.
AhnkSvn now seems to be satisfied that the linked files are under subversion control, and seems to handle them just fine.
(I haven't added any reference to the dummy project to my existing projects - they just use the linked files as before - but now AhnkSvn shows me their status, and allows me to get the latest version, and commit changes.)
I can see the case for having a proper library - but that would have meant modifying a large body of existing projects. This approach lets me get up and running with Subversion without requiring those changes first.
So I see two solutions to my current problem, but I was wondering what the pros and cons are, or if there is a defacto best practices approach.
So my current project has a number of configuration files, help files, and other external content. I need this content local to run and debug the application. Currently we duplicate this content in a standard windows installer project. This clearly is a bad idea. We are moving to a new setup that uses the WiX installer, and I'm currently setting the project up next to the code project and trying to figure the best way to share resources. I see two solutions.
One is that I can put all the resources in the WiX project and then add them as links in the code project. This way I know what I'm debugging is installer.
The other option would be to leave the content in the code project and path into it in the installer using the reference variables.
Right now it seems 6 one way, half dozen the other. Any persuasive arguments for either method?
Assuming that these configuration and help files are going to be installed in the same directory as the executables then definitely put them in the code project, mark them as Content, and add a reference to the code project to the installer project. If you're using WiX 3.5 the files will be automatically included in the installer along with the executables, which makes writing simple installers much easier.
For earlier versions of WiX or more complex deployment scenarios (where the content files could be going into different directories) you would still put them in the code project but then you'd use File elements with a relative path or reference variable in the Source attribute to include the the content files from the code project directory.
I don't believe that putting the content files in the WiX installer project directory instead of the code project directory will do anything to ensure that the version you use to debug will be the same as the version installed. That can only be ensured by thinking through the process of how your application finds these content files and making sure the right versions are found.
So going back to the simple case where the content is in the code project and marked as Content, and it will be installed and loaded from the same directory as the executables, then it is only a matter of setting "Copy to Output Directory" to "Copy always" or "Copy if newer" and then you can be sure the versions used in debugging and the version installed will match.
For a long time looking for a way to manage references, I haven't found any ideal way.
The main problems are:
1-) Should I include all projects that I use in same Solution and reference the Project? Or reference just the dll file?
2-) If I should reference dll file, the best way is to create a ReferencedAssemblies inside each project or a main folder at svn root?
3-) Its ok paste and reference dll´s inside bin folder of my project?
4-) Its ok add and commit dll´s inside bin folder of my project? This way when a new devoloper checkout the project, it will compile perfect, but isn´t default behavior of visual studio, all source controls ignore bin and obj by default, just adding .refresh files(for web-site project)
Someone can help me?
1) If you include projects in your solution that are already checked in somewhere else, you can change the SVN binding for that project at the solution level in Visual Studio. (File > Source Control > Change Source Control). You would change it to point to wherever it's located in your SVN repo.
2) If you have a lot of developers on different machines all wanting to use the same libraries, it's probably easier to have a common place for all your third-party libraries/assemblies. There's no point in having them copied all over the place in your SVN repository.
3) No, it's not usually ok to do this. I would avoid it (unless somebody has a valid reason for it).
4) Never commit your bin folders. The default behavior is such for a reason. The .refresh files are byproducts of the old Web Site projects and they are fine.
1) In the typical scenario yes, you should reference all projects that you own. But you should make a decision according to frequency of changes made to referenced projects. For example if you have an open source library it is better to include it as an assembly, cos you probably will not change this code frequently.
2) Typical approach is to create separate single directory at SVN root and place assemblies there in different sub-folders according to assemblies type. Here is how my current folder looks like:
3) No, it is better to reference assemblies from some other from bin folder. All referenced assemblies will be copied to the bin while building process. Also note that the purpose of *.refresh files in the bin folder is to prevent you from having to copy new versions yourself.
4) No, you should never commit your bin folder cos you can rely on *.refresh files for WebSites and just forget about this problem for other project types.
1) I'd argue it depends upon your particular situation, especially since Visual Studio is pretty flexible on what projects are included in solutions. (It's not tied to a directory structure.)
We have a couple applications that have one solution with a number of projects contained within (for each 'piece').
2, 3, 4) For referencing and including files within a project, why not just use the functionality built into Visual Studio? Adding references in this way adds the items to your csproj (vbproj) files.
(Based on my research, if you're not referencing a project that's part of the solution, put the DLLs in a directory everyone on the team can access and use that when adding the reference. In the project file it ends up looking like this:
<Reference Include="Elmah">
<HintPath>\\pathInformation\shared assemblies\ELMAH 1.1 32-bit\Elmah.dll</HintPath>
</Reference>
)
This also means that you don't have to commit DLLs; if anything changes the project file will be updated accordingly.
(I'll admit, I'm unsure about that last point. I've seen a lot of people check in external libraries, like ELMAH. I generally follow those who tell you to ignore the bin directory entirely.)
I have a couple of different solutions, in which some projects may depend on output from projects in other solutions. To manage this, I've been copying dll files from the /bin/ folder in each project to a shared library location after build, and then copy/reference them from there to the dependent project.
However, as the library solution gets larger, this tends to become unmaintainable. Too much of my time is being spent traversing solution directories in Windows Explorer looking for /bin/ folders, and trying to figure out which one, or which ones, of the dll files from each one I need.
Is there any way to give Visual Studio a hint that I want all projects in a solution to have the same output directory? For example, a /bin/ folder directly under the solution folder, where all projects put their output.
If possible, I'd like to achieve this without hard-coded post-build events that copy the files, since that will fail if a project output changes file name, or adds another file. I'd rather like to change the location of the actual output directory - the location of $(OutDir), if you will.
I know you said you don't want to use post build events, but your reason as to why not intrigued me. It sounds like you might be hard coding the name of the .dll in your post build event. That can easily be avoided.
xcopy "$(TargetDir)*" "c:\common\" /Y
The * would just cause everything in your bin/Debug/ folder to get copied to your common folder. You could also just copy dlls if you want. Or, if you use $(TargetPath), you'll copy just the 1 dll that is the result of the project, and not any other related dependencies.
UPDATE
The way we do it is each projects entire bin folder is copied to a subfolder. Suppose you have 2 projects, WebUtil and HtmlParser, where WebUtil depends on HtmlParser. For both projects, use xcopy "$(TargetDir)*" "c:\common\$(ProjectName)" /Y. This will create c:\common\WebUtil\ and c:\common\HtmlParser. In WebUtil, add a reference to c:\common\HtmlParser\HtmlParser.dll. There will now be 2 copies of HtmlParser.dll in c:\common.
c:\common\HtmlParser\HtmlParser.dll // the most recent build.
c:\common\WebUtil\HtmlParser // what was the most recent build when WebUtil was built
This has all kinds of advantages. If you change the API of HtmlParser, WebUtil will continue to work, since it will have the older HtmlParser.dll until you try to rebuild WebUtil (at which point you'll get build errors because of the changed API).
Now, if a 3rd project got in the mix that depended on WebUtil, and you're using some part of WebUtil that exposes classes in HtmlParser, then you'll need to add a reference to both projects from your new project. When you add a reference to HtmlParser.dll, use the one in c:\common\WebUtil. You do this because you're only including it as a necessary requirement of WebUtil. Now you'll always have the version of HtmlParser.dll that matches your current version of WebUtil.dll.
I hope that makes sense. It can definitely be a tricky thing to manage. Just wait till you have to start pulling down all your dependencies using svn:externals =P
You can set the output directory in each project properties.
Right click on the project, select Properties
For C#, it is one of the Build property page, under Output, Output directory.
In VB.Net projects, it is on the Compile tab, in the textbox at the top.