tags:

views:

1500

answers:

10

I have a Subversion working copy where I made some local modifications to one file. The modifications are only relevant to me, I do not want to commit them. (The version in the repository contains some default values which are suitable for the other users, just not for me, which is why I want to override them locally.)

Note that although I do not want to commit my changes, I do want to receive any updates made in the repository when I do svn update. Also, it is only in my working copy that I do not want to commit the changes to that file, the other users should not be affected. So svn:ignore or commit hooks do not fit my purpose.

Currently, I simply do:

svn commit file1 file2...

where I specify explicitly the files that have changes excluding the particular file that I do not want to commit.

However, while I'm working, I have the habit of simply writing:

svn commit -m "Log of what I just did"

and I fear that I will inadvertently commit the "forbidden" file by using the above command at a moment when I'm not attentive.

In short, what I'm looking for is simply a way of "marking" a file in a working copy which prevents Subversion from committing the changes in that file (it doesn't have to be automatic exclusion, even if I just get an error when I try to commit all files, it is fine). Sort of like marking files in a "conflict" state...

Does such a thing exist?

Update: akent, thanks for pointing out this very similar question.

+1  A: 

Lock certainly isn't what you want, and I don't think any of the built in features will do it for you.

Depending on which environment you are working in, I'd write a script that:

  1. Gets the list of files
  2. Removes the ones I don't want to commit
  3. Commits the files

Something along the lines of:

svn status | grep ^M | grep -v exclude.c | awk -F' ' '{print $2}' | xargs svn ci -m "I'm committing something"

Or if the list of files is really static, just fix the list!

Cybergibbons
+5  A: 

I understand the problem you're having; probably this "forbidden" file contains configuration settings and the like that are only relevant to your local build environment. I've not found any way directly to tell SVN just to ignore changes in a versioned file, but here's a workaround I've used in the past.

Assuming your file is called, say, "build.conf". Name the SVN versioned file something like build.conf.example. Then, in your Makefile or build script or whatever, you can automatically copy the build.conf.example to the real build.conf, which remains unversioned. Then you svn ignore build.conf and each developer can then make any local changes they need to it.

But "there must be a better way"...

Edit: Almost identical question here: http://stackoverflow.com/questions/635446/svn-is-there-a-way-to-mark-a-file-as-do-not-commit

akent
Apparently, this is also the answer from the FAQ. However, this is a hassle and it overlooks one very important point: whenever the "forbidden" file is updated in the repository, I want svn up to merge the remote changes with my local modifications (and signal a conflict if necessary). With an unversioned file, you have to do this manually, which means that your build.conf will probably grow out of date compared to build.conf.example.
Bruno De Fraine
Agreed, not ideal. CoverosGene's answer looks to be "the better way". Only in recent versions (1.5+) of SVN though, it seems.
akent
+2  A: 

This question is in the Subversion FAQ. But the answer is not very helpful if you do not control the repository.

Maybe try to manage your local copy with git on top of subversion. There is a simple course for git available. You can then use git-svn for tracking changes in svn repository and for commiting your changes. It will need some learning and training through.

Tometzky
+6  A: 

Create a changelist with that file in it, and then just pay no attention to the changelist. The file will sit there waiting to be committed, but your regular commits, which work on the default changelist, will never pick it up.

svn changelist mylocal file1

will create a changelist called mylocal and assign the file file1 to it.

CoverosGene
Good solution for sure, but only works on a per-developer basis; not something you can set up for everyone who checks out the repo. Plus, only available in SVN versions > 1.5.
akent
Changelists seem very cool, but what you say isn't quite right: when I create a changelist "mylocal", then "svn commit" will still consider all modified files. As far as I see, there is no mention of the "default" changelist in the documentation.
Bruno De Fraine
@akent: per-working-copy is exactly what I want
Bruno De Fraine
A: 

You can use a pre-commit hook. In the hook use svnlook author to see if you are the one committing the changes. If so, use svnlook changed to see if you are changing one of the forbidden files.

Dingo
+1  A: 

From my experience: don`t put that file under version control and use svn:ignore on it.

It’s a little hard at the beginning, since you cannot ignore a file that is allready under version control, and you cannot remove a file from version control without removing it from hard drive (and from every working copy on next update...). But when you finally manage to set up the repo correctly, it works like charm. Don’t forget to add a generic-template in place of your original config file (so that everyone knows about new config variables, and so on).

For new repo:

mkdir config
svn add config
svn propset svn:ignore '*.conf' config

For existing repo: be sure, to have a backup of your config in every working copy, then remove (svn del) config from the repo, commit (please note: the file will be deleted in every working copy on next update! you have to have a backup) and then restore the file and set the ignore property.

Another way is a lock. It guarantees that noone commits the file, but it will result in an error on every commit. not very nice.

And the third way - changesets, a new feature in SVN 1.5 clients. This is neat, but it’s only related to one working copy, not to a repository globally. And you have to set them up manually, add every new file — it’s hard to maintain.

Maciej Łebkowski
+3  A: 

Speaking of Tortoisesvn and changelists, it already comes with a changelist called ignore-on-commit, which does what you are looking for.

azkotoki
+1  A: 

If you're on Windows, use TortoiseSVN. You can add files to the special "ignore-on-commit" changelist that behaves exactly as you described.

spoulson
+3  A: 

Actually, a pre-commit script would do the job.

Write a pre-commit script that executes 'svnlook diff' and rejects the commit if there is a property named 'nocommit' being set in the changeset.

Then, in your working copy, you can just set a 'nocommit' property on any file that shouldn't be committed. Any subsequent commit will fail if any file has the 'nocommit' property. If you later do need to check in changes on the file, all you have to do is remove the 'nocommit' property from your working copy.

Don
+1  A: 

There have been a few answers that can work:

  1. Create a pre-commit hook script that reject the commit when a specific property is being added. You can then add this property to files in the working copy to prevent commits.
  2. TortoiseSVN will exclude files in the special changelist "ignore-on-commit". However, this is not honored by the SVN command-line client.

CoverosGene suggested that the default commands such as svn commit operate on a default changelist, such that you can exclude a file if you assign it to another changelist, but I can't find any reference of that in the documentation, and in my testing this does not work.

Since there is no good solution for the SVN command-line client, I've opened an enhancement request here. The request suggests that the command-line client could also honor the "ignore-on-commit" changelist.

Bruno De Fraine