180

I'm looking for a good way to automatically 'svn add' all unversioned files in a working copy to my SVN repository.

I have a live server that can create a few files that should be under source control. I would like to have a short script that I can run to automatically add these, instead of going through and adding them one at a time.

My server is running Windows Server 2003 so a Unix solution won't work.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
JerSchneid
  • 5,635
  • 4
  • 31
  • 36
  • 1
    @Saul This question clearly predates the one you linked so I don't see how it can be a duplicate. If anything the other question is the duplicate. – Neutrino Feb 13 '14 at 12:03
  • Cygwin is an option. Gives you the power of bash on any windows environment. Been a user for over 10 years with very minor problems. – user151841 Dec 03 '14 at 02:02

19 Answers19

354

svn add --force * --auto-props --parents --depth infinity -q

Great tip! One remark: my Eclipse adds new files to the ignore list automatically. It may be a matter of configuration, but anyhow: there is the --no-ignore option that helps.

After this, you can commit:

svn commit -m 'Adding a file'
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Ronan
  • 4,261
  • 3
  • 17
  • 14
72

This is a different question to mine but there is an answer there that belongs on this question:

svn status | grep '?' | sed 's/^.* /svn add /' | bash
Community
  • 1
  • 1
Sam Saffron
  • 121,058
  • 74
  • 309
  • 495
  • 8
    This uses UNIX tools (grep, sed, bash) which the OP said he didn't have. – Naaff Jul 01 '09 at 23:55
  • 3
    also you could probably dig up sed and grep on windows if you really wanted. – Sam Saffron Jul 02 '09 at 05:13
  • 1
    Sorry for that upvote on the cygwin comment, wasn't intentional (and I can't undo it). In fact I think cygwin is as ugly as you can get on Windows. You can still use findstr instead of grep which will work at least since Windows 2000 without installing anything additional. – Joey Jul 02 '09 at 10:09
  • @Johannes just for you http://meta.stackexchange.com/questions/1775/why-can-you-not-take-back-an-upvote-on-a-comment – Sam Saffron Jul 02 '09 at 12:19
  • So install cygwin. This probably won't be the last time he needs to automate something. (deleted original comment that was above, to get rid of upvote) – KeyserSoze Jul 02 '09 at 18:56
  • I know the OP said he didn't have UNIX tools, but this is the question that came up when I was looking for this answer, so I'm voting it up. – mbyrne215 Nov 19 '10 at 17:04
  • 2
    I'm with mbyrne215; this answer helped me more than the OP's solution, so I'm voting it up. Works perfectly in OS X 10.6.7. – Asbjørn Ulsberg Mar 29 '11 at 16:40
  • I've used Cygwin for 6 years with Mercurial on Windows and didn't have any particularly spectacular challenges. Nice to see some non-windows solutions posted for those of us on a *nix varient. (Mac OS X :-)) – Norman H Feb 23 '12 at 13:37
  • Any idea's how I could move this into an alias for less copy-pasta? – Steve Robbins Mar 11 '13 at 22:59
  • +1 unlike the accepted answer, this solution honors svn ignores – Stephen Swensen May 11 '14 at 02:32
40

What works is this:

c:\work\repo1>svn add . --force

Adds the contents of subdirectories.

Does not add ignored files.

Lists what files were added.

The dot in the command indicates the current directory, this can replaced by a specific directory name or path if you want to add a different directory than the current one.

