SVN:有没有办法将文件标记为“不提交”?
Posted
技术标签:
【中文标题】SVN:有没有办法将文件标记为“不提交”?【英文标题】:SVN: Is there a way to mark a file as "do not commit"? 【发布时间】:2010-10-12 17:39:42 【问题描述】:使用 TortoiseSVN,我可以将文件移动到提交时忽略更改列表中,这样当我提交整棵树时,不会提交对该文件的更改。
有没有办法使用 svn 命令行工具来做类似的事情?
编辑:感谢使用 svn:ignore
的建议,但这并不完全符合我的要求。
svn:ignore
会影响svn add
和svn import
之类的东西。它提供了一个要忽略的文件名模式列表。
我有一个文件已经在源代码管理下,但我想对该文件进行临时更改,我不想在以后提交整个源代码树时提交这些更改。我正在做很多其他的更改,我可以在我的显示器上贴一个注释,告诉我在提交树之前恢复那个文件,但是如果 svn 可以自动跳过那个文件,那就太好了。
【问题讨论】:
有一种使用个人分支和切换状态的方法。 [请参阅我关于此主题的其他帖子。][1] [1]:***.com/questions/862950/… 【参考方案1】:截至 2016 年 2 月/版本 1.9,Subversion 没有内置的“不提交”/“提交时忽略”功能。这个答案是一个不理想的命令行解决方法
正如 OP 所述,TortoiseSVN 有一个内置的更改列表“ignore-on-commit”,它会自动从提交中排除。 命令行客户端没有此功能,因此您需要使用多个更改列表来完成相同的行为(带有警告):
一个你想提交的工作[工作] 你想忽略的事情[ignore-on-commit]由于 TortoiseSVN 有先例,我在示例中对我不想提交的文件使用“ignore-on-commit”。我将对我所做的文件使用“工作”,但您可以选择任何您想要的名称。
首先,将所有文件添加到名为“work”的更改列表中。这必须从工作副本的根目录运行:
svn cl work . -R
这会将工作副本中的所有文件递归地添加到名为“work”的更改列表中。这样做有一个缺点 - 当新文件添加到工作副本中时,您需要专门添加新文件,否则它们将不会被包含在内。其次,如果您必须再次运行此程序,则需要再次重新添加所有“ignore-on-commit”文件。不理想 - 您可以像其他人一样开始在文件中维护自己的“忽略”列表。
然后,对于要排除的文件:
svn cl ignore-on-commit path\to\file-to-ignore
因为文件只能在一个更改列表中,所以在您之前的“工作”添加之后运行此添加将从“工作”更改列表中删除您想要忽略的文件并将其放入“忽略提交”更改列表中。
当您准备好提交您希望提交的修改文件时,您只需将“--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 中存在一个长期存在的问题,以防将来发生变化。
【讨论】:
我已经使用您提到的命令添加了两个文件:$svn st --- Changelist 'ignore-on-commit': M database.php M config.php
,并且仍然在提交时将它们发送到存储库。知道我做错了什么吗?
将文件添加到更改列表“ignore-on-commit”本身并不会阻止文件被提交。 TortoiseSVN(一个 Windows GUI 客户端)内置了“ignore-on-commit”,但命令行 svn 没有。我在原始答案中的唯一建议是将要提交的文件添加到更改列表中,并告诉它提交
ignore-on-commit 绝对是一个 Tortoise 保留列表。它所做的只是阻止默认情况下在 GUI 中检查项目,因此它是 Tortoise GUI 特有的功能。如果您使用 GUI,您也不需要使用命令行添加到列表中。只是提交列表项上的上下文菜单,在底部您可以将它们移动到更改列表,并且已经定义了提交时忽略。 tortoisesvn.net/docs/release/TortoiseSVN_en/…
这不是杰克。它承诺了一切。
不工作,这个问题专门询问了命令行解决方案,而不是 GUI。【参考方案2】:
我也经常遇到这种情况:更改列表对我不起作用 - 我想列出我不想提交的文件的简短列表,而不是维护我确实想要提交的大量文件列表!
我在 linux 命令行上工作:所以我的解决方案是创建一个脚本 /usr/bin/svnn(是的,有两个 'n's!),如下所示:
#! /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”来运行颠覆,而不必担心检查 IGNORE_FILES 列表中文件的本地更改。我希望这有帮助!
【讨论】:
最后,这个答案其实是对的。你需要写一些工具。这实际上是不完美的,因为我想要一个动态选项,例如svnn ignore configs/*
- 带有通配符和花里胡哨。我想我自己写了类似的东西,然后回到这里!
这太棒了!更好的是,在 .bashrc 中为 svn -> svnn 创建一个别名。更好的是,它不是在命令中指定要忽略的文件,而是可以像 git 一样运行,它会检查文件夹中的 .ignore 文件并忽略与模式匹配的每个文件。
不必重新学习输入svnn
,而是考虑将其命名为svn
,并将此脚本放置在路径开头的位置,例如$HOME/bin
。然后从脚本本身调用/usr/bin/svn
。【参考方案3】:
我不相信有一种方法可以忽略存储库中的文件。我们经常在使用 web.config 和其他配置文件时遇到这种情况。
虽然不完美,但我最常看到和使用的解决方案是拥有 .default 文件和一个 nant 任务来创建本地副本。
例如,在 repo 中有一个名为 web.config.default
的文件,它具有默认值。然后创建一个 nant 任务,将所有 web.config.default
文件重命名为 web.config
,然后可以将其自定义为本地值。当检索到新的工作副本或运行构建时,应调用此任务。
您还需要忽略创建的 web.config
文件,以便它不会提交到存储库。
【讨论】:
【参考方案4】:查看changelists,它可以为您提供一个选项来过滤您已更改但不想提交的文件。 SVN 不会自动跳过一个文件,除非你告诉它——你告诉它这个文件与其他文件有某种不同的方式是把它放在一个更改列表中。
这确实需要您做更多的工作,并且您只能将更改列表应用到您的工作副本(显然,想象一下如果您可以将“从不更新”属性应用到修订版可能会出现混乱!)。
【讨论】:
但这正是我们想要的。比如一个源文件里面你需要设置一个defaultUserId = yourId,而不是系统默认的。【参考方案5】:我来到这个线程是为了寻找一种方法来对一些文件进行“原子”提交,而不是在提交时忽略一些文件,我采取了另一种方式,只提交了我想要的文件:
svn ci filename1 filename2
也许,它会帮助某人。
【讨论】:
您的回答只是此线程中的一个适当建议。svn ci
只是 svn commit
的别名。提交命令允许对指定文件进行特定提交【参考方案6】:
伙计们,我刚刚找到了解决方案。鉴于 TortoiseSVN 按我们想要的方式工作,我尝试在 Linux 下安装它——也就是说,在 Wine 上运行。令人惊讶的是它的工作原理!您所要做的就是:
-
通过运行添加要跳过提交的文件:“svn changelist 'ignore-on-commit'”。
使用 TortoiseSVN 提交:“~/.wine/drive_c/Program\ Files/TortoiseSVN/bin/TortoiseProc.exe /command:commit /path:'
默认情况下,排除的文件将被取消检查提交,而其他修改的文件将被检查。这与在 Windows 下完全相同。尽情享受吧!
(需要通过 CLI 排除文件的原因是因为找不到执行此操作的菜单项,不知道为什么。无论如何,这很好用!)
【讨论】:
【参考方案7】:不允许提交有冲突的文件。您可以利用这一点将您的私有更改保留在存储库之外。这最适用于少量文件。
要使 a-file
发生冲突,您的工作副本 (WC) 没有来自存储库的最新 a-file
,并且您的 WC 中的 a-file
具有与位于相同位置的更改存储库中的更改(您尚未更新到的更改)。如果您不想等待上述条件,您可以像这样为a-file
创建冲突:
在工作副本 1 (WC1) 中,在a-file
的顶部添加一行文本,例如“在此处产生冲突”。使用必要的语法,以免破坏存储库。从 WC1 提交 a-file
。在 WC2 中,在 a-file
的顶部添加不同的文本行,例如 “我想要冲突”。从 WC2 更新,现在 a-file 应该有冲突。
【讨论】:
【参考方案8】:我会改为编写一个辅助 bash 脚本,该脚本在您需要的所有文件上运行 svn commit
,而不是您不需要的文件。这样你就有了更多的控制权。
例如,通过一行,您可以提交所有扩展名为 .h
和 .cpp
的文件,您对其进行了更改(并且不会导致冲突):
svn commit -m "" `svn status | grep "^M.*[h|cpp]$" | awk 'print $2' | tr "\\n" " "`
更改/添加扩展名到 [h|cpp]
部分。如果需要,在 -m ""
的引号之间添加一条日志消息。
【讨论】:
【参考方案9】:一些提议的想法可以这样实现:
在 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
取别名,这样您就不必每次都指定它了。另一个好处是您可以将提交时忽略列表(如果需要)存储在存储库中。
我对一些不断重新生成但很少真正手动更改的文件执行此操作。例如,我将修订号添加到特定占位符的配置文件中,以便在每次提交时更改文件,但手动更改很少见。
【讨论】:
【参考方案10】:我厌倦了等待它被内置到 SVN 中。我正在使用带有忽略提交的 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
【讨论】:
【参考方案11】:更新 user88044 的脚本。
想法是将文件推送到不提交更改列表中并运行恶意脚本。
脚本从命令中提取不提交文件:svn status --changelist 'do-not-commit'
#! /bin/bash DIR="$(pwd)"
IGNORE_FILES="$(svn status --changelist 'do-not-commit' | tail -n +3 | grep -oE '[^ ]+$')"
对于 $IGNORE_FILES 中的 i;做 mv $DIR/$i $DIR/"$i"_;完成;
svn "$@";
对于 $IGNORE_FILES 中的 i;做 mv $DIR/"$i"_ $DIR/$i;完成;
脚本放在/usr/bin/svnn (sudo chmod +x /usr/bin/svnn)
svnn 状态、svnn 提交等...
【讨论】:
【参考方案12】:您可以直接使用 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
【讨论】:
你好,我刚看到 tjmoore 的 cmets,已经为 tortoiseSVN 用户提供了很好的信息...没有命令行tortoisesvn.net/docs/release/TortoiseSVN_en/… 这在 1.9 中被破坏了吗?【参考方案13】:这对游戏来说已经很晚了,但我找到了最棒的命令行命令来解决这个问题。使用 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 来执行带有消息的提交命令。它执行提交,并将我引用的文件列表作为最后一个参数删除。
结果是一切最终都按照我想要的方式进行。我仍然有点讨厌 svn 强迫我跳过这些该死的箍,但我可以忍受这个。我猜。
【讨论】:
【参考方案14】:由于我面临完全相同的问题,并且我的谷歌搜索一直没有给我任何信息,我想我找到了解决方法。这是我所做的,它似乎对我有用,但是由于我坚持使用旧版本的 SVN(
我正在处理从 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 根目录而不添加我的配置,即使它与 repo 的版本不匹配(我想如果我再修改一次,我将不得不再次经历这一切,没有测试)。我也可以进行 svn 更新,而不会覆盖我的文件或出现任何错误。
【讨论】:
【参考方案15】:不忽略目录属性更改的解决方案
我尝试使用基于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
和当前目录.
的属性),基本上是那些在发出svn status
命令时在第二列中有M
的目录.
解决方案
我使用了补丁和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 "$@"
我通常将它与ci
和revert -R .
一起使用。
【讨论】:
【参考方案16】:如果你在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 ║
╚════════════════════╩════════════════════════════════════════════════════════════════════════════════════════════════════════╝
【讨论】:
【参考方案17】:svn:ignore
is your answer.
例子:
$ svn propset svn:ignore -F .cvsignore .
property 'svn:ignore' set on '.'
【讨论】:
注意,上面的例子展示了如何使用之前配置的 cvsignore 文件作为 svnignore 属性的输入。 no svn:ignore 仅适用于 unversion 文件。不适用于版本文件 而且它也不是本地的。这是一个将自行提交的属性更改。【参考方案18】:svn propset "svn:ignore" "*.xml" .
*.xml
是要忽略的文件模式;
您也可以在此处使用目录名称。
【讨论】:
-1 因为您不能忽略存储库中的文件。以上是关于SVN:有没有办法将文件标记为“不提交”?的主要内容,如果未能解决你的问题,请参考以下文章