SVN Switch 不会删除工作中切换到标签或分支时不存在的文件夹/文件

发布于 2024-10-15 08:16:51 字数 211 浏览 2 评论 0原文

我需要根据标签或分支进行构建。因此,我已经自动化了我的构建过程,以便在他们要求构建时切换到标签或分支。我使用 svn switch 命令使工作副本指向主干工作副本的标记或分支。问题是:如果头修订中存在新添加的文件夹,它们不会从工作副本中删除。它们在工作副本中保持未版本化状态,但构建中的未版本化文件夹会导致很多问题。如何避免这个问题呢?使用 svn switch 命令时是否有任何选项可以避免未版本化的文件。

I have a requirement to make a build based on the tag or branch. So I have automated my build process to do switch to a tag or branch whenever they are asking for the Builds. Iam using svn switch command to make the working copy point to tag or branch from trunk working copy. The problem is: If there are newly added folders present in the head revision, they are not getting deleted from the working copy. They remain as unversioned in the working copy, but the unversioned folders in the build causing lot of problems. How to avoid this problem? Is there any option to avoid unversioned files while using svn switch command.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

勿忘初心 2024-10-22 08:16:51

没有错误,但您必须在切换之前确保工作区确实干净。如果它是干净的,则切换会删除/创建仅存在于一个版本中的文件和目录。为此,subversion 1.6 手册说:

“切换”一个没有本地修改的工作副本到不同的分支会导致工作副本看起来就像您重新签出目录一样。

我刚刚使用新创建的测试存储库对此进行了测试。另一方面,如果当前工作空间中有本地修改,svn 不会丢弃它们。 svn 在这方面相当保守。例如,我在 trunk 上创建了一个目录 dir 并提交了它。然后我创建了一个备份文件dir/file.~1~svn st 没有报告它,因为 *~ 在我的配置中被全局忽略。当我切换回分支时,svn 应该删除了 dir 但这会删除备份文件,所以 svn 没有这样做。它将目录保留为本地修改。

旁注:当再次切换到主干时,svn 报告错误,因为分支上的本地修改 dir 与主干上的版本控制 dir 冲突。 --force 解决了这个问题。

there's no bug but you have to make sure that the workspace is really clean before switching. If it is clean, switching deletes/creates files and dirs that are present in only one version. To this end the subversion 1.6 manual says:

“Switching” a working copy that has no local modifications to a different branch results in the working copy looking just as it would if you'd done a fresh checkout of the directory.

I just tested this with a newly created test repository. If on the other hand there are local modifications in the current workspace, svn won't discard them. svn is pretty conservative with this respect. E.g. I created a directory dir on trunk and committed it. Then I created a backup file dir/file.~1~. It wasn't reported by svn st because *~ is globally ignored with my config. When I switched back to a branch svn should have deleted dir but this would have deleted the backup file, so svn didn't do that. It kept the directory as a local modification.

side note: when switching forth to trunk again svn reported an error because dir as local modification on the branch was in conflict with the versioned dir on trunk. --force solved that problem.

≈。彩虹 2024-10-22 08:16:51

正如您所发现的,SVN 交换机不会删除未版本控制的文件。

我在构建过程(Cruise Control)中处理它的方式是在每次构建后始终删除整个工作文件夹。然后,当您的构建过程执行 SVN get 时,它将进入一个空目录,并且不会发生冲突。

顺便说一句,这就是为什么你应该使用单独的构建服务器 - 那么你就不会有未提交的开发工作干扰构建。

SVN switch wont delete unversioned files as you've found.

The way I handle it in my build process (Cruise Control) is to always delete the entire working folder after every build. Then when your build process does a SVN get, it will be into an empty directory and there will be no conflicts.

BTW this is why you should use a separate build server - then you wont have uncommitted dev work interfering with the build.

月牙弯弯 2024-10-22 08:16:51

事情按应有的方式进行,至少在 svn 1.6.11 及更高版本中是这样。然而,构建过程很可能会留下未经修订的文件。由于 SVNIGNORE 设置,这些在“svn status”上可能是透明的。当人们期望 svn 删除整个目录时,这可能会引起麻烦。

