Sharing a file between multiple locations - windows

We are currently using Subversion (on Windows) for our source control but we examine switching to Mercurial. One problem is that we use externals in our repositories to share single files between multiple sub-projects. If one version of such a file is edited, the changes are propagated to each other version in our check-out. Is there a way to achieve the same in Mercurial, i.e. the same file in multiple locations? On Unix, this may be possible using some kind of links. But how about Windows?

Mercurial has the Subrepository features which is a little bit like svn externals.
The Mercurial feature is a more complicated than external in my point of view, but you can achieve the same goal with it and it is more flexible.
You can even use Subversion or Git repository as subrepo in Mercurial, so depending on what you're doing now, you could reuse your actual externals repo without any changes.
Everything is well explained in the linked documentation to have a good start with this functionnality !
BTW, symbolic links also exists on Windows : NTFS Symbolic link

Related

Store related files in Xcode project?

If I have an Xcode project that is version controlled and I want to keep related files together, would it be ok if I added them to a separate group in the project for as long as the files don't get included in any target? I am thinking Photoshop files and the like...
There is no technical reason why you couldn't do this. However, you should be aware that if you are using Git (which is likely since it sounds like you are using the Xcode integration), the Git doesn't deal well with binary files. It will cause your repository to be bloated, as well as the fact that you won't be able to merge these files at a later date.
That said, with tools like git-annex you can get around some of these limitations.

Add as link with VisualSVN

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/

Mercurial repository & MSVS - two projects & shared files

I am currently developping an application in MS VS2010 that's based on a client-server architecture with one project for each part in VS. Until recently, they both had their own repositories in Hg, but I decided to move them together as there are quite a few files that are now shared.
I have been using hard links to make sure that the changes on one file are propagated to the same file in the other folder/project. However, if you clone the repository or check out from the online repository, the hard links are broken.
I have read up as much as I could on both soft & hard links with Hg, and neither of them seems to be a good, portable solution at this point. What method of sharing the files between the two projects would you recommend, keeping in mind that I would ideally like a clean structure that is also reflected in VS?
Best regards,
Max.
You could use Mercurial's sub-repository feature to put your shared files in an external repository and share it in the places you need. There's also the guest repository extension, which is relatively newer and lighter-weight than a sub-repo.
Instead of solving it in version control, however, I would re-arrange your Visual Studio project so that your shared code compiles to an assembly that your client and server assemblies use and depend on. Share code at the assembly level, not the code level.
If you really must keep your existing structure, I would use NTFS junctions (similar to UNIX-style soft links) to junction in the shared code where it needs to go. You would then add these junctions to your repository's ignore list (in .hgignore). Create a PowerShell script that you and other developers can run that will initialize your repository with the right junctions.

Tracking hard or symbolic links with mercurial on Windows

In a rather large project, I would like to put the same file (or folder) in different locations. When it is changed in one location, the changes should be propagated. In Subversion, I could use externals to achieve this behavior.
I tried to solve this by using hard links and symbolic links, but Mercurial seems to not track any of them. Instead, it commits the content of the files to its repository instead of the link property. When I clone the repository, the information is lost.
Is this a Windows-specific behavior of Mercurial or can't it track links at all? Is there another way to track a file that is accessible from different locations in Mercurial?
Mercurial can track symbolic links, but they look strange when checked out on Windows. What happens is that Mercurial creates a file with the link target as the file content. There is unfortunately no support for creating real symbolic links on Windows systems that support them, such as Windows Vista. The result of this is that you cannot use symbolic links in a repository that is supposed to be portable between both systems. Please see the discussion in Issue1825 for more on this feature.
The closest match for svn:externals is Mercurial subrepositories. Depending on how you used svn:externals, subrepos may or may not be what you want. Please see my answer to another question about subrepos for some advice. I wrote part of the code for subrepos and off the top of my head, I think mounting a subrepo several times in the same main repository sounds like a recipe for confusion. But maybe you can make it work — just be aware that subrepos are a tricky part of Mercurial.

What SCM does support symlinks under Windows and Linux?

I found out that subversion doesn't support symlinks under Windows.
I'm wondering if somebody knows a SCM tool that is able to work with symlinks under both Windows and Linux?
SCM tools currently missing symlink support under Windows:
Clear Case
Subversion
Mercurial
Perforce
Most SCM focus on storing normalized data (think of your SCM as a database). This means that they store source files and build scripts instead of storing executable files derived from them. People could store both but it leads to unnecessary duplication.
Similarly, symlinks are references to other files and represent a similar problem to data normalization.
Furthermore, pointers in general are hard to reason about. Adding support for pointers (symlinks) in a SCM means that certain operations will need to examine where the symlinks point and act accordingly. This makes merges harder, adding/updating symlinks is tricky because you need to figure out where it points (in repo vs. out of repo, two symlinks to same file, etc).
For these reasons, most VCS/SCM do not allow you to manage symlinks. Most SCM do have support for user defined hooks. Using custom hooks or other scripts to manage the symlinks is a better approach because it means the SCM doesn't have to reason about them (it's ignorant to them), and you are side-stepping the issue of data normalization that they create.
So, in conclusion, you're best off writing scripts that manages your symlinks and then calling those at the appropriate times (clone/checkout, update/commit, etc).
Git itself handles symlinks (symbolic links) natively; I mean here that Git stores information that file is symlink in repository.
I think that Git for Windows (msysGit) can represent symlinks in working directory on NTFS. There is also core.symlinks configuration variable, that if false makes Git check out symbolic links are checked out as small plain files that contain the link text. Git will probe and set 'core.symlinks' false if appropriate when the repository is created (git clone or git init).

Resources