SVN: Is there a way to mark a file as "do not commit"?
Asked Answered
L

18

161

With TortoiseSVN, I can move a file into the ignore-on-commit changelist, so that when I commit a whole tree, changes to that file do not get committed.

Is there a way to do something like that using the svn command-line tool?

EDIT: Thanks for the suggestions to use svn:ignore, but that doesn't do quite what I was looking for.

svn:ignore affects things like svn add & svn import. It gives it a list of filename patterns to ignore.

I have a file that's already under source control, but I want to make temporary changes to that file that I don't want to be committed later on when I commit the whole source tree. I am making a lot of other changes and I could stick a note on my monitor telling me to revert that file before I commit the tree, but it would be nice if svn could automatically skip that file.

Leath answered 11/3, 2009 at 17:0 Comment(1)
There is a way using personal branch and switch status. [See my other post on this subject.][1] [1]: #863450Putandtake
F
123

Subversion does not have a built-in "do not commit" / "ignore on commit" feature, as of February 2016 / version 1.9. This answer is a non-ideal command-line workaround

As the OP states, TortoiseSVN has a built in changelist, "ignore-on-commit", which is automatically excluded from commits. The command-line client does not have this, so you need to use multiple changelists to accomplish this same behavior (with caveats):

  • one for work you want to commit [work]
  • one for things you want to ignore [ignore-on-commit]

Since there's precedent with TortoiseSVN, I use "ignore-on-commit" in my examples for the files I don't want to commit. I'll use "work" for the files I do, but you could pick any name you wanted.

First, add all files to a changelist named "work". This must be run from the root of your working copy:

svn cl work . -R

This will add all files in the working copy recursively to the changelist named "work". There is a disadvantage to this - as new files are added to the working copy, you'll need to specifically add the new files or they won't be included. Second, if you have to run this again you'll then need to re-add all of your "ignore-on-commit" files again. Not ideal - you could start maintaining your own 'ignore' list in a file as others have done.

Then, for the files you want to exclude:

svn cl ignore-on-commit path\to\file-to-ignore

Because files can only be in one changelist, running this addition after your previous "work" add will remove the file you want to ignore from the "work" changelist and put it in the "ignore-on-commit" changelist.

When you're ready to commit your modified files you do wish to commit, you'd then simply add "--cl work" to your commit:

svn commit --cl work -m "message"

Here's what a simple example looks like on my machine:

D:\workspace\trunk>svn cl work . -R
Skipped '.'
Skipped 'src'
Skipped 'src\conf'
A [work] src\conf\db.properties
Skipped 'src\java'
Skipped 'src\java\com'
Skipped 'src\java\com\corp'
Skipped 'src\java\com\corp\sample'
A [work] src\java\com\corp\sample\Main.java
Skipped 'src\java\com\corp\sample\controller'
A [work] src\java\com\corp\sample\controller\Controller.java
Skipped 'src\java\com\corp\sample\model'
A [work] src\java\com\corp\sample\model\Model.java
Skipped 'src\java\com\corp\sample\view'
A [work] src\java\com\corp\sample\view\View.java
Skipped 'src\resource'
A [work] src\resource\icon.ico
Skipped 'src\test'

D:\workspace\trunk>svn cl ignore-on-commit src\conf\db.properties
D [work] src\conf\db.properties
A [ignore-on-commit] src\conf\db.properties

D:\workspace\trunk>svn status

--- Changelist 'work':
        src\java\com\corp\sample\Main.java
        src\java\com\corp\sample\controller\Controller.java
        src\java\com\corp\sample\model\Model.java
M       src\java\com\corp\sample\view\View.java
        src\resource\icon.ico

--- Changelist 'ignore-on-commit':
M       src\conf\db.properties

D:\workspace\trunk>svn commit --cl work -m "fixed refresh issue"
Sending        src\java\com\corp\sample\view\View.java
Transmitting file data .done
Committing transaction...
Committed revision 9.

An alternative would be to simply add every file you wish to commit to a 'work' changelist, and not even maintain an ignore list, but this is a lot of work, too. Really, the only simple, ideal solution is if/when this gets implemented in SVN itself. There's a longstanding issue about this in the Subversion issue tracker, SVN-2858, in the event this changes in the future.

