SVN:有没有办法将文件标记为“不提交”?

时间:2009-03-11 17:00:28

标签: svn command-line

使用TortoiseSVN,我可以将文件移动到ignore-on-commit更改列表中,这样当我提交整个树时,对该文件的更改不会被提交。

有没有办法使用svn命令行工具做类似的事情?

编辑:感谢您使用svn:ignore的建议,但这并不是我想要的。

svn:ignore会影响svn add& svn import。它给出了一个要忽略的文件名模式列表。

我有一个已经受源代码控制的文件,但是我希望对该文件进行临时更改,以后在提交整个源代码树时我不想再提交。我正在进行很多其他更改,我可以在我的监视器上粘贴一条说明,告诉我在提交树之前恢复该文件,但如果svn可以自动跳过该文件,那将会很好。

18 个答案:

答案 0 :(得分:116)

截至2016年2月/版本1.9,Subversion没有内置的“不提交”/“提交时忽略”功能。这个答案是一个非理想的命令行解决方法

正如OP所述,TortoiseSVN有一个内置的变更列表,“ignore-on-commit”,它会自动从提交中排除。 命令行客户端没有这个,所以你需要使用多个更改列表来完成同样的行为(有警告)

  • 您要提交的工作[工作]
  • 一个你想忽略的东西[ignore-on-commit]

由于有TortoiseSVN的先例,我在我的例子中使用“ignore-on-commit”来获取我不想提交的文件。我会对我的文件使用“work”,但你可以选择你想要的任何名字。

首先,将所有文件添加到名为“work”的更改列表中。必须从工作副本的根目录运行:

svn cl work . -R

这会将工作副本中的所有文件递归地添加到名为“work”的更改列表中。这样做有一个缺点 - 随着新文件被添加到工作副本中,您需要专门添加新文件,否则它们将不会包含在内。其次,如果你必须再次运行它,那么你需要再次重新添加所有“ignore-on-commit”文件。不理想 - 您可以像其他人一样开始在文件中维护自己的“忽略”列表。

然后,对于要排除的文件:

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

因为文件只能在一个更改列表中,所以在上一次“工作”添加之后运行此添加将从“工作”更改列表中删除要忽略的文件,并将其放入“ignore-on-commit”更改列表中。

当您准备好提交您希望提交的修改过的文件时,您只需在提交中添加“--cl work”:

svn commit --cl work -m "message"

以下是我的机器上的一个简单示例:

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.

另一种方法是简单地将您希望提交的每个文件添加到“工作”更改列表中,甚至不维护忽略列表,但这也是很多工作。实际上,唯一简单,理想的解决方案是在SVN本身实现这一点。在Subversion问题跟踪器SVN-2858中有一个长期存在的问题,如果将来这种情况发生变化。

答案 1 :(得分:26)

我也一直发现自己处于这种情况:并且变更列表对我不起作用 - 我想列出我想要提交的文件的简短列表,而不是维护我想要提交的大量文件列表!