Neutrino
  • 6,048
  • 4
  • 37
  • 64
  • Actually that should be `.\*` or if svn root is on a different dir `stuff\svn_root\*`. – Nux Feb 12 '14 at 14:01
  • I don't follow. Commands to SVN execute in the context of the path from which they are executed, this is to be expected. "svn add .\\*" alone does not recurse and prints a load of warning spam making it impossible to see what was actually added. "svn add .\\* --force" does recurse but also prints "svn: Skipping argument: E200025: '.\.svn' ends in a reserved name". So that seems worse than my original solution. – Neutrino Feb 13 '14 at 11:59
  • I was pointing out that you probably don't have whole C drive on SVN ;-), and so you should add a path. And from my testing specifing path as `stuff\svn_root` doesn't add files in sub directories (e.g. in `stuff\svn_root\already_in_svn\not_in_svn.txt`). Hence the star at the end. – Nux Feb 14 '14 at 20:03
  • 1
    @Nux Only now after all these years do I finally see what you were getting at :) In the command the dot is the path that specifies the current directory. Naturally any valid alternative can be supplied instead. – Neutrino Jan 03 '17 at 13:43
  • 1
    This IS the right answer. I'm not sure how a solution that includes adding ignored files has the top spot. @Neutrino, suggest removing your comment to joey which no longer appears on this page, and also add a line reinforcing that your suggestion does NOT add ignored files – b_levitt Dec 01 '17 at 21:18
35

This worked for me:

svn add `svn status . | grep "^?" | awk '{print $2}'`

(Source)

As you already solved your problem for Windows, this is a UNIX solution (following Sam). I added here as I think it is still useful for those who reach this question asking for the same thing (as the title does not include the keyword "WINDOWS").

Note (Feb, 2015): As commented by "bdrx", the above command could be further simplified in this way:

 svn add `svn status . | awk '/^[?]/{print $2}'`
lepe
  • 22,543
  • 9
  • 85
  • 99
  • 1
    Nice, compact, concise, also lends itself to extension quite well. Thanks. – Norman H Feb 23 '12 at 13:38
  • 1
    Great. Also easy to expand, modify to delete etc. – Drewid Apr 18 '12 at 14:43
  • Perfect for what i needed. Thank you! – Jeff Jun 14 '12 at 16:06
  • 2
    Why do people always grep and then pipe to awk? Awk can do pattern matching: `awk '/^[?]/{print $2}'`; No need for the extra grep process. – bdrx Feb 26 '15 at 13:59
  • 1
    @bdrx: Perhaps because grep is commonly associated with pattern matching? In my personal case, I'm much more experienced with grep than with awk. I wasn't aware that you could do such things in awk, so I will start using awk more in my scripts. Thanks! – lepe Feb 27 '15 at 00:45
  • The first variation seemed to break on filenames with spaces, didn't check the second variation. – siliconpi Feb 03 '16 at 12:31
  • Both variations break if there are spaces in directories or filenames. – tholu Nov 28 '16 at 10:52
5
svn add --force .

This will add any unversioned file in the current directory and all versioned child directories.

jmc734
  • 297
  • 3
  • 3
5

This method should handle filenames which have any number/combination of spaces in them...

svn status /home/websites/website1 | grep -Z "^?" | sed s/^?// | sed s/[[:space:]]*// | xargs -i svn add \"{}\"

Here is an explanation of what that command does:

  • List all changed files.
  • Limit this list to lines with '?' at the beginning - i.e. new files.
  • Remove the '?' character at the beginning of the line.
  • Remove the spaces at the beginning of the line.
  • Pipe the filenames into xargs to run the svn add multiple times.

Use the -i argument to xargs to handle being able to import files names with spaces into 'svn add' - basically, -i sets {} to be used as a placeholder so we can put the " characters around the filename used by 'svn add'.

An advantage of this method is that this should handle filenames with spaces in them.