Flinn answered 11/3, 2009 at 18:31 Comment(5)
I've added two files with the command you've mentioned: $svn st --- Changelist 'ignore-on-commit': M database.php M config.php and still, they have been sent to the repo on commit. Any idea what did I do wrong?Cephalo
Adding files to the changelist 'ignore-on-commit' doesn't in itself prevent files from being committed. TortoiseSVN (a Windows GUI client) has built in respect for "ignore-on-commit", but command line svn does not. The only suggestion I had in my original answer was to add the files you want to commit to a changelist, and tell it to commit thatFlinn
ignore-on-commit is defintiely a Tortoise reserved list. All it's doing is preventing the items from being checked in the GUI by default, so it's a Tortoise GUI specific feature. You don't need to use the command line to add to the list either if you use the GUI. Just context menu on commit list items and at the bottom you can move them to a changelist and ignore-on-commit is already defined. tortoisesvn.net/docs/release/TortoiseSVN_en/…Bastien
this didn't do jack. it committed everything.Schuss
Not working, the question specifically asked about a command line solution, not GUI.Dichlamydeous
M
26

I've consistently found myself in this situation too: and changelists don't work for me - I want to make a short list of files that I don't want to commit, rather than maintain a m-a-s-s-i-v-e list of files that I do want to commit!

I work on the linux command-line: so my solution is to create a script /usr/bin/svnn (yes, with two 'n's!) as follows:

#! /bin/bash
DIR=/home/mike/dev/trunk

IGNORE_FILES="\
        foo/pom.xml \
        foo/src/gwt/App.gwt.xml \
        foo/src/main/java/gwt/Common.gwt.xml \
        foo/src/main/resources/context/datasource/local.xml \
        foo/src/main/resources/context/environment/local.xml"

for i in $IGNORE_FILES; do mv $DIR/$i $DIR/"$i"_; done;

svn "$@"

for i in $IGNORE_FILES; do mv $DIR/"$i"_ $DIR/$i; done;

Obviously, this is tailored to my situation - but just change DIR and IGNORE_FILES to suit your dev setup. Remeber to change the script to executable with:

sudo chmod +x /usr/bin/svnn

..then you just use "svnn" instead of "svn" to run subversion without fear of checking in local changes to the files on the IGNORE_FILES list. I hope this helps!

