Best approaches to versioning Mac "bundle" files - macos

So you know a lot of Mac apps use "bundles": It looks like a single file to your application, but it's actually a folder with many files inside.
For a version control system to handle this, it needs to:
check out all the files in a directory, so the app can modify them as necessary
at checkin,
commit files which have been modified
add new files which the application has created
mark as deleted files which are no longer there (since the app deleted them)
manage this as one atomic change
Any ideas on the best way to handle this with existing version control systems? Are any of the versioning systems more adept in this area?

Mercurial in particular versions based on file, not directory structure. Therefore, your working tree, which is a fully-fledged repository, doesn't spit out .svn folders at each level.
It also means that a directory that is replaced, like an Application or other Bundle, will still find it's contents with particular file names under revision control. File names are monitored, not inodes or anything fancy like that!
Obviously, if a new file is added to the Bundle, you'll need to explicitly add this to your repository. Similarly, removing a file from a Bundle should be done with an 'hg rm'.
There aren't any decent Mercurial GUIs for OS X yet, but if all you do is add/commit/merge, it isn't that hard to use a command line.

For distributed SCM systems like git and mercurial shouldn't be a problem as Matthew mentioned.
If you need to use a centralized SCM like Subversion or CVS, then you can zip up (archive) your bundles before checking them into source control. This can be painful and takes an extra step. There is a good blog post about this at Tapestry Central:
Mac OS X bundles vs. Subversion
This article demonstrates a ruby script that manages the archiving for you.

An update from the future:
If I recall, the problem with managing bundles in SVN was all the .svn folders getting cleared each time you made a bundle. This shouldn't be a problem any more, now that SVN stores everything in a single .svn folder at the root.

Bringing this thread back to daylight, since the October 2013 iWork (Pages 5.0 etc.) no longer allows storing in 'flat file' (zipped), but only as bundles.
The problem is not the creation of version control hidden folders inside such structures (well, for svn it is), but as Mark says in the question: getting automatic, atomic update of files added or removed (by the application, in this case iWork) so I wouldn't need to do that manually.
Clearly, iWork and Apple are only bothered by iCloud usability. Yet I have a genuine case for storing .pages, .numbers and .keynote in a Mercurial repo. After the update, it blows everything apart. What to do?
Addendum:
Found 'hg addremove' that does the trick for me.
$ hg help addremove
hg addremove [OPTION]... [FILE]...
add all new files, delete all missing files

Related

Best practices for Xcode + Git for multi-developer projects