bailey86
  • 221
  • 3
  • 5
  • This presumes Linux or similar (e.g. [MinGW](http://en.wikipedia.org/wiki/MinGW) or [Cygwin](http://en.wikipedia.org/wiki/Cygwin)). The OP stated: *"My server is running Windows Server 2003 so a Unix solution won't work."* – Peter Mortensen Nov 29 '16 at 17:45
4

TortoiseSVN has this capability built in, if you're willing to use a non-command-line solution. Just right click on the top level folder and select Add...

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
John Meagher
  • 20,560
  • 13
  • 50
  • 57
3

I always use:

Copy&paste

svn st | grep "^\?" | awk "{print \$2}" | xargs svn add $1
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Oritm
  • 2,064
  • 2
  • 23
  • 40
  • 1
    Op explicity states that a Unix solution is no use to him. – Neutrino Aug 27 '12 at 14:46
  • This presumes Linux or similar (e.g. [MinGW](http://en.wikipedia.org/wiki/MinGW) or [Cygwin](http://en.wikipedia.org/wiki/Cygwin)). The OP stated: *"My server is running Windows Server 2003 so a Unix solution won't work."* – Peter Mortensen Nov 29 '16 at 17:45
3

Use:

svn st | grep ? | cut -d? -f2 | xargs svn add
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Xiè Jìléi
  • 12,317
  • 15
  • 72
  • 100
  • 1
    Or you can use cut to do grep's job: `svn status | cut -d ? -f 2 -s | xargs svn add` – Eric3 Jun 09 '11 at 16:53
  • This presumes Linux or similar (e.g. [MinGW](http://en.wikipedia.org/wiki/MinGW) or [Cygwin](http://en.wikipedia.org/wiki/Cygwin)). The OP stated: *"My server is running Windows Server 2003 so a Unix solution won't work."* – Peter Mortensen Nov 29 '16 at 17:40
3

This is as documented on svn book and the simplest and works perfect for me

svn add * --force

http://svnbook.red-bean.com/en/1.6/svn.ref.svn.c.add.html

Serjik
  • 9,013
  • 6
  • 57
  • 65
3

Since this post is tagged Windows, I thought I would work out a solution for Windows. I wanted to automate the process, and I made a bat file. I resisted making a console.exe in C#.

I wanted to add any files or folders which are not added in my repository when I begin the commit process.

The problem with many of the answers is they will list unversioned files which should be ignored as per my ignore list in TortoiseSVN.

Here is my hook setting and batch file which does that

Tortoise Hook Script:

"start_commit_hook".
(where I checkout) working copy path = C:\Projects
command line: C:\windows\system32\cmd.exe /c C:\Tools\SVN\svnadd.bat
(X) Wait for the script to finish
(X) (Optional) Hide script while running
(X) Always execute the script

svnadd.bat

@echo off

rem Iterates each line result from the command which lists files/folders
rem     not added to source control while respecting the ignore list.
FOR /F "delims==" %%G IN ('svn status ^| findstr "^?"') DO call :DoSVNAdd "%%G"
goto end

:DoSVNAdd
set addPath=%1
rem Remove line prefix formatting from svn status command output as well as
rem    quotes from the G call (as required for long folder names). Then
rem    place quotes back around the path for the SVN add call.
set addPath="%addPath:~9,-1%"
svn add %addPath%

:end
Valamas
  • 22,332
  • 24
  • 97
  • 172
2
for /f "usebackq tokens=2*" %%i in (`svn status ^| findstr /r "^\?"`) do svn add "%%i %%j"

Within this implementation, you will get in trouble in the case your folders/filenames have more than one space like below:

"C:\PROJECTS\BACKUP_MGs_via_SVN\TEST-MG-10\data\destinations\Sega Mega      2"
"C:\PROJECTS\BACKUP_MGs_via_SVN\TEST-MG-10\data\destinations\One space"
"C:\PROJECTS\BACKUP_MGs_via_SVN\TEST-MG-10\data\destinations\Double  space"
"C:\PROJECTS\BACKUP_MGs_via_SVN\TEST-MG-10\data\destinations\Single"

such cases are covered by simple:

for /f "usebackq tokens=1*" %%i in (`svn status ^| findstr /r "^\?"`) do svn add "%%j"
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
olexa
  • 21
  • 1
2

If you use Linux or use Cygwin or MinGW in windows you can use bash-like solutions like the following. Contrasting with other similar ones presented here, this one takes into account file name spaces:

svn status| grep ^? | while read line ; do  svn add "`echo $line|cut --complement -c 1,2`" ;done
ajaest
  • 525
  • 4
  • 13
  • What is this for? CMD? Bash? It looks like Bash (or a similar shell). In that case, it presumes Linux or similar (e.g. [MinGW](http://en.wikipedia.org/wiki/MinGW) or [Cygwin](http://en.wikipedia.org/wiki/Cygwin)). The OP stated: *"My server is running Windows Server 2003 so a Unix solution won't work."* – Peter Mortensen Nov 29 '16 at 17:47
  • Thanks, you are right, when I am in Windows I use Cygwin with Bash. However the statement "My server is running Windows Server 2003 so a Unix solution won't work." is false. Maybe he don't want to use Cygwin or MinGW, but he didn't expressed himself in that way. I reformulated the response. – ajaest Dec 02 '16 at 13:11
1

After spending some time trying to figure out how to recursively add only some of the files, i thought it would be valid to share what did work for me:

FOR /F %F IN ('dir /s /b /a:d') DO svn add --depth=empty "%F"
FOR /F %F IN ('dir /s /b /a *.cs *.csproj *.rpt *.xsd *.resx *.ico *.sql') DO svn add "%F"

Here goes some explanation.

The first command adds all the directories. The second command adds only the files accordingly to the specifed patterns.

Let me give more details:

  • FOR: you know, the loop control.
  • /F: means take the files and directories (not sure exactly).
  • %F: its a variable; it will assume the value of each of the listed files at a time; it could have another one-character-name.
  • IN: no need to explain, right?
  • ('dir /s /b /a:d'): the DOS command that will list the directories; in my case /s is recursive, /b is to take only the full path, /a:d means only the directory; change it as you wish keeping the parenthesis and apostrophes.
  • DO: means that what comes next in the command is what will be executed for each directory
  • svn add --depth=empty: it is the desired SVN commando to be run; the depth definition means to add only the directory and not the files inside them.
  • "%F": that's how you use the variable defined earlier.

In the second command, the only differences are the dir command and the svn command, i think it is clear enough.

heringer
  • 2,088
  • 1
  • 17
  • 29
1

You can use command

svn add * force--

or

svn add <directory/file name>

If your files/directories are not adding recursively. Then check this.

Recursive adding is default property. You can see in SVN book.

Issue can be in your ignore list or global properties.

I got solution google issue tracker

Check global properties for ignoring star(*)

  • Right click in your repo in window. Select TortoiseSVN > Properties.
  • See if you don't have a property svn:global-ignores with a value of *
  • If you have property with star(*) then it will ignore recursive adding. So remove this property.

Check global ignore pattern for ignoring star(*)

  • Right click in your repo in window. Select TortoiseSVN > Settings > General.
  • See in Global Ignore Pattern, if you don't have set star(*) there.
  • If you found star(*), remove this property.

This guy also explained why this property added in my project.

The most like way that it got there is that someone right-clicked a file without any extension and selected TortoiseSVN -> SVN Ignore -> * (recursively), and then committed this.

You can check the log to see who committed that property change, find out what they were actually trying to do, and ask them to be more careful in future. :)

Khemraj Sharma
  • 46,529
  • 18
  • 168
  • 182
0

You can input the following command on Linux:

find ./ -name "*." | xargs svn add
Stephen Rauch
  • 40,722
  • 30
  • 82
  • 105
liu zhijun
  • 11
  • 1
0

Since he specified Windows, where awk & sed aren't standard:

for /f "tokens=1*" %e in ('svn status^|findstr "^\?"') do svn add "%f"

or in a batch file:

for /f "tokens=1*" %%e in ('svn status^|findstr "^\?"') do svn add "%%f"
WLH
  • 1
0

This is the lazy and dangerous way to synchronize a directory with SVN including new files:

svn rm --keep-local dir
svn add dir

Although this can work in a pinch it can have serious consequences as well. For example, SVN will often lose track of a file's history.

The ideal way to syncronize a directory would be to be able to diff then use svn patch, however this deviates from formats in the diff command and the svn diff command will compare working directory differences rather than differences on the file system level.

jgmjgm
  • 3,028
  • 1
  • 20
  • 18
-1

I think I've done something similar with:

svn add . --recursive

but not sure if my memory is correct ;-p

chakrit
  • 57,172
  • 24
  • 125
  • 160