Metaphrase answered 17/9, 2012 at 0:44 Comment(3)
Finally, this answer is actually right. You need to write some tool. This is actually imperfect, because i want to have a dynamic option, like svnn ignore configs/* - with wildcards, and bells and whistles. I think I write something like that myself, and then get back here!Demoiselle
this is great! Even better, create an alias in .bashrc for svn -> svnn. Even better, instead of specifying the files to ignore inside the command, it could behave like git, it would check a .ignore file inside the folder and ignore every file that matches the pattern.Astonied
Instead of having to re-learn typing svnn, consider calling it svn and placing this script in something that can be at the start of your PATH, such as ${HOME}/bin. From the script itself, you would then call /usr/bin/svn.Midlands
H
19

I don't believe there is a way to ignore a file in the repository. We often run into this with web.config and other configuration files.

Although not perfect, the solution I most often see and use is to have .default file and an nant task to create local copies.

For example, in the repo is a file called web.config.default that has default values. Then create a nant task that will rename all the web.config.default files to web.config that can then be customized to local values. This task should be called when a new working copy is retrieved or a build is run.

You'll also need to ignore the web.config file that is created so that it isn't committed to the repository.

Hacking answered 11/3, 2009 at 17:45 Comment(0)
F
8

Check out changelists, which can provide you with an option to filter out files you have changed but do not want to commit. SVN will not automatically skip a file unless you tell it to - and the way you tell it that this file is somehow different to other files is to put it in a changelist.

It does require more work for you, and you can only apply the changelist to your working copy (obviously, imagine the chaos that could ensue if you could apply a 'never update' property to a revision!).

Fickle answered 11/3, 2009 at 18:8 Comment(1)
But that is exactly what we want. For example, a source file which you need to set a defaultUserId = yourId, instead of the system default.Infatuation
B
5

I came to this thread looking for a way to make an "atomic" commit of just some files and instead of ignoring some files on commit I went the other way and only commited the files I wanted:

svn ci filename1 filename2

Maybe, it will help someone.

Boaten answered 23/11, 2010 at 15:10 Comment(1)
Your answer is only one adequate suggestion in this thread. svn ci is simply alias to svn commit. Commit command allows to make particular commit of specified filesFlaviaflavian
B
2

Conflicted files are not allowed to be committed. You can take advantage of this to keep your private changes out of the repository. This works best with a small number of files.

To get a conflict for a-file, your working copy (WC) does not have the up to date a-file from the repository, and that the a-file in your WC has changes that are in the same location as changes in the repository (changes that you didn't update to yet). If you don't want to wait for the conditions above you can create a conflict for a-file like this:
In working copy 1 (WC1), add a line of text to the top of a-file, such as "make a conflict here". Use the necessary syntax so that you don't break the repository. Commit a-file from WC1. In WC2, add a different line of text to the top of a-file, like "i want a conflict". Update from WC2, and now a-file should be in conflict.

Buyer answered 23/7, 2009 at 17:21 Comment(0)
F
2

Guys I just found a solution. Given that TortoiseSVN works the way we want, I tried to install it under Linux - which means, running on Wine. Surprisingly it works! All you have to do is:

  1. Add files you want to skip commit by running: "svn changelist 'ignore-on-commit' ".
  2. Use TortoiseSVN to commit: "~/.wine/drive_c/Program\ Files/TortoiseSVN/bin/TortoiseProc.exe /command:commit /path:'
  3. The files excluded will be unchecked for commit by default, while other modified files will be checked. This is exactly the same as under Windows. Enjoy!

(The reason why need to exclude files by CLI is because the menu entry for doing that was not found, not sure why. Any way, this works great!)

Faeroese answered 12/8, 2011 at 2:38 Comment(0)
A
2

You can configure the "ignore-on-commit" changelist directly with TortoiseSVN. No need to configure any other changelist including all the others files

1) Click "SVN Commit..." (we will not commit, just a way to find a graphical menu for the changelist) 2) On the list Right click on the file you want to exclude. 3) Menu: move to changelist > ignore-on-commit

The next time you do a SVN Commit... The files will appear unchecked at the end of the list, under the category ignore-on-commit.

Tested with : TortoiseSVN 1.8.7, Build 25475 - 64 Bit , 2014/05/05 20:52:12, Subversion 1.8.9, -release

Artimas answered 18/4, 2016 at 12:45 Comment(2)
youps, I just saw the comments of tjmoore, already giving the good info for tortoiseSVN user... no command line tortoisesvn.net/docs/release/TortoiseSVN_en/…Artimas
Is this broken in 1.9?Decanter
S
1

I would instead write a helper bash script that runs svn commit on all the files you need to and none of the ones you don't. This way you have much more control.

For example, with one line, you can commit all files with extension .h and .cpp to which you made changes (and which wouldn't cause a conflict):

svn commit -m "" `svn status | grep "^M.*[h|cpp]$" | awk '{print $2}' | tr "\\n" " "`

Change / add extensions to the [h|cpp] part. Add a log message in between the quotes of -m "" if needed.

Scharff answered 11/5, 2011 at 21:43 Comment(0)
B
1

Some of the proposed ideas can be implemented like this:

On Windows in PowerShell

add all to default list.ps1

dir -Recurse | ? { -not $_.PSIsContainer } | % { svn cl default $_.FullName }

add to ignore list.ps1

 dir file1 ... filN  % { $_.FullName } > ignore-on-commit
 cat .\ignore-on-commit | % { svn cl ignore-on-commit $_ }
 svn add ignore-on-commit

Now, you can alias svn ci --changelist default so that you don't have to specify it each time. The additional benefit is that you can store the ignore-on-commit list (if you want) in the repository.

I do this for some files which are constantly regenerated but rarely actually changed by hand. For instance I add revision number to my config files on specific placeholders so files are changed on each commit, yet manual change is rare.

Bluejacket answered 20/5, 2013 at 9:12 Comment(0)
N
1

I got tired of waiting for this to get built into SVN. I was using tortoiseSVN with ignore-on-commit, but that pops up a user dialog box that you can't suppress from the command line, and when I run my build script and go and make a cup of tea, I hate it when I come back to discover it's waiting for user input 10% of the way through.

So here's a windows powershell script that commits only files that aren't in a changelist:

# get list of changed files into targets
[XML]$svnStatus = svn st -q --xml C:\SourceCode\Monad
# select the nodes that aren't in a changelist
$fileList = $svnStatus.SelectNodes('/status/target/entry[wc-status/@item != "unversioned"]') | Foreach-Object {$_.path};
# create a temp file of targets
$fileListPath =  [IO.Path]::GetTempFileName();
$fileList | out-file $fileListPath -Encoding ASCII
# do the commit
svn commit --targets $fileListPath -m "Publish $version" --keep-changelists 
# remove the temp file
Remove-Item $filelistPath
Noonan answered 9/11, 2013 at 11:43 Comment(0)
L
1

Update of user88044's script.

The idea is to push the files in the do-not-commit changelist and run the evil script.

The script extracts the do-not-commit files from the command : svn status --changelist 'do-not-commit'

#! /bin/bash DIR="$(pwd)"

IGNORE_FILES="$(svn status --changelist 'do-not-commit' | tail -n +3 | grep -oE '[^ ]+$')"

for i in $IGNORE_FILES; do mv $DIR/$i $DIR/"$i"_; done;

svn "$@";

for i in $IGNORE_FILES; do mv $DIR/"$i"_ $DIR/$i; done;

The script is placed in /usr/bin/svnn (sudo chmod +x /usr/bin/svnn)

svnn status, svnn commit, etc...

Leeds answered 13/1, 2015 at 21:16 Comment(0)
A
1

This is late to the game, but I found the most awesome-est command line command for this problem. Done using bash. Enjoy.

svn status | grep -v excluding | sed 's/^A */"/g; s/$/"/g' | tr '\n' ' ' | xargs svn commit -m "My Message"

