Subversion: prevent local modifications to one fil

2019-01-10 18:49发布

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.

标签: svn
13条回答
该账号已被封号
2楼-- · 2019-01-10 19:15

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.

查看更多
干净又极端
3楼-- · 2019-01-10 19:18

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!

查看更多
爷、活的狠高调
4楼-- · 2019-01-10 19:21

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

查看更多
叛逆
5楼-- · 2019-01-10 19:22

For the last several years I have been using a simple solution which achieves exactly what you are looking for. It is called the NOCOMMIT keyword.

What I do is that I have a pre-commit hook in my SVN repository which checks to see whether any file contains the string NOCOMMIT, and if so, it fails the commit.

So, when a programmer makes a modification that should not be committed, (say, they changed the project-wide database connection string from the company-wide test server to their own local test server, or they added diagnostic debug statements that are going to be spamming the log with thousands of lines per second,) they append a //NOCOMMIT comment to it, and they do not have to worry about accidentally committing it. When the time comes to commit, they are prevented, so they are forced to either:

  • move that file to their do-not-commit changelist, or
  • search for NOCOMMIT and remove any occurrences of it, thus hopefully fixing the code that they had attached it to.

Personally, I find the NOCOMMIT keyword so useful that I use it even when working on pet projects of mine, where obviously, I am the only programmer in the team.

If you are using windows, you can paste the following text into file called pre-commit.bat in the hooks folder of your SVN repository.

:: Stops commits that contain the NOCOMMIT keyword.
setlocal  
set REPOS=%1  
set TXN=%2           
SVNLook diff %REPOS% -t %TXN% | findstr /I /M /L NOCOMMIT > nul
if %errorlevel% gtr 0 (
    exit 0
) else (
    echo Your commit has been blocked because it contains the keyword NOCOMMIT. 1>&2  
    exit 1
)

On Unix systems, something like the following should do the trick, though please note that I have not tested it.

#!/bin/sh
REPOS="$1"
TXN="$2"
SVNLOOK=/usr/local/bin/svnlook
$SVNLOOK diff -t "$TXN" "$REPOS" | grep -i "NOCOMMIT" > /dev/null && { echo "Your commit has been blocked because it contains the keyword NOCOMMIT." 1>&2; exit 1; }
查看更多
Evening l夕情丶
6楼-- · 2019-01-10 19:23

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.

查看更多
欢心
7楼-- · 2019-01-10 19:28

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.

查看更多
登录 后发表回答