如何将所有未版本控制的文件“ svn添加”到SVN?


177

我正在寻找一种自动将工作副本中所有未版本控制的文件自动“ svn添加”到我的SVN存储库的好方法。

我有一个实时服务器,可以创建一些应在源代码控制下的文件。我希望有一个简短的脚本可以运行以自动添加这些脚本,而不是每次都添加一个脚本。

我的服务器正在运行Windows Server 2003,因此Unix解决方案无法正常工作。


1
@Saul这个问题很明显早于您链接的那个问题,因此我看不出它是如何重复的。如果有其他问题,请重复。
中微子2014年

Cygwin是一种选择。在任何Windows环境中为您提供bash的功能。成为用户已有10多年了,但遇到的问题很小。
user151841 2014年

Answers:


346

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

大提示!一句话:我的Eclipse自动将新文件添加到忽略列表。这可能是配置问题,但无论如何:有--no-ignore帮助的选项。

之后,您可以提交:

svn commit -m 'Adding a file'

14
大提示。比使用svn status好得多。“ svn add --force”似乎就足够了。
命名

1
有没有简单的方法可以将其设置为缩短的宏(即,您可以使用git设置)?另外,是否有可能更新此答案,以便对每个位进行解释?
MrDuk

2
@MrDuk:缩短:alias magic="svn add --force * --auto-props --parents --depth infinity -q"-解释:svn help add
Ronan

17
问题是这会添加被忽略的文件正确吗?不可取。
ladieu2014年

1
@Name-您需要放在*末尾,否则它将不起作用(对我而言租用)
vsync

72

这是一个与不同的问题,但该问题有一个答案:

svn status | grep '?' | sed 's/^.* /svn add /' | bash

8
这使用了OP表示他没有的UNIX工具(grep,sed,bash)。
纳夫

3
如果您确实想要的话,也可以在Windows上挖出sed和grep。
Sam Saffron

1
对cygwin评论的投票表示抱歉,这不是故意的(我无法撤消)。实际上,我认为cygwin就像在Windows上一样丑陋。您仍然可以使用findstr而不是grep,因为至少从Windows 2000开始,它将不会运行,而无需安装任何其他组件。
乔伊(Joey)


2
我和mbyrne215在一起;这个答案比OP的解决方案对我有更大的帮助,所以我投票赞成。在OS X 10.6.7中完美运行。
阿斯比约恩Ulsberg

37

这是可行的:

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

添加子目录的内容。

不添加忽略的文件。

列出添加了哪些文件。

该命令中的点表示当前目录,如果要添加与当前目录不同的目录,则可以用特定的目录名或路径替换。


实际上,应该是.\*svn root在另一个dir上stuff\svn_root\*
Nux

我不懂 到SVN的命令是在执行路径的上下文中执行的,这是可以预期的。仅“ svn add。\ *”不会递归,并且会打印大量警告垃圾邮件,使您无法看到实际添加的内容。“ svn add。\ * --force”会递归,但也会显示“ svn:跳过参数:E200025:'。\。svn'以保留名称结尾”。因此,这似乎比我原来的解决方案还差。
中微子2014年

我指出的是,您可能在SVN上没有完整的C驱动器;-),因此应该添加路径。从我的测试指定路径来看,stuff\svn_root不会在子目录(例如中stuff\svn_root\already_in_svn\not_in_svn.txt)中添加文件。因此,最后的明星。
Nux

@Nux这些年来,直到现在,我终于终于明白了:)在命令中,点是指定当前目录的路径。自然,可以提供任何有效的替代方法。
Neutrino

这是正确的答案。我不确定包括添加被忽略文件的解决方案如何排在首位。@Neutrino,建议删除您对joey的注释,此注释将不再显示在此页面上,并添加一行以强调您的建议不会添加被忽略的文件
b_levitt

35

这对我有用:

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

来源