Ok, so here's an explanation of the command. Some things will need to be changed based on your use case.

svn status

I get a list of all the files. They'll all start with those status characters (?, !, A, etc). Each is on its own lines

grep -v excluding

I use grep to filter the list. It can either be used normally (to include) or with the -v flag (to exclude). In this case, it's being used to exclude, with a phrase "excluding" being what will be excluded.

sed 's/^. */"/g; s/$/"/g'

Now I remove the status character and whitespace at the beginning of each line, and then quote each line, using sed. Some of my filenames have spaces in them, hence the quoting.

tr '\n' ' '

Using tr, I replace all newlines with spaces. Now my entire list of files to commit is on one line.

xargs svn commit -m "My Message"

Lastly, I use xargs to execute my commit command with the message. It does the commit, and drops my quoted file list as the last argument.

The result is that everything ultimately works the way that I want it to. I still kind of hate svn for forcing me to jump through these goddamn hoops, but I can live with this. I guess.

Assyria answered 28/9, 2017 at 18:10 Comment(0)
L
0

As I was facing the exact same issue, and my googling kept giving me nothing, I think I found a workaround. Here's what I did, it seems to work for me, but as I'm stuck with an old version of SVN (< 1.5, as it doesn't have the --keep-local option) and I'm no expert of it, I can't be sure it's an universal solution. If it works for you too, please let me know !

I was dealing with a Prestashop install I got from SVN, since other people had already started working on it. Since the DB settings were done for another server, I changed them in some file in the /config folder. As this folder was already versioned, setting it in svn:ignore would not prevent my local modifications on it from being committed. Here's what I did :

cp config ../cfg_bkp              # copy the files out of the repo
svn rm config                     # delete files both from svn and "physically"
svn propset svn:ignore "config" . # as the files no longer exists, I can add my ignore rule and then...
mv ../cfg_bkp config              # ...bring'em back
svn revert --recursive config     # make svn forget any existing status for the files (they won't be up for deletion anymore)

Now I can run svn add --force . at the repo root without adding my config, even if it's not matching the repo's version (I guess I would have to go through all this again if I modified it one more time, did not test). I can svn update as well without having my files being overwritten or getting any error.

Lavonia answered 26/7, 2012 at 13:9 Comment(0)
F
0

A solution that does not ignore changes in directory properties

I tried to use the solution based on changelist, but I have a couple of issues with it. First my repository has thousand of files, so the changelist to be committed is huge, and my svn status output became way too long and needed to be parsed to be useful. Most important is that I wanted to commit changes that came from a merge, which means they include property changes. When committing a changelist, the svn properties attached to the directory are not committed, so I had to do an extra commit:

svn ci --cl work -m "this commits files from the work changelist only"
svn up
svn ci --depth empty DIR . -m "record merge properties"

You may have to do that for several directories (here I record the properties of DIR and of the current dir .), basically those with a M in the second column when issuing the svn status command.

Solution

I used patches and svn patch. In pseudo-code:

svn diff $IGNORE_FILES > MYPATCH   # get the mods to ignore
svn patch --reverse-diff MYPATCH   # remove the mods
svn ci -m "message"                # check-in files and directory properties
svn patch MYPATCH                  # re-apply the mods

Like other posters, I end up using a script to maintain the list of files to ignore:

#! /usr/bin/env bash

finish() {
    svn patch MYPATCH               # re-apply the mods
}
trap finish EXIT

IGNORE_FILES="\
sources/platform/ecmwf-cca-intel-mpi.xml \
runtime/classic/platform/ecmwf-cca.job.tmpl \
runtime/classic/platform/ecmwf-cca-intel.xml"

svn diff $IGNORE_FILES > MYPATCH # get the mods to ignore
svn patch --reverse-diff MYPATCH # remove the mods

svn "$@"

I typically used it with ci and revert -R ..

Fabi answered 24/4, 2018 at 15:41 Comment(0)
H
0

If you are on linux, below answer will be useful

Step 1 Create .svnignore file in root level of your working copy, and add folders/files in each new line(e.g, below)

\.
folder1
folder2
folder3/file2.html
folder4/file1.js

Note: You also need to add \. as that points to root directory

Tip: To get exact folder/file path, run svn st -u then copy and paste same path in .svnignore file

Step 2 Run below command to commit everything except folder/files from .svnignore file

svn ci -m "YOUR-COMMENT-HERE" $(svn st | grep -v -w -f .svnignore | awk '{print $NF}')

Command Explanation

╔════════════════════╦════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ svn ci             ║ Shorthand for svn commit                                                                               ║
╠════════════════════╬════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ svn st             ║ Shorthand for svn status                                                                               ║
╠════════════════════╬════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ |                  ║ Pipe(|) is used to pass output of previous command to next command's input                             ║
╠════════════════════╬════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ grep               ║ grep is a linux command to filter                                                                      ║
╠════════════════════╬════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ grep -v            ║ Give result other than matched (Inverse)                                                               ║
╠════════════════════╬════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ grep -w            ║ Exact match(used to match literal Dot(.))                                                              ║
╠════════════════════╬════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ grep -f filename   ║ Read pattern from file                                                                                 ║
╠════════════════════╬════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ awk '{print $NF}') ║ print last column data (columns are divided with space delimiter), used to get exact folder/file names ║
╚════════════════════╩════════════════════════════════════════════════════════════════════════════════════════════════════════╝
Hydrangea answered 26/8, 2020 at 6:28 Comment(0)
B
-3

svn:ignore is your answer.

Example:

$ svn propset svn:ignore -F .cvsignore .
property 'svn:ignore' set on '.'
Byers answered 11/3, 2009 at 17:1 Comment(3)
Note, the above example shows how to use a previously-configured cvsignore file as input to your svnignore property.Drainpipe
no svn:ignore is just for unversion files. dosn't work with version filesErgonomics
And also it is not local. It is a property change that will be commited by itself.Dupe
D
-11
svn propset "svn:ignore" "*.xml" .

the *.xml is the pattern of files to ignore; you can use directory names here as well.

Donau answered 11/3, 2009 at 17:6 Comment(1)
-1 because you can't ignore a file that is part of the repository.Selig

© 2022 - 2024 — McMap. All rights reserved.