I would like to know if there is any SCM that meets these criteria:
not keeping the entire depot history locally because this can be huge for some projects
not polluting the entire source tree with hidden directories (like .svn ones)
work decently with binary files, or at least to be able to limit the number of revisions to store for them (like perforce)
sync over HTTP
free
optionally, be able to link other repositories or even ones from other SCM (something like svn:externals)
(as of now unreleased) svn 1.7 does away with the .svn directory in each directory.
From http://subversion.apache.org/docs/release-notes/1.7.html#wc-ng :
A key feature of the changes introduced in Subversion 1.7 is the centralization of working copy metadata storage into a single location. Instead of a .svn directory in every directory in the working copy, Subversion 1.7 working copies have just one .svn directory—in the root of the working copy. This directory includes (among other things) an SQLite-backed database which contains all of the metadata Subversion needs for that working copy.
I've never really been bothered by the .svn dirs littered throughout - packaging or even a deploy using svn export always seemed to make them not matter when it mattered. Out of curiosity, what's making them onerous in your situation?
You should have a look at Git : http://git-scm.com/
Related
I'm totally new to git and have a question related to the work bench. I do stuffs in java so I would ask in term of java. When you commit files to git repository, do we commit .java, .class files? Or it is ok to put the whole work bench into the local git folder then commit everything?
It's generally not considered a good idea to commit binary files to any version control system if you can recreate them by simply compiling the source code you also committed. This is especially important with a DVCS as every copy of the repository carries around the redundant data. This might not be a big deal if you're working on a fairly small project, but once the project gets bigger it's a nuisance.
The other problem with committing the .class files or any sort of binary is that any sort of build will show your source tree as "dirty" in multiple places unnecessarily as both the class files and the java files will need comitting.
My advice would be to put the build directories in your projects in .gitignore so git knows not to look at them, then add your source files and the Eclipse project files to git.
First, there are no problems with my build path, and there's no problem in the "problems" window regarding this error. What happens is:
I check a project out of SVN
I then build that project
SVN "version" and link gets removed from classes and build directories (and red ! appears)
I can no longer commit project as a whole, as I get this error:
svn: Commit failed (details follow):
svn: Working copy 'C:\Users\<me>\Documents\eclipseSDK\<project>\classes' is missing or not locked
It's NOT missing, it just was "refreshed" during build
I've also tried to delete the dir on the SVN side, but the red arrows still appear and committing throws an error - even though those dirs are no longer part of the checked resources.
Also, basically, any "Team" menu option will no longer work on those two dirs, if I try to Team>Add to Version Control, nothing shows up in the Resources window.
I don't even know if I care about the red exclamation as much as just getting those two dirs out of the SVN process. Like I said, I've deleted on the SVN side even, so they are no longer there.
Are your compiled classes file part of your Subversion repository? If so, GET RID OF THEM FROM SUBVERSION!.
Sorry about the screaming, but files that can be built (like classes and jar files) should not be stored in version control. It just doesn't make sense.
Source control allows you to see the history of changes. You can see who made what changes in the source, but you can't do that in class files or jars. Source control allows you to branch and merge changes. You can't do that with class files. And, they go stale very quickly. No one cares about class files that were built last month.
The biggest issue is sheer size. Binary files don't diff well (and many version control systems don't even try). Let's say you build 15 megabytes worth of class files each time you do a build. That's probably at least 12 megabytes added to your repository each and every time. With in a year, you could be adding, 1 gigabyte to your repository. You can easily end up with the vast majority (and I mean in the 90% range of your source repository being nothing more than compiled code. Compiled code that no one cares about. Compiled code that can't help you understand your development history. Compiled code that clogs up your repository.
Go to your classes directory, and do an revert from the Team menu on that directory. You'll lose all of your changes, but so what? They shouldn't be there. This will set things up, so you can at least commit your changes.
Then, delete that classes directory and all of its contents from Subversion and commit. Eclipse will create the directory when it does a build, and you can make the directory in Ant's build file before you compile the code. You should then set an svn:ignore property on the directory parent to prevent people from checking in the classes directory.
If you need to store jar files for other projects to use, use a release repository. In fact, use a Maven repository like Artifactory or Nexus. You don't have to use Maven. Ant can use Ivy to fetch the files from a Maven repository, or you can simply use URLs to download the files as needed via wget or the <get/> task in Ant.
OK, I deleted [build & classes] from local, and deleted from SVN. Made a minor edit to a file, just to be able to run Commit - which worked fine.
That's good.
Both local & SVN were in sync. build & classes are (and were) part of ANT build file, so ran build again. build & classes reappeared (with ? this time), and added to svn:ignore.
Any file that's not in the repository will show up with a question mark. Those question marks will disappear if you add the svn:ignore property to the parent directory with classes, sync, and build in it.
Made another file change, but now I cannot commit the entire project, as I'm getting more/different errors now (e.g. "out of date").
The out of date means that someone somewhere modified a file that was in the repository and committed it. It's very likely that the change is one of the *.class files that you removed. You will have to do an update before a commit. When you do the update, you will likely see a lot of conflicts where a class file was changed, but you had removed it. Resolve these changes, update, and commit again.
By the way, I have a pre-commit hook that is useful in this situation. First, it can prevent people from adding that classes directory to the repository (and any files under it). Second it can make sure that the svn:ignore is setup correctly.
Using the combination of tools in the title, when I check out a branch, SourceTree/GIT will:
Definitely NOT delete folders from the previously checked-out branch, so if I have BRANCH-ALPHA with FOLDER1 and FOLDER2 and then I check out BRANCH-BETA which has FOLDER2 and FOLDER3 only and no FOLDER1, the resulting structure in FINDER will show that FOLDER1 is still there. Can reproduce this over and over.
Often will not even overwrite files from the previously checked-out branch, so that I'm still seeing BRANCH-ALPHA in Eclipse when I have checked-out BRANCH-BETA.
I close Eclipse before doing the checkout, and then open Eclipse, CLEAN and BUILD everything. It's really a problem with GIT.
The only "solution" is to delete all the folders and all the metadata and then check out the branch. This typically leads to a few hours of trying to "convince" Eclipse to open the project, creating a new workspace, new metadata, etc., and then fixing a lot of things like paths etc.
Any ideas on how to further research the cause and find a solution are very much appreciated.
Git only deletes empty folders when checking out a new commit. You might see apparently empty directories because there are hidden files stored in them. If you try to monitor the behavior by opening them in Finder, you're actually causing the problem since Finder creates hidden files to track the way the folders are displayed.
Does it really bother you that the folders are there? You could add a post-checkout hook that runs git clean -dxf after each checkout; this will remove all the files that are not known by git. Be careful that it will also delete compiled classes, so a new build will be required.
Another possibility is that something is locking files or directories, so git can't remove them while they're still opened/locked by the other program. This would also explain why some files aren't updated to the right version. Does git complain when you switch branches? It should if there's indeed a lock on the files.
In my project I have a directory structure like this :
project
--common
--subproject
--common (junction, not a copy)
The subproject needs some files from common. Therefore I created a 'junction' (in XP using the sysinternals command) to be able to see and make changes in common from within the subproject.
This works like a charm, any changes to both commons are immediately on both common since in fact it points to the same folder.
Then I made a separate project in Eclipse for the subproject folder and its own svn repository.
But when I want to commit the subproject, it wants to commit the 'common' folder as if it were a real folder, but in fact this folder needs to be committed only to its parents repository!
Is there a way of telling svn to make commits to a different repository than its own?
svn:externals is not a good solution since this creates duplicate sources, and makes it even harder to maintain, because it's not automatically kept in sync.
eclipse's file system abstraction features linked folders.
Have you tried using those rather than a junction at the filesystem level? (I don't know how the subversion plugin treats those, but perhaps you are in luck)
Suppose I have the following (desired) folder structure:
*CommonProject
*Project#1
----> CommonProject(link)
*Project#2
----> CommonProject(link)
Where the CommonProject is the location of the source belonging to that project, and CommonProject(link) is merely a soft link to the main location. If we imagine this as a tree-view in a visual client, if I expand Project#1 I will see CommonProject there as a subdirectory, even though the files are not actually stored there.
The purpose of this is to enable the following behaviour:
When I check out Project#1 I get the files associated with that project as well as a subfolder CommonProject containing all of its files (as if Project#1 contained the copy of the files in the Version Control repository). Now if I were to modify CommonProject's files inside of Project#1 and was to submit my changes to the repository, the changes would go into the CommonProject location (no file is actually stored locally under Project#1 in the repository). Now if I was to sync Project#2, as it also contains symlink to CommonProject, it will now get my updates.
Essentially the duplication of files only exists on my machine, but in the repository there is only one version of CommonProject.
I know Perforce can’t do this, without juggling 3 specs. This is very complicated and error prone, especially when a lot of people do it. Is there a source control repository out there that can do this? (a pointer to some docs on how it can be done is a plus)
Thank you.
Subversion can directly store symlinks in the repository. This only works for operating systems that support symlinks though, as svn just stores the symlink the same way it would with any other file.
I think what you really want is to link to separate projects though. Subversion supports this through externals and git through submodules. Another alternative is to manage this sort of thing with in your build process, so that some static resources are gathered when you initialize the build. Generally, updating a utilities library that changes often is going to cause stability problems, so you can do this manually (or with clever scripts) when you need to
You'd probably be much better off just storing the projects in a flat directory (1 directory per project, all at the same level), and using whatever you build system or IDE is to link all the stuff together.