【问题标题】:Why does subversion switch to the parent directory when doing a commit为什么subversion在提交时会切换到父目录
【发布时间】:2012-03-08 06:48:49
【问题描述】:

当我从 unix 命令行执行 svn 提交时,它会在打开编辑器之前切换到父目录。当我进行 shell 转义时,这会引起很大的混乱,因为我不在我认为的位置。

这种行为的原因是什么?

(编辑)下面的屏幕截图显示这发生在最低目录中,而不发生在最顶层目录中

svn --version svn, version 1.5.5 (r34862)

test: svn checkout file:///export/home/svn/xxx/a
A    a/b
A    a/b/c
A    a/b/c/new
Checked out revision 8882.

test: cd a/b/c
test: pwd
/home/geretz/test/a/b/c
test: echo changed > new
test: svn commit

--This line, and those below, will be ignored--

M    c/new
~
~
:!pwd
/home/geretz/test/a/b

Hit ENTER or type command to continue

中止编辑会话,尝试从顶级目录提交

test: pwd
/home/geretz/test/a/b/c
test: cd ../..
test: pwd
/home/geretz/test/a
test: svn commit

--This line, and those below, will be ignored--

M    b/c/new
~
~
:!pwd
/home/geretz/test/a

Hit ENTER or type command to continue

【问题讨论】:

  • svn --version svn,版本 1.5.5 (r34862)
  • 它是切换到直接父级还是工作副本的根?如果是后者,我敢打赌你可以弄清楚为什么......
  • 但是如果它上面的目录不在svn控制下它会停留在当前目录中
  • 你是直接使用svn还是通过shell脚本?在 unix 上调用原生 svn 客户端?
  • 您是否会包含您正在运行的命令,包括目录结构的概要以及打开时编辑器缓冲区的近似值?

标签: svn shell directory


【解决方案1】:

如果你浏览svn源码,你会发现svn commit是由http://svn.apache.org/repos/asf/subversion/branches/1.5.x/subversion/svn/commit-cmd.c中的svn_cl__commit函数处理的。负责将路径拆分为“basename”和“dirname”的实际函数是svn_wc_get_actual_target。此函数在http://svn.apache.org/repos/asf/subversion/branches/1.5.x/subversion/include/svn_wc.h 中声明,并有以下注释:

/** Conditionally split @a path into an @a anchor and @a target for the
 * purpose of updating and committing.
 *
 * @a anchor is the directory at which the update or commit editor
 * should be rooted.
 *
 * @a target is the actual subject (relative to the @a anchor) of the
 * update/commit, or "" if the @a anchor itself is the subject.
 *
 * Allocate @a anchor and @a target in @a pool.
 */

最后在http://svn.apache.org/repos/asf/subversion/branches/1.5.x/subversion/libsvn_wc/update_editor.c 文件中,我们可以看到以下评论:

Updates are accomplished by driving an editor, and an editor is
"rooted" on a directory.  So, in order to update a file, we need to
break off the basename of the file, rooting the editor in that
file's parent directory, and then updating only that file, not the
other stuff in its parent directory.

Secondly, we look at the case where we wish to update a directory.
This is typically trivial.  However, one problematic case, exists
when we wish to update a directory that has been removed from the
repository and replaced with a file of the same name.  If we root
our edit at the initial directory, there is no editor mechanism for
deleting that directory and replacing it with a file (this would be
like having an editor now anchored on a file, which is disallowed).

All that remains is to have a function with the knowledge required
to properly decide where to root our editor, and what to act upon
with that now-rooted editor.  Given a path to be updated, this
function should conditionally split that path into an "anchor" and
a "target", where the "anchor" is the directory at which the update
editor is rooted (meaning, editor->open_root() is called with
this directory in mind), and the "target" is the actual intended
subject of the update.

svn_wc_get_actual_target() is that function.

...

As it turns out, commits need to have a similar check in place,
too, specifically for the case where a single directory is being
committed (we have to anchor at that directory's parent in case the
directory itself needs to be modified)

【讨论】:

  • 如果您在编写消息时需要一个可预测的工作目录,看起来最好的办法是创建您的提交消息并将其保存到文件之前你这样做提交,然后通过svn commit --file commit_log.txt 提交以使用它。无论如何,这基本上是幕后发生的事情,只有文件是临时的,并且在提交完成后会自动删除。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-03
  • 2019-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-09
  • 2012-08-12
相关资源
最近更新 更多