选项--diff-cmd和--diff3-cmd的形式相似,也有类似名称的运行配置参数(见“配置”一节),这会导致一个错误的观念,也就是在Subversion中使用外置的比较(或“diff”)和合并工具会非常的容易,虽然Subversion可以使用大多数类似的工具,但是设置这些工具绝非易事。
The interface between Subversion and external diff and merge
tools harkens back to a time when Subversion's only contextual
differencing capabilities were built around invocations of the
GNU diffutils toolchain, specifically the
diff and diff3 utilities.
To get the kind of behavior Subversion needed, it called these
utilities with more than a handful of options and parameters,
most of which were quite specific to the utilities. Some time
later, Subversion grew its own internal differencing library,
and as a failover mechanism,
[48]
the --diff-cmd and --diff3-cmd
options were added to the Subversion command-line client so
users could more easily indicate that they preferred to use the
GNU diff and diff3 utilities instead of the newfangled internal
diff library. If those options were used, Subversion would
simply ignore the internal diff library, and fall back to
running those external programs, lengthy argument lists and all.
And that's where things remain today.
人们很快意识到使用简单的配置机制必须使Subversion使用位于特定位置的GNU diff和diff3工具,毕竟,Subversion并不验证其被告之要执行的程序是否是GNU的工具链的比较工具。唯一可以配置的方面是外置工具在系统的位置—而不是选项集,参数顺序等等。Subversion一直将这些GNU工具选项发给你的外置比较工具,而不管程序是否可以理解那些选项,那不是所有用户直觉的方式。
使用外置比较和合并工具的关键是使用包裹脚本将Subversion的输出转化为你的脚本程序可以理解的形式,然后将这些比较工具的输出转化为你的Subversion期望的格式—GNU工具可能使用的格式,下面的小节覆盖了那些期望格式的细节。
The decision on when to fire off a contextual diff or
merge as part of a larger Subversion operation is made
entirely by Subversion, and is affected by, among other
things, whether or not the files being operated on are
human-readable as determined by their
svn:mime-type property. This means, for
example, that even if you had the niftiest Microsoft
Word-aware differencing or merging tool in the Universe, it
would never be invoked by Subversion so long as your versioned
Word documents had a configured MIME type that denoted that
they were not human-readable (such as
application/msword). For more about MIME
type settings, see “文件内容类型”一节
Subversion calls external diff programs with parameters suitable for the GNU diff utility, and expects only that the external program return with a successful error code. For most alternative diff programs, only the sixth and seventh arguments—the paths of the files which represent the left and right sides of the diff, respectively—are of interest. Note that Subversion runs the diff program once per modified file covered by the Subversion operation, so if your program runs in an asynchronous fashion (or “backgrounded”), you might have several instances of it all running simultaneously. Finally, Subversion expects that your program return an error code of 1 if your program detected differences, or 0 if it did not—any other error code is considered a fatal error. [49]
例 7.2 “diffwrap.sh”和例 7.3 “diffwrap.bat”分别是Bourne shell和Windows批处理外置diff工具的包裹器模版。
例 7.2. diffwrap.sh
#!/bin/sh
# Configure your favorite diff program here.
DIFF="/usr/local/bin/my-diff-tool"
# Subversion provides the paths we need as the sixth and seventh
# parameters.
LEFT=${6}
RIGHT=${7}
# Call the diff command (change the following line to make sense for
# your merge program).
$DIFF --left $LEFT --right $RIGHT
# Return an errorcode of 0 if no differences were detected, 1 if some were.
# Any other errorcode will be treated as fatal.
例 7.3. diffwrap.bat
@ECHO OFF REM Configure your favorite diff program here. SET DIFF="C:\Program Files\Funky Stuff\My Diff Tool.exe" REM Subversion provides the paths we need as the sixth and seventh REM parameters. SET LEFT=%6 SET RIGHT=%7 REM Call the diff command (change the following line to make sense for REM your merge program). %DIFF% --left %LEFT% --right %RIGHT% REM Return an errorcode of 0 if no differences were detected, 1 if some were. REM Any other errorcode will be treated as fatal.
Subversion calls external merge programs with parameters suitable for the GNU diff3 utility, expecting that the external program return with a successful error code and that the full file contents which result from the completed merge operation are printed on the standard output stream (so that Subversion can redirect them into the appropriate version controlled file). For most alternative merge programs, only the ninth, tenth, and eleventh arguments, the paths of the files which represent the “mine”, “older”, and “yours” inputs, respectively, are of interest. Note that because Subversion depends on the output of your merge program, you wrapper script must not exit before that output has been delivered to Subversion. When it finally does exit, it should return an error code of 0 if the merge was successful, or 1 if unresolved conflicts remain in the output—any other error code is considered a fatal error.
例 7.4 “diff3wrap.sh”和例 7.5 “diff3wrap.bat”分别是Bourne shell和Windows批处理外置diff工具的包裹器模版。
例 7.4. diff3wrap.sh
#!/bin/sh
# Configure your favorite diff3/merge program here.
DIFF3="/usr/local/bin/my-merge-tool"
# Subversion provides the paths we need as the ninth, tenth, and eleventh
# parameters.
MINE=${9}
OLDER=${10}
YOURS=${11}
# Call the merge command (change the following line to make sense for
# your merge program).
$DIFF3 --older $OLDER --mine $MINE --yours $YOURS
# After performing the merge, this script needs to print the contents
# of the merged file to stdout. Do that in whatever way you see fit.
# Return an errorcode of 0 on successful merge, 1 if unresolved conflicts
# remain in the result. Any other errorcode will be treated as fatal.
例 7.5. diff3wrap.bat
@ECHO OFF REM Configure your favorite diff3/merge program here. SET DIFF3="C:\Program Files\Funky Stuff\My Merge Tool.exe" REM Subversion provides the paths we need as the ninth, tenth, and eleventh REM parameters. But we only have access to nine parameters at a time, so we REM shift our nine-parameter window twice to let us get to what we need. SHIFT SHIFT SET MINE=%7 SET OLDER=%8 SET YOURS=%9 REM Call the merge command (change the following line to make sense for REM your merge program). %DIFF3% --older %OLDER% --mine %MINE% --yours %YOURS% REM After performing the merge, this script needs to print the contents REM of the merged file to stdout. Do that in whatever way you see fit. REM Return an errorcode of 0 on successful merge, 1 if unresolved conflicts REM remain in the result. Any other errorcode will be treated as fatal.