I can create a repo and use GitHub / BitBucket fine for my own projects. I have had problems when collaborating with other developers or trying to fork a project on GitHub.
I am aware of other answers like Best practices for git repositories on open source projects but there are OSX / Xcode specific problems I want to know how to solve.
.DS_Store files can be a pain. You can use .gitignore to prevent, but what happens if they have already been included, or another developer adds them back in through a clumsy git command?
The .xcodeproj will have changes to the directory names and developer profiles for the other person. What's the best way to do merges or to avoid conflicts?
If I have forked or pulled from a github project, how can I clean up these issues and also minimise merge conflicts for the maintainer?
If people have an example .gitignore created for Xcode, or scripts they use to initialise their repos then that would be great!
Put .DS_Store in .gitignore. Then, if you haven't already, add .gitignore to the repo. (You should not ignore .gitignore.) Now all developers will ignore .DS_Store files. If any were added to the repo erroneously before you put .DS_Store in .gitignore, you can now remove them (in a commit) and they should stay out.
The xcodeproj is a directory. The only file in this directory that must be in the repository is the project.pbxproj file. I generally ignore all of the others by putting these lines in my .gitignore:
*.xcuserstate
project.xcworkspace/
xcuserdata/
You should avoid putting absolute paths in your build settings. Use relative paths.
Your Debug and Release builds should use iPhone Developer as the code signing identity, so that Xcode will automatically select the local developer's profile. When you want to create an IPA (for distribution), Xcode will offer to re-sign it with a different identity, at which point you can choose your distribution profile if you need to.
If you're trying to use a project from github that has made these mistakes, you can try to get the maintainer to fix them, or you can make sure you don't touch the .DS_Store files and the code signing identities in the same commits that you want to send upstream.
For the 2nd issue regarding the .xcodeproj and merge conflicts.
Using a .gitattributes file to specify that merge conflicts for all .pbxproj files should be handled using the merge=union strategy, which should mean that Git knows to merge in the changes from both sides of the conflict, taking the upstream changes first.
This article explains it in a bit more depth
I'll try one by one:
I. You need to use git filter-branch only if you need to remove the files from your history completely. If those files do not contain any credit card information, then i think the following should be enough:
git rm --cached .DS_Store
git commit -m "{Your message}"
then add this file to .gitignore and commit it.
This will commit the removal of the file from the repository but will keep the file in working directory. If you push it though and then somebody else will pull this commit, they might have their file removed, so you MUST communicate this.
By committing .gitignore you will prevent other developers from adding this file again.
If you're not a maintainer, then i don't think you should do anything, but address this issue to the maintainer.
II. I'm a strong believer that hidden files of any nature are most of the time not supposed to be put into the repository exactly for that reason. Therefore i think that you should do the same thing with .xcodeproj as with .DS_Store and put it into .gitignore and commit it. .gitignore is the exception for the rule above.
III. If those files are properly ignored , then there will be no issues in future with them. If they are already in the repo and somebody wants do such cleanup it should be done by maintainer and communicated inside the team.
Hope that helps!
git filter-branch might help you to remove unwanted files (.DS_Store files) from your repository -- see e.g. https://help.github.com/articles/remove-sensitive-data
If a clumsy git commit has added files you should be able to replay the corrected changesets onto a clean repository.
You're right in the sense that if a .DS_Store is already added the .gitignore won't be of much help however I think this is still a good resource for you and others.
When I start a project, I normally look at this list to see if there is a good .gitignore already existing. More specifically for you, this one is the Objective-C .gitignore.
Hopefully those resources are of some use.
As a Mac user you should download a tool like SourceTree which supports Git Flow. Git Flow will help you establish some best practices around how your collaborators will commit code to the repo and at the very least make merge conflicts less frequent and more manageable. For a set of gitignore files for various project types you can go to GitHub and download one that is ready to go. For Xcode they have it listed as Objective-C.gitignore. That is a good starting place and it even covers Cocoapods. If you're using external libraries, your project should use CocoaPods so that you can isolate that code and keep it outside of your repo and avoid git submodules.
Now when you find a file has made it into your repo like .DS_Store just remove it, and move on. Make sure you add it to the .gitignore file that is checked into the project.
As for xcodeproj... there shouldn't be that much customization within the file that is user specific since the above mentioned gitignore filters that out. If a scheme is to be shared make sure you check shared under Manage Schemes and you will check in files in that subdirectory. You should be using automatic selection of certificates so the only real choice is Developer or Distribution. You should also take advantage of variables provided within Xcode that avoid hardcoding complete paths. When trying to think of an example Plists came to mind, in this case, you might have written /Users/me/MyProject/Resources/MyProject.plist, but instead should use $(SRCROOT)/resources/MyProject.plist.

Subversion in multiuser environment with XCode 4.0

I have been using XCode with subversion for some time now, no problem was caused when I was using it as a single developer (I was using 2 commands only, commit and add).
But now I have to share the code with another developer (who has never used any kind of version control) and integrating/merging the code has become a nightmare. No problem occur when we are integrating/merging .h/.m files but as soon as it comes to ".nib", "xcodeproj" and ".xcdatamodeld" files, we really don't know what to do.
Whenever we try to merge "xcodeproj", project was getting corrupt and merging ".xcdatamodeld" was kind of impossible for us.
So I was wondering if someone can share his/her experience on how to effectively use subversion/git/mercurial with XCode 4.0 in multiuser environment? or share a link, which can explain how to use subversion effectively in multiuser environment.
Thanks.
Are you doing this using Subversion? For 90% to 99% of the files in your repository, the standard Subversion workflow of checkout, edit, commit works well. However, for some types of files such as JPEGS and GIFS simply don't merge well. In this case, you'll have to do it the way we use to in the old SCCS and RCS days: Before you can edit and commit a file, you must lock it.
Locking a file prevents others from editing the same file and committing changes while you're doing your work on the file. It's crude, but it works. In Subversion, you can always lock any file you're editing, but if the file has the property svn:needs-lock on it, it will be checked out as read-only. You have to lock the file before editing it to make it writable, and you're not allowed to commit the file unless it is locked.
So, for those files, set the svn:needs-lock property on it.
You can automatically set this property on all newly added files (depending upon suffix) via setting the auto-properties in your Subversion client configuration.
And, if you really, really want to make sure that all .nibs and xcodeproj and all of the other flies of these types have svn:needs-lock set on them, you can use my pre-commit hook which will prevent these files from being committed unless this property is set.
There is no failsafe way to merge these kinds of files that I am aware of. So you will have to
try to ensure that only one person is changing these files at a time. That won't work always, so just log what you changed in the file with the commit message. Then if there is a conflict, you can manually resolve it by taking the version that changed more of the file and redo manually what the other person did.
That's normally not a big deal, like adding a new source file to an .xcodeproject, or changing the alignment of an element in a .nib. It's becoming a problem if your project is huge or your nib is containing the whole interface. For it to work well (which in practice it does), you need to split up your projects into sub-projects if they grow too huge.
I had the same problem with 2 other developers Xcode with git. Unfortunately, Xcode project files are an XML file, tracks file included in the project as well as setting. I'm not certain, but I think .nib files are also XML files as well. Someone can correct me on that.
Git did a great job at merging the Xcode project file, and never really had any problems with our *.nib files either. The only time we did have a problem is when we both added/removed files with the same names, or someone did a lot of heavy removing and adding of a lot of files.
The only way we solved this was to have each other push ann pull as soon as we added/removed files. So that way the person had the latest files, and didn't add them in their own repository then pull the latest commit which had the same file in it. Or they work adding changes to a file that was removed or renamed.
That is the best solution we found, as soon as we added or removed a file have everyone else in the team pull. Not a great solution btw. However, you should be committing often anyways.