当您已经为Windows解决了问题时,这是UNIX解决方案(紧随Sam之后)。我在这里添加了内容,因为我认为这对于那些遇到相同问题的人仍然很有用(因为标题不包含关键字“ WINDOWS”)。

注意(2015年2月):如“ bdrx”所评论,可以通过以下方式进一步简化上述命令:

 svn add `svn status . | awk '/^[?]/{print $2}'`

1
美观,紧凑,简洁,也非常适合扩展。谢谢。
Norman H

1
大。也易于扩展,修改,删除等
Drewid

完美满足我的需求。谢谢!
杰夫

2
人们为什么总是grep然后通过管道传输到awk?AWK可以做模式匹配:awk '/^[?]/{print $2}'; 无需额外的grep流程。
bdrx

1
@bdrx:也许是因为grep通常与模式匹配相关联?就我个人而言,我对grep的经验比对awk的经验丰富。我不知道您可以在awk中执行这些操作,因此我将在脚本中更多地使用awk。谢谢!
lepe

5
svn add --force .

这将在当前目录和所有版本控制的子目录中添加所有未版本控制的文件。


5

此方法应处理文件名中包含任意数量/空格的组合...

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

以下是该命令的解释:

  • 列出所有更改的文件。
  • 将此列表限制为带有“?”的行 在开始-即新文件。
  • 去除 '?' 该行开头的字符。
  • 删除行首的空格。
  • 将文件名通过管道传递到xargs以多次运行svn add。

使用xargs的-i参数来处理是否能够将带有空格的文件名导入到'svn add'中-基本上,-i设置{}用作占位符,因此我们可以在'svn使用的文件名周围加上“加'。

此方法的优点是,它应该处理文件名中带有空格的文件名。


假设使用Linux或类似的软件(例如MinGWCygwin)。OP指出:“我的服务器正在运行Windows Server 2003,因此Unix解决方案将无法使用。”
彼得·莫滕森

4

如果您愿意使用非命令行解决方案,TortoiseSVN内置了此功能。只需右键单击顶层文件夹,然后选择添加 ...。


由于巨大的存储库,TortoiseSVN挂起。这使我寻找命令行替代方案:-)
Upendra'3


3

用:

svn st | grep ? | cut -d? -f2 | xargs svn add

1
您也可以使用cut来完成grep的工作: svn status | cut -d ? -f 2 -s | xargs svn add
Eric3 2011年

假设使用Linux或类似的软件(例如MinGWCygwin)。OP指出:“我的服务器正在运行Windows Server 2003,因此Unix解决方案将无法使用。”
彼得·莫滕森

3

我一直使用:

复制粘贴

svn st | grep "^\?" | awk "{print \$2}" | xargs svn add $1

1
Op明确指出,Unix解决方案对他没有用。
中微子

假设使用Linux或类似的软件(例如MinGWCygwin)。OP指出:“我的服务器正在运行Windows Server 2003,因此Unix解决方案将无法使用。”
彼得·莫滕森

3

由于这篇文章被标记为Windows,我想我会为Windows解决方案。我想自动化该过程,并制作了一个bat文件。我拒绝在C#中制作console.exe。

我想添加开始提交过程时未添加到存储库中的任何文件或文件夹。

许多答案的问题在于它们将列出未版本控制的文件,根据我在TortoiseSVN中的忽略列表,这些文件应被忽略。

这是我的钩子设置和批处理文件

乌龟钩脚本:

"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

2
for /f "usebackq tokens=2*" %%i in (`svn status ^| findstr /r "^\?"`) do svn add "%%i %%j"

在此实现中,如果您的文件夹/文件名具有多个如下所示的空间,您将遇到麻烦:

"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"

这样的情况很简单:

for /f "usebackq tokens=1*" %%i in (`svn status ^| findstr /r "^\?"`) do svn add "%%j"

2

如果您使用Linux或在Windows中使用Cygwin或MinGW,则可以使用类似以下bash的解决方案。与此处介绍的其他类似文件相比,此文件考虑了文件名空间:

svn status| grep ^? | while read line ; do  svn add "`echo $line|cut --complement -c 1,2`" ;done

这个是来做什么的?CMD?重击?它看起来像Bash(或类似的shell)。在这种情况下,它将假定为Linux或类似版本(例如MinGWCygwin)。OP指出:“我的服务器正在运行Windows Server 2003,因此Unix解决方案将无法使用。”
彼得·莫滕森

谢谢,您是对的,当我在Windows中时,将Cygwin与Bash一起使用。但是,语句“我的服务器正在运行Windows Server 2003,因此Unix解决方案将不起作用。” 是错误的。也许他不想使用Cygwin或MinGW,但他并没有以这种方式表达自己。我重新制定了回应。
最近

1

在花了一些时间试图弄清楚如何仅递归地添加一些文件之后,我认为分享对我有用的东西是有效的:

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"

这里有一些解释。

第一条命令添加所有目录。第二条命令仅将文件相应地添加到指定的模式。

让我提供更多细节:

  • FOR:您知道循环控制。
  • / F:表示获取文件和目录(不确定)。
  • %F:其为变量;它将一次假定每个列出的文件的值;它可以有另一个单字符名称。
  • IN:无需解释,对吗?
  • ('dir / s / b / a:d'):将列出目录的DOS命令;在我的情况下,/ s是递归的,/ b仅采用完整路径,/ a:d表示仅目录;更改它,如您所愿,保留括号和撇号。
  • DO:意味着命令的下一个内容是将对每个目录执行的内容
  • svn add --depth = empty:这是需要运行的SVN突击队;深度定义意味着仅添加目录,而不添加其中的文件。
  • “%F”:这就是您使用先前定义的变量的方式。

在第二个命令中,唯一的区别是dir命令和svn命令,我认为这很清楚。


0

您可以使用命令

svn add * force--

要么

svn add <directory/file name>

如果您的文件/目录不是递归添加的。然后检查。

递归添加是默认属性。您可以在SVN书中看到。

问题可能出在您的忽略列表或全局属性中。

我有解决方案的Google问题跟踪器

检查全局属性以忽略星号(*)

  • 右键单击窗口中的仓库。选择TortoiseSVN > Properties
  • 看看你没有财产 svn:global-ignores with a value of *
  • 如果您具有属性,star(*)则它将忽略递归添加。因此删除此属性。

检查全局忽略模式以忽略星号(*)

  • 右键单击窗口中的仓库。选择TortoiseSVN > Settings > General
  • 如果未在此处设置星号(*),请参见“全局忽略模式” 。
  • 如果找到star(*),请删除此属性。

这个人还解释了为什么将此属性添加到我的项目中。

最类似于到达该目录的方式是,有人右键单击没有任何扩展名的文件,然后选择TortoiseSVN-> SVN Ignore-> *(递归),然后提交该文件。

您可以检查日志以查看谁进行了该属性更改,找出他们实际尝试执行的操作,并要求他们将来更加小心。:)


0

您可以在Linux上输入以下命令:

find ./ -name "*." | xargs svn add

0

由于他指定了Windows,因此awk和sed不是标准的:

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

或在批处理文件中:

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

0

这是将目录与包含新文件的SVN同步的一种惰性和危险的方式:

svn rm --keep-local dir
svn add dir

尽管这可能会在紧急情况下起作用,但也会产生严重的后果。例如,SVN经常会丢失文件的历史记录。

同步目录的理想方法是能够进行差异处理然后使用svn补丁,但是这与diff命令中的格式有所不同,并且svn diff命令将比较工作目录差异而不是文件系统级别的差异。


-1

我想我已经做了类似的事情:

svn add . --recursive

但不确定我的记忆是否正确;-p


2
只是您的内存更新:svn 1.4和1.5不支持--recursive作为svn的参数添加:)
路德维希·文索尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.