我做了一些测试 - 我设置了一个新的空存储库,在那里创建了一个主干和标签目录,在标记它的同时添加了一个和一个文件。 (下面的代码部分不包括 SVN 抛出的输出和错误,建议您将其复制到终端窗口中,看看是否可以复制该行为)。

mkdir /tmp/workdir/
cd /tmp/workdir
svnadmin create /tmp/foobar
svn checkout file:///tmp/foobar/
svn mkdir foobar/tags
svn mkdir foobar/trunk
cd foobar
svn commit -m "trunk and tags"
## NOTE: in svn 1.8 and higher, it's needed with a --ignore-ancestry option below
svn switch file:///tmp/foobar/trunk 

(在这里我们已经可以看到它正在做正确的事情 - 删除标签和 trunk 子目录)

touch file1
svn add file1
svn commit -m "added file1"
svn cp -m "file1 in tag1" . file:///tmp/foobar/tags/tag1

然后再次...

touch file2
svn add file2
svn commit -m "added file2"
svn cp -m "file2 in tag2" . file:///tmp/foobar/tags/tag2

让我们从 tag3 中显式删除 file1

svn rm file1 
svn commit -m "deleted file1"
svn cp -m "file1 removed from tag3" file:///tmp/foobar/trunk/ file:///tmp/foobar/tags/tag3/

...以及一个新目录......

svn mkdir dir1
touch dir1/file3
svn add dir1/file3
svn commit -m "added dir1/file3"
svn cp -m "dir1/file3 in tag4" file:///tmp/foobar/trunk file:///tmp/foobar/tags/tag4/

然后让我们在tag5中删除它……

svn rm dir1
svn commit -m "removed dir1/file3"
svn cp -m "dir1/file3 removed in tag5" file:///tmp/foobar/trunk file:///tmp/foobar/tags/tag5/

让我们检查一下切换是如何工作的……

svn switch file:///tmp/foobar/tags/tag1
svn switch file:///tmp/foobar/tags/tag2
svn switch file:///tmp/foobar/tags/tag3
svn switch file:///tmp/foobar/tags/tag4
svn switch file:///tmp/foobar/tags/tag5
svn switch file:///tmp/foobar/tags/tag4

没有任何问题。但是,假设我用 emacs 修改了 dir1/file3 - 它通常会创建一个备份文件:

touch dir1/file3~

由于默认的 SVNIGNORE 设置,这不会显示在“svn status”上......

svn status

但这足以破坏事情:

svn switch file:///tmp/foobar/tags/tag5
svn status
svn switch file:///tmp/foobar/tags/tag4

第一个命令表明dir1 已被删除,但由于文件未修订,该目录仍然存在。

不幸的是,“svn revert”不会删除未修订的文件...

svn revert -R .
svn switch file:///tmp/foobar/tags/tag5
svn status
svn switch file:///tmp/foobar/tags/tag4

“make clean”可能有效,也可能无效,具体取决于环境。当然可以编写一个脚本来删除它,即像这样:

rm -rf $(svn status --no-ignore | grep -E '^\?' | awk ' { print $2 ; }')
svn switch file:///tmp/foobar/tags/tag4

请注意,当遇到带有空格的文件名时,上面的命令可能会做坏事。

人们还可以通过使用“--force”来避免上面的一些错误消息:

touch dir1/file3~
svn switch --force file:///tmp/foobar/tags/tag5
svn switch --force file:///tmp/foobar/tags/tag4

请注意,mydir1/file3~永远不会被删除,但最后一个切换不会失败

Things works like they should, at least in svn 1.6.11 and higher. However, a build process is quite likely to leave behind unrevisioned files. Those may be transparent on "svn status" due to SVNIGNORE settings. This may cause troubles when one expects svn to remove the whole directory.