Delete an unreferenced image from repository in Xcode

I deleted default.png from my resources folder because I wanted a different image for the loading screen, but I just deleted the reference which was apparently a dumb thing to do. I dragged the new image into resources and tried to change the name to Default.png, but it won't let me, which I think is because the first Default.png is still in the repository somewhere. Anyway, how do I delete that image(and others with which I have probably done the same thing) from the repository when it is no longer visible in xcode?
What kind of repository is it? Subversion? Git?
The SCM integration in Xcode is great for checking out files and committing changes without having to leave the IDE, but it's hardly a full-blown GUI front end to either svn or git. It may be possible to fix your mistake by adding the file back to the project and then deleting it in Xcode in such a way that Xcode will remove it from the repository for you, but the simple solution is to just delete the file from the repository yourself by using the appropriate version control command. For example, if you're using Subversion you could:
svn remove default.png
to remove the file from your version of the repository. When you commit your changes, the file will be deleted in that version. (It'll still exist in previous versions -- that's the whole point of SCM, after all.)
After that, you can create the new file and add it to both the project and the repository in the usual way.
You need to manually go into your app's file structure and delete the image files themselves. Also, it is usually a good idea to "clean" the app whenever you remove files or references to files from an XCode project, since XCode can be a bit temperamental about removing files; the key combination for this is
Hope this fixes your problem.
Clean all targets should work (at least it worked for me). You can try the following:
a) delete the reference from "Copy Bundle resources" of your target
b) delete the app from Simulator/Device
c) clean all targets
Caleb is absolutely right. That fixed the problem here as well for the most files.
An easier way to get an overview of the accidentally un-deleted files, is creating a bookmark of the working copy with Versions (SVN Software - in case you use SVN). There you can detect the problematic files grafically and delete them. I always have to do this after restructuring the project folder.

Lightweight version control for small projects (prototypes, demos, and one-offs) [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 9 years ago.
Improve this question
Background
I work on a lot of small projects (prototypes, demos, one-offs, etc.). They are mostly coded in Visual Studio (WPF or ASP.NET with code written in C#). Usually, I am the only coder. Occasionally, I work with one other person. The projects come and go, usually in a matter of months, but I have a constantly evolving set of common code libraries that I reuse.
The problem
I've tried to use source control software before (SourceGear Vault), but it seemed like a lot of overhead when working on a small project, especially when I was the only programmer. Still, I would like some of the features that version control offers.
Here's a list of features I'd like to have:
Let me look at any file in an older version of my project instantly. Please don't force me through the rigmarole of (1) checking in my current work, (2) reverting my local copy to the old version, and (3) checking the current version back out so I can once again work on it.
In fact, if I'm the only one on the project, I don't ever want to check out. The only thing I want to be able to do is say, "Please save what I have now as version 2.5."
Store my data efficiently. If I have 100 Mb of media in my project, I don't want that to get copied with every new version I release. Only copy what changes.
Let me keep my common library code files in a single location on my hard drive so that all my current projects can benefit from any bug fixes or improvements I make to my library. I don't want to have to keep copying my library to other projects every time I make a change.
However, do let me go back in time to any version of any project and see what the source code (including the library code) looked like at the time that version was released.
Please don't make me store a special database server on my machine that makes my computer take longer to start up and/or uses resources when I'm not even programming.
Does this exist?
If not, how close can I get?
Edit 1: TortoiseSVN impressions
I did some experimenting with Subversion. A couple observations:
Once you check something in to a repository, it does stuff to your files. It puts these hidden .svn folders inside your project folders. It messes with folder icons. I'm still yet to get my project back to "normal". Unversion a working copy got me part of the way there, but I still have folders with blue question mark icons. This makes me grumpy :-/ Update: finally got rid of the folder icons by manually creating new folders and copying the folders over. (Not good.)
I installed the open source plugin for Visual Studio (AnkhSVN). After creating a fresh repository in my hard drive, I attempted to check in a solution from Visual Studio. It did exact what I was afraid it would do. It checked in only the folders and files that are physically (from the POV of the file system) inside my solution folder. In order to accomplish item #5 above, I need all source code used by solution to be check in. I attempted to do this by hand, but it wasn't a user friendly process (for one thing, when I selected multiple library projects at once and attempted to check them in, it only appeared to check in the first one). Then, I started getting error dialogs when I tried to check in subsequent projects.
So, I'm a little frustrated with SVN (and its supporting software) at this point.
Edit 2: TortoiseHG impressions
I'm trying out Mercurial now (TortoiseHG). It was a little bit difficult to figure out at first, no better or worse than TortoiseSVN I'd say. I noticed an RPC Server on startup (relates to item 6). I figure it should be possible to turn this off if I'm not sharing anything with anyone, but it wasn't something I could figure out just by looking at the options (will check out the help later).
I do appreciate having my local repository as just a single .hg folder. And, simply throwing the folder in the Recycle Bin seemed to be all I needed to do to return everything back to normal (i.e., unversion my project). When I check in (commit), it seems to offer a simple comment window only. I thought maybe there would be a place to put version numbers.
My (probably not very clever) attempt to add a Windows shortcut (a folder aliasing my library projects) failed, not that I really thought it would work :) I thought maybe this would be a sneaky way to get my library projects (currently located elsewhere) included in the repository. But no. Maybe I'll try out "subrepos", but that feature is under construction. So, iffy that I'll be able to do items 4 and 5 without some manual syncing.
Any of the distributed source control solutions seem to match your requirements. Take a look at bazaar, git or mercurial (already mentioned above). Personally I have been using bazaar since v0.92 and have no complaints.
Edit: Heck, after looking at it again, I'm pretty sure any of those 3 solutions handles all 6 of your requested features.
Distributed Version Control Systems (Mercurial, Bazaar, Git) are nice in that they can be completely self-contained in a single directory (.hg, .bzr, .git) in the top of the working copy, where Subversion uses a separate repository directory, in addition to .svn directories in every directory of your working copy.
Mercurial and Subversion are probably the easiest to use on Windows, with TortoiseHG and TortoiseSVN; the Bazaar GUIs have also been improving. Apparently there is also TortoiseGit, though I haven't tried it. If you like the command line, Easy Git seems to be a bit nicer to use than the standard git commands.
I'd like to address point 4, common libraries, in more detail. Unfortunately I don't think any of them will be too easy to use, since I don't think they're directly supported by GUIs (I could be wrong). The only one of these I've actually used in practice is Subversion Externals.
Subversion is reasonably good at this job; you can use Externals (see the chapter in the SVN book), but to associate versions of a project with versions of a library you need to "pin" the library revision in the externals definition (which is itself versioned, as a property of the directory).
Mercurial supports something similar, but both solutions seem a bit immature: subrepository support built-in to the latest version and the "Forest Extension".
Git has "submodule" support.
I haven't seen anything like sub-respositories or sub-modules for Bazaar, unfortunately.
I think Fog Creek's new product, Kiln, will get you pretty close. In response to your specific points:
This is easily done through the web interface -- you don't need to touch your local copy or update. Just find the file you want, click the revision you want to see, and your code will be in front of you.
I'm not sure you can do things exactly like "Please save this as version 2.5", but you can add unique tags to changesets that allow you to identify a special revision (where "special" can mean whatever it wants to you).
Mercurial does a great job of this already (which Kiln uses in the back end), so there shouldn't be any problems in this regard.
By creating different repositories, you can easily have one central 'core' section which is consistent across various projects (though I'm not entirely sure if this is what you're talking about).
I think most version control systems allow you to do this...
Kiln is hosted, so there's no hit on performance to your local machine. The code you commit to the system is kept safe and secure.
Best of all, Kiln is free for up to two licenses by way of their Student and Startup Edition (which also gets you a free copy of FogBugz).
Kiln is in public beta right now -- you can request your account at my first link -- and users are being let as more and more problems are already resolved. (For some idea of what current beta users are saying, take a look at the Kiln Knowledge Exchange site that's dedicated to feedback.)
(Full Disclosure: I am an intern currently working at Fog Creek)
For your requirements I would recommend subversion.
Let me look at any file in an older version of my project instantly. Please don't force me through the rigmarole of (1) checking in my current work, (2) reverting my local copy to the old version, and (3) checking the current version back out so I can once again work on it.
You can use the repository browser of Tortoise Svn to navigate to every existing version easily.
In fact, if I'm the only one on the project, I don't ever want to check out. The only thing I want to be able to do is say, "Please save what I have now as version 2.5."
This is done by svn copy . svn://localhost/tags/2.5.
Store my data efficiently. If I have 100 Mb of media in my project, I don't want that to get copied with every new version I release. Only copy what changes.
Given by subversion.
Let me keep my common library code files in a single location on my hard drive so that all my current projects can benefit from any bug fixes or improvements I make to my library. I don't want to have to keep copying my library to other projects every time I make a change.
However, do let me go back in time to any version of any project and see what the source code (including the library code) looked like at the time that version was released.
Put your libraries into the same svn repository as your remaining code and you'll have global revision numbers to switch back all to a common state.
Please don't make me store a special database server on my machine that makes my computer take longer to start up and/or uses resources when I'm not even programming.
You only have to start svnserve to start a local server. If you only work on one machine you can even do without this and use your repository directly.
I'd say that Mercurial along with TortoiseHg will do what you want. Of course, since you don't seem to be requiring much, subversion with TortoiseSvn should serve equally well, if you only ever work alone, though I think mercurial is nicer for collaboration.
Mercurial:
hg cat --rev 2.5 filename (or "Annotate Files" in TortoiseHg)
hg commit ; hg tag 2.5
Mercurial stores (compressed) diffs (and "keyframes" to avoid having to apply ten thousand diffs in a row to find a version of a file). It's very efficient unless you're working with large binary files.
Symlink the library into all the projects?
OK, now that I read this point I'm thinking Mercurial's Subrepos are closer to what you want. Make your library a repository, then add it as a subrepository in each of your projects. When your library updates you'll need to hg pull in the subrepos to update it, unfortunately. But then when you commit in a project Mercurial will record the state of the library repo, so that when you check out this version later to see what it looked like you'll get the correct version of the library code.
Mercurial doesn't do that, it stores data in files.
Take a look on fossil, its single exe file.
http://www.fossil-scm.org
As people have pointed out, nearly any DVCS will probably serve you quite well for this. I thought I would mention Monotone since it hasn't been mentioned already in the thread. It uses a single binary (mtn.exe), and stores everything as a SQLite database file, nothing at all in your actual workspace except a _MTN directory on the top level (and .mtn-ignore, if you want to ignore files). To give you a quick taste I've put the mtn commands showing how one carries out your wishlist:
Let me look at any file in an older version of my project instantly.
mtn cat -r t:1.8.0 readme.txt
Please save what I have now as version 2.5
mtn tag $(mtn automate heads) 2.5
Store my data efficiently.
Monotone uses xdelta to only save the diffs, and zlib to compress the deltas (and the first version of each file, for which of course there is no delta).
Let me keep my common library code files in a single location on my hard drive so that all my current projects can benefit from any bug fixes or improvements I make to my library.
Montone has explicit support for this; quoting the manual "The purpose of merge_into_dir is to permit a project to contain another project in such a way that propagate can be used to keep the contained project up-to-date. It is meant to replace the use of nested checkouts in many circumstances."
However, do let me go back in time to any version of any project and see what the source code (including the library code) looked like at the time that version was released.
mtn up -r t:1.8.0
Please don't make me store a special database server on my machine
SQLite can be, as far as you're concerned, a single file on your disk that Monotone stores things in. There is no extra process or startup craziness (SQLite is embedded, and runs directly in the same process as the rest of Monotone), and you can feel free to ignore the fact that you can query and manipulate your Monotone repository using standard tools like the sqlite command line program or via Python or Ruby scripts.
Try GIT. Lots of positive comments about it on the Web.

Storing file permissions in Subversion repository

How do you store file permissions in a repository? A few files need to be read-only to stop a third party program from trashing it but after checking out of the repository they are set to read-write.
I looked on google and found a blog post from 2005 that states that Subversion doesn't store file-permissions. There are patches and hook-scripts listed (only one url still exists). Three years later does Subversion still not store file permissions and are hooks the only way to go about this? (I've never done hooks and rather use something that is native to Subversion.)
SVN does have the capability of storing metadata (properties) along with a file. The properties are basically just key/value pairs, however there are some special keys like the 'svn:executable', if this property exists for a file, Subversion will set the filesystem's executable bit for that file when checking the file out. While I know this is not exactly what you are looking for it might just be enough (was for me).
There are other properties for line ending (svn:eol-style) and mime type(svn:mime-type).
There's no native way to store file permissions in SVN.
Both asvn and the patch from that blog post seem to be up (and hosted on the official SVN repository), and that's a good thing, but I don't think they will have such metadata handling in the core version any time soon.
SVN has had the ability to handle symbolic links and executables specially for a long while, but neither work properly on Win32. I wouldn't hold my breath for another such non-portable feature (though it wouldn't be too hard to implement on top of the already existing metadata system.)
I would consider writing a shell script to manually adjust file permissions, then putting it in the repository.
One possible solution would be to write a script that you check in with the rest of your code and which is run as the first step of your build process.
This script runs through your copy of the codebase and sets read permissions on certain files.
Ideally the script would read the list of files from a simple input file.
This would make it easy to maintain and easy for other developers to understand which files get marked as read-only.
Since this wasn't fully said in previous responses yet. I hate to resurrect zombied threads though.
Since adding permission support for SVN would have to accommodate multiple OS's and permission types, NFS, POSIX, ARWED, and RACF
This would make SVN bloated, possibly clash with conflicting permission types like NFS and POSIX, or open up possible exploits/security vulnerabilities.
There are a couple of workarounds.
pre-commit, post-commit, start-commit are the more commonly used, and are a part of the Subversion system.
But will allow you to control the permissions with what ever programming language you like.
The system I implemented is what I call a packager, that validates the committed files of the working copy, then parses a metadata file, which lists out the default permissions desired for files/folders, and any changes to them you also desire.
Owner, Group, Folders, Files
default: <user> www-user 750 640
/path/to/file: <user> non-www 770 770
/path/to/file2: <user> <user> 700 700
You can also expand upon this and allow things such as automated moving, renaming them, tagging revision by types, like alpha, beta, release candidate, release
As far as supporting clients to checkout your repository files with permissions attached to them. You are better off looking into creating an installer of your package and offering that as a resource.
Imagine people setting their repositories with an executable in it set with permissions of root:www-user 4777
This is the updated link for SVN patch which handles unix style file permissions correctly. I have tested out on fedora12 and seems to work as expected:
I just saved it /usr/bin/asvn and use asvn instead of svn command if i need permissions handled correctly.
Many answers have stated that svn does not store file permissions. This may be true, but I was able to solve a dll file without execute permissions problem simply by these steps:
chmod 755 badpermission.dll
mv badpermission.dll ../
svn update
svn rm badpermission.dll
svn commit badpermission.dll -m "Remove dll to fix permissions"
mv ../badpermission.dll .
svn add badpermission.dll
svn commit badpermission.dll -m "Add the dll back to fix permissions"
rm badpermission.dll
svn update
badpermission.dll comes back with execute permissions
#morechilli:
The asvn wrapper from my earlier post and the blog in the OP's post seems to do what you're suggesting. Though it stores the permissions in the corresponding files' repository properties as opposed to a single external file.
I would recommend to generate permissions map using mtree utility (FreeBSD has it by default), store the map in the repository, and, as was mentioned above, run a script that would restore proper file permissions from the map as the first step of the build process.
Locking would not solve this problem. Locking stops others from editing the file. This is a third party application which gets run as part of the build process that tries to write to a file - changing it - which breaks the build process. Therefore we need to stop the program from changing the file which is simply marking the file read-only. We would like that information to be held in the repository and carried across checkins, branches, etc.
Graham, svn doesn't store permissions. Your only option is to wrap your call to svn in a script. The script should call svn with its arguments, then set the permissions afterward. Depending on your environment, you might need to call your script svn and tweak your PATH to ensure it gets called.
I quite like morechilli's idea to have the list of files and permissions checked into the repository itself.
We created a batch file to do this for us. Would prefer actual support in subversion though...
Consider using svn lock to disallow others from writing to the file.

Resources