我在linux命令行上工作:所以我的解决方案是创建一个脚本/ usr / bin / svnn(是的,有两个'n!),如下所示:

#! /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;

显然,这是根据我的情况量身定制的 - 但只需更改DIR和IGNORE_FILES以适合您的开发设置。记得用以下内容将脚本更改为可执行文件:

sudo chmod +x /usr/bin/svnn

..然后你只需使用“svnn”而不是“svn”来运行subversion而不用担心检查IGNORE_FILES列表上文件的本地更改。我希望这有帮助!

答案 2 :(得分:17)

我不相信有一种方法可以忽略存储库中的文件。我们经常使用web.config和其他配置文件来解决这个问题。

虽然不完美,但我经常看到和使用的解决方案是使用.default文件和创建本地副本的非任务。

例如,在repo中有一个名为web.config.default的文件,它具有默认值。然后创建一个nant任务,将所有web.config.default文件重命名为web.config,然后可以将其自定义为本地值。检索新的工作副本或运行构建时,应调用此任务。

您还需要忽略创建的web.config文件,以便它不会提交到存储库。

答案 3 :(得分:8)

查看changelists,它可以为您提供筛选出已更改但不想提交的文件的选项。 SVN不会自动跳过文件,除非你告诉它 - 以及你告诉它该文件与其他文件有某种不同的方式是将它放在更改列表中。

它确实需要你做更多的工作,你只能将更改列表应用到你的工作副本(显然,如果你可以将'永不更新'属性应用于修订版,可以想象可能发生的混乱!)。

答案 4 :(得分:4)

我来到这个线程寻找一种方法来对一些文件进行“原子”提交,而不是在提交时忽略一些文件我走了另一条路,只提交了我想要的文件:

svn ci filename1 filename2

也许,它会帮助别人。

答案 5 :(得分:3)

伙计我刚刚找到了解决方案。鉴于TortoiseSVN以我们想要的方式工作,我尝试在Linux下安装它 - 这意味着,在Wine上运行。令人惊讶的是它有效!您所要做的就是:

  1. 通过运行以下命令添加要跳过提交的文件:“svn changelist'ignore-on-commit'”。
  2. 使用TortoiseSVN提交:“〜/ .wine / drive_c / Program \ Files / TortoiseSVN / bin / TortoiseProc.exe / command:commit / path:'
  3. 默认情况下,排除的文件将取消选中以进行提交,同时将检查其他已修改的文件。这与Windows下完全相同。享受!
  4. (需要通过CLI排除文件的原因是因为没有找到用于执行该操作的菜单条目,不确定原因。无论如何,这非常有用!)

答案 6 :(得分:2)

不允许提交冲突的文件。您可以利用此功能将私有更改保留在存储库之外。这适用于少量文件。

要解决a-file的冲突,您的工作副本(WC)没有来自存储库的最新a-file,并且您的WC中的a-file已更改与存储库中的更改位于相同的位置(您尚未更新的更改)。如果您不想等待上述条件,则可以为此a-file创建冲突:
在工作副本1(WC1)中,在a-file的顶部添加一行文字,例如“在此处发生冲突”。使用必要的语法,以便不破坏存储库。从WC1提交a-file。在WC2中,在a-file的顶部添加不同的文本行,例如“我想要冲突”。从WC2更新,现在a文件应该冲突。

答案 7 :(得分:1)

我会改为编写一个帮助器bash脚本,在你需要的所有文件上运行svn commit,而不是你不需要的文件。这样你就可以有更多的控制权。

例如,使用一行,您可以提交所有对其进行更改的扩展名.h.cpp的文件(并且不会导致冲突):

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

更改/添加[h|cpp]部分的扩展程序。如果需要,在-m ""的引号之间添加日志消息。

答案 8 :(得分:1)

一些提议的想法可以这样实现:

在PowerShell中的Windows上

将所有内容添加到默认列表.ps1

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

添加到忽略list.ps1

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

现在,您可以使用别名svn ci --changelist default,这样您就不必每次都指定它。另外一个好处是您可以在存储库中存储ignore-on-commit列表(如果需要)。

我为一些不断重新生成但很少实际手动更改的文件执行此操作。例如,我在特定占位符的配置文件中添加了修订号,因此每次提交时都会更改文件,但手动更改很少。

答案 9 :(得分:1)

我厌倦了等待内置到SVN中。我正在使用带有ignore-on-commit的tortoiseSVN,但会弹出一个用户对话框,你无法从命令行中取消,当我运行我的构建脚本并去喝杯茶时,我讨厌它我回过头来发现它正在等待10%的用户输入。

所以这里是一个windows powershell脚本,它只提交不在更改列表中的文件:

# 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

答案 10 :(得分:1)

更新user88044的脚本。

这个想法是推送do-not-commit更改列表中的文件并运行恶意脚本。

该脚本从命令中提取do-not-commit文件:svn status --changelist'do-not-commit'

  

#! /斌/庆典      DIR = “$(PWD)”

     

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

     $ $ IGNORE_FILES中的

;做mv $ DIR / $ i $ DIR /“$ i”_;完成的;

     

svn“$ @”;

     $ $ IGNORE_FILES中的

;做mv $ DIR /“$ i”_ $ DIR / $ i;完成的;

脚本放在/ usr / bin / svnn(sudo chmod + x / usr / bin / svnn)

svnn status,svnn commit等...

答案 11 :(得分:1)

您可以直接使用TortoiseSVN配置“ignore-on-commit”更改列表。 无需配置任何其他更改列表,包括所有其他文件

1)点击“SVN Commit ...”(我们不会提交,只是找到更改列表的图形菜单的方法) 2)在列表中右键单击要排除的文件。 3)菜单:移至更改列表>忽略上提交

下次执行SVN提交时...文件将在列表末尾的“提交时忽略”下显示为未选中。

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

答案 12 :(得分:1)

这是游戏的后期,但我找到了最令人敬畏的命令行命令来解决这个问题。使用bash完成。享受。

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

好的,所以这里是对命令的解释。有些事情需要根据您的使用情况进行更改。

svn status

我得到了所有文件的列表。他们都会从那些状态字符(?,!,A等)开始。每个都有自己的路线

grep -v excluding

我使用grep来过滤列表。它可以正常使用(包括)或使用-v标志(排除)。在这种情况下,它被用来排除短语"排除"将被排除在外。

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

现在我删除每行开头的状态字符和空格,然后使用sed引用每一行。我的一些文件名中有空格,因此引用。

tr '\n' ' '

使用tr,我用空格替换所有换行符。现在我要提交的整个文件列表都在一行上。

xargs svn commit -m "My Message"

最后,我使用xargs执行带有消息的commit命令。它执行提交,并将我引用的文件列表作为最后一个参数。

结果是一切最终都按照我想要的方式运作。我仍然讨厌强迫我跳过这些该死的箍,但我能忍受这个。我想。

答案 13 :(得分:0)

当我面对同样的问题时,我的谷歌搜索一直没有给我任何东西,我想我找到了一个解决方法。这就是我所做的,它似乎对我有用,但因为我坚持使用旧版本的SVN(< 1.5,因为它没有--keep-local选项)而且我不是专家它,我不能确定它是一个通用的解决方案。如果它也适合你,请告诉我!

我正在处理从SVN获得的Prestashop安装,因为其他人已经开始研究它了。由于数据库设置是为另一台服务器完成的,我在/ config文件夹中的某个文件中更改了它们。由于此文件夹已经过版本化,因此在svn:ignore中设置它不会阻止我对其进行本地修改。这是我做的:

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)

现在我可以运行svn add --force。在repo root上没有添加我的配置,即使它与repo的版本不匹配(我想如果我再次修改它,我将不得不再次完成所有这些,没有测试)。我也可以更新svn,而不会覆盖我的文件或收到任何错误。

答案 14 :(得分:0)

如果您使用的是Linux,则以下答案将非常有用

第1步在工作副本的根目录级别创建.svnignore文件,并在每个新行(例如下面)中添加文件夹/文件

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

注意:您还需要添加\.,因为它指向根目录

提示:要获取确切的文件夹/文件路径,请运行svn st -u,然后将相同的路径复制并粘贴到.svnignore文件中

步骤2 ,运行以下命令以提交.svnignore文件中除文件夹/文件之外的所有内容

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

命令说明

╔════════════════════╦════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ 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 ║
╚════════════════════╩════════════════════════════════════════════════════════════════════════════════════════════════════════╝

答案 15 :(得分:0)

不会忽略目录属性更改的解决方案

我尝试使用基于changelist的解决方案,但我遇到了一些问题。首先,我的存储库有数千个文件,因此要提交的更改列表很大,我的svn status输出变得太长,需要解析才有用。最重要的是我想提交来自合并的更改,这意味着它们包含属性更改。提交更改列表时,附加到目录的svn属性未提交,因此我不得不进行额外提交:

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

您可能必须为多个目录执行此操作(此处我记录DIR和当前目录.的属性),基本上是第二列中具有M的属性发出svn status命令。

<强>解决方案

我使用了补丁和svn patch。在伪代码中:

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

与其他海报一样,我最终使用脚本来维护要忽略的文件列表:

#! /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 "$@"

我通常将其与cirevert -R .一起使用。

答案 16 :(得分:-1)

svn:ignore is your answer.

示例:

$ svn propset svn:ignore -F .cvsignore .
property 'svn:ignore' set on '.'

答案 17 :(得分:-9)

svn propset "svn:ignore" "*.xml" .

*.xml是要忽略的文件模式; 你也可以在这里使用目录名称。