I did some testing - I set up a new and empty repository, made a trunk and tags directories there, added one and one file while tagging it. (the code sections below does not include the output and errors thrown by SVN, you're encouraged to copy it into a terminal window and see if you can duplicate the behaviour).

mkdir /tmp/workdir/
cd /tmp/workdir
svnadmin create /tmp/foobar
svn checkout file:///tmp/foobar/
svn mkdir foobar/tags
svn mkdir foobar/trunk
cd foobar
svn commit -m "trunk and tags"
## NOTE: in svn 1.8 and higher, it's needed with a --ignore-ancestry option below
svn switch file:///tmp/foobar/trunk 

(and here we can already see that it's doing the right thing - deleting the tags and trunk subdirectories)

touch file1
svn add file1
svn commit -m "added file1"
svn cp -m "file1 in tag1" . file:///tmp/foobar/tags/tag1

And then again ...

touch file2
svn add file2
svn commit -m "added file2"
svn cp -m "file2 in tag2" . file:///tmp/foobar/tags/tag2

Let's explicitly delete file1 from tag3

svn rm file1 
svn commit -m "deleted file1"
svn cp -m "file1 removed from tag3" file:///tmp/foobar/trunk/ file:///tmp/foobar/tags/tag3/

... and a new directory as well ...

svn mkdir dir1
touch dir1/file3
svn add dir1/file3
svn commit -m "added dir1/file3"
svn cp -m "dir1/file3 in tag4" file:///tmp/foobar/trunk file:///tmp/foobar/tags/tag4/

... and let's delete it in tag5 ...

svn rm dir1
svn commit -m "removed dir1/file3"
svn cp -m "dir1/file3 removed in tag5" file:///tmp/foobar/trunk file:///tmp/foobar/tags/tag5/

... and let's check how switching works ...

svn switch file:///tmp/foobar/tags/tag1
svn switch file:///tmp/foobar/tags/tag2
svn switch file:///tmp/foobar/tags/tag3
svn switch file:///tmp/foobar/tags/tag4
svn switch file:///tmp/foobar/tags/tag5
svn switch file:///tmp/foobar/tags/tag4

... no problems whatsoever. But, say that I modified dir1/file3 with emacs - it would typically make a backup file:

touch dir1/file3~

This doesn't show up on "svn status" due to default SVNIGNORE settings ...

svn status

But it's sufficient to break things:

svn switch file:///tmp/foobar/tags/tag5
svn status
svn switch file:///tmp/foobar/tags/tag4

The first command indicates that dir1 is deleted, but due to the unrevisioned file the directory gets standing.

"svn revert" unfortunately doesn't remove unrevisioned files ...

svn revert -R .
svn switch file:///tmp/foobar/tags/tag5
svn status
svn switch file:///tmp/foobar/tags/tag4

"make clean" may and may not work, depending on the environment. One could of course make a script to remove it, i.e. like this:

rm -rf $(svn status --no-ignore | grep -E '^\?' | awk ' { print $2 ; }')
svn switch file:///tmp/foobar/tags/tag4

Please note that the command above may do Bad Things when encountering file names with spaces.

One may also avoid some error messages above by using "--force":

touch dir1/file3~
svn switch --force file:///tmp/foobar/tags/tag5
svn switch --force file:///tmp/foobar/tags/tag4

Note that mydir1/file3~ never gets deleted, but that the last switch won't fail

会发光的星星闪亮亮i 2024-10-22 08:16:51

两年后……

经过一番修改并看到你的问题(桑迪),答案是,是的,Switch 应该删除该目录。我遇到了同样的问题并解决了这个问题。

需要明确的是,据我了解,问题是您将目录/文件夹添加到分支,然后切换回主干。切换回来时应删除此添加的文件夹。

我看到 Tortoise SVN 试图删除该文件夹,但没有错误,也没有实际删除该文件夹。事实证明存在某种权限问题。当我在中继上手动删除文件夹后,来回切换产生了预期的结果;该文件夹被删除。

Two years later...

After some tinkering around and seeing your question (Sandy) the answer is, yes, a Switch should delete the directory. I was having the same issue and figured this one out.

To be clear, the issue as I understand it is that you add a directory/folder to your branch, then switch back to the Trunk. This added folder should be deleted when switching back.

I saw that Tortoise SVN was trying to delete the folder but without error and without actually deleting the folder. Turns out there was some kind of permissions issue. Once I manually deleted the folder while on the Trunk, switching back and forth produced the expected results; the folder is deleted.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文