Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm in charge of a software platform, written in C, that is used to provide a variety of projects to clients. I am trying to improve the workflow for people using this platform, and looking at whether source code control (Mercurial being the most likely candidate) can help.

The platform is only used internally for ~10 projects / year. It's got a wide range of functionality, and lots of bits that are unused on most projects. As a result, there are plenty of bugs hidden away.

I'm wondering if anyone has similar experience, either managing or using a constantly updated platform in this way.

The current situation

Platform development is done with a mercurial repository, but the releases of the platform are not done through mercurial. For a release, the platform files are put into a tarball on a central server. For any system connected to the core, the start of the build process copies the updated tarball and unpacks it into the application source code. Application programmers can't edit the core files (various commands are aliased through shell scripts, and they get an error if they try).

What I'm after

It seems like it should be possible to somehow use Mercurial to manage this. We could easily maintain a release branch of the platform, and have projects clone the release branch as their starting points.

But I'm not sure where it would go after that. On a project, the functionality is completely up to the client. If the core files are unlocked, people will immediately start editing them, even when there is a better way (this is what happened before the lockdown). This is going to mean merging in new core changes becomes difficult, and I suspect will result in a lot of teams not bothering.

The draconian solution of locking the core files, and forcing automatic updates to all projects was really quite successful: we get more complaints and problems from the projects that are disconnected, than the ones receiving the forced updates. However, as soon as projects go into testing, they have to be disconnected. After that, short of manual merging, they get no more platform updates.

share|improve this question

migrated from stackoverflow.com Jan 19 '12 at 3:57

This question came from our site for professional and enthusiast programmers.

    
Why the off-topic close votes? It isn't directly programming, but isn't it covered as 'software tools commonly used by programmers'? –  asc99c Jan 17 '12 at 12:29
    
It may still be a better fit on programmers.se, but I'm not sure about that. –  Christian Rau Jan 17 '12 at 13:59
    
Yes, I could agree with that. Not used programmers much, but if anyone with permissions to migrate sees this, can it be moved across? –  asc99c Jan 17 '12 at 14:03
    
I would say your current (maven-like) flow is fine, in fact better than managing it through subrepositories. –  Laurens Holst Jan 17 '12 at 15:32
1  
I should probably have stated the big problem with the current situation! A few people immediately disconnect their projects from the platform and work standalone. This would be fine with me if they didn't then come asking for help fixing stuff :) I'm trying to provide an alternative for the people who refuse to use the draconian version. –  asc99c Jan 17 '12 at 16:38

4 Answers 4

I've dealt with similar issues with different flavors of commit-approval. Additionally using ACLs (and in some cases where security required) CheckGpgSig.

I've somewhat cheated in that for each project I setup, I force folks to use a setup.(csh|sh) script that when necessary will either (1) warn or (2) prompt them to update their tree.

share|improve this answer
    
I hadn't seen the ACL option - it looks like an interesting idea. A possibility is that upon cloning the repository, everything would be locked down. In cases where someone wanted to change a core file, they could unlock it by changing the hgrc, but hopefully the roadblock would be enough to point them towards a change in the application files when possible. –  asc99c Jan 17 '12 at 12:25

I'm not a Mercurial or Subrepositories guru in any form, but I think I can use subrepositories (Aragost Kick-start and Wiki) in your work.

I.e:

  • Have platform in (separate?) repo
  • Link it to all project as subrepository (instead of direct copy)

This way you get

  • Easy publishing of releases to projects (update subrepository to needed cset, commit into main repo)
  • Platform code is effectively locked (if projects devs haven't rights to push into remote platform repo, they can't change and commit) - TBT!!!
share|improve this answer
    
I like the idea of subrepositories - in fact I looked at it for managing the plugins for this platform. Unfortunately, the applications have all files in one big directory, and too many people like it that way. For the plugins, I couldn't win that argument, and wrote a couple of scripts to copy the plugin files to a subdirectory and run the mercurial commands in the subdirectory. I think that would be too cumbersome with the core platform. –  asc99c Jan 17 '12 at 14:00
    
@asc99c - OK, if platform's and project's files are in one common tree (i.e project is just some added objects to platform objects), you can maintain platform and every projects in separate branch inside common repo, disable with ACL changing "Platform" branch to "all, except ...", update platform in projects by merging branches ("platform" to "project"). I don't know only how to avoid modification of core files in project's branches (good solution wanted, dirty solution is *-commit hook with some check-logic) –  Lazy Badger Jan 19 '12 at 10:57

I am not a Mercurial user, too, but it seems that you are after something like what subversion users (like me) call "externals" - the possibility to pull a shared library (your "platform/core") into different projects, which may reside in different repos. Here is a link to a mercurial extension providing the same functionality

http://mercurial.selenic.com/wiki/HgExternals

Googling for "mercurial externals" will provide you with some more links.

Using the "external" feature allows you to

  • define exactly which revision of the lib you want to use in your project; even when new revisions of the lib are checked in, you are not forced to use them immediately
  • prevent changes to the lib directly to be commited back to the repo from the using project

There are, of course, some further things you can do, independently from your specific version control system.

If you don't want the users of your lib to edit the source code, why not provide a "binary only" version of it? That is a very effective way of preventing them to edit "the core". If that is not an option, perhaps you could add a "DO NOT EDIT" disclaimer to every source file. Actually, everyone can ignore that comment, but then it will be easier for you to refuse assistance.

On the other hand, if you actually want (some) users of your lib to edit the source code of the lib, you should not give them a tarball, but create a special branch in your repository for them. This way it gets a lot easier to merge the changes back later.

One more thing: do you have automated tests (unit & integration tests) for your platform? That may be very (!) helpful in your situation. Before you merge back something to the trunk of your platform, you can run those tests to make sure the users of your platform won't get some bad surprises when they update to the latest release.

share|improve this answer

You could try git

Linux kernel project is using it, github is using it, ... is using it.

For the core files that application programmers cannot edit, you could use git update-index --assume-unchanged file\*

When these flags are specified, the object names recorded for the paths are not updated. Instead, these options set and unset the "assume unchanged" bit for the paths. When the "assume unchanged" bit is on, git stops checking the working tree files for possible modifications, so you need to manually unset the bit to tell git when you change the working tree file. This is sometimes helpful when working with a big project on a filesystem that has very slow lstat(2) system call (e.g. cifs).

This option can be also used as a coarse file-level mechanism to ignore uncommitted changes in tracked files (akin to what .gitignore does for untracked files). You should remember that an explicit git add operation will still cause the file to be refreshed from the working tree. Git will fail (gracefully) in case it needs to modify this file in the index e.g. when merging in a commit; thus, in case the assumed-untracked file is changed upstream, you will need to handle the situation manually.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.