Localization
Localization is the act of making programs behave in a region-specific way. When a program formats numbers or dates in a way specific to your part of the world, or prints messages (or accepts input) in your native language, the program is said to be localized. This section describes steps Subversion has made towards localization.
Understanding locales
Most modern operating systems have a notion of the «current locale»—that is, the region or country whose localization conventions are honored. These conventions—typically chosen by some runtime configuration mechanism on the computer—affect the way in which programs present data to the user, as well as the way in which they accept user input.
On Unix-like systems, you can check the values of the locale-related runtime configuration options by running the locale command:
$ locale
LANG=
LC_COLLATE="C"
LC_CTYPE="C"
LC_MESSAGES="C"
LC_MONETARY="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_ALL="C"
The output is a list of locale-related environment variables and their current values. In this example, the variables are all set to the default C locale, but users can set these variables to specific country/language code combinations. For example, if one were to set the LC_TIME variable to fr_CA, then programs would know to present time and date information formatted according a French-speaking Canadian's expectations. And if one were to set the LC_MESSAGES variable to zh_TW, then programs would know to present human-readable messages in Traditional Chinese. Setting the LC_ALL variable has the effect of changing every locale variable to the same value. The value of LANG is used as a default value for any locale variable that is unset. To see the list of available locales on a Unix system, run the command locale -a.
On Windows, locale configuration is done via the «Regional and Language Options» control panel item. There you can view and select the values of individual settings from the available locales, and even customize (at a sickening level of detail) several of the display formatting conventions.
Subversion's use of locales
The Subversion client, svn, honors the current locale configuration in two ways. First, it notices the value of the LC_MESSAGES variable and attempts to print all messages in the specified language. For example:
$ export LC_MESSAGES=de_DE
$ svn help cat
cat: Gibt den Inhalt der angegebenen Dateien oder URLs aus.
Aufruf: cat ZIEL[@REV]...
…
This behavior works identically on both Unix and Windows systems. Note, though, that while your operating system might have support for a certain locale, the Subversion client still may not be able to speak the particular language. In order to produce localized messages, human volunteers must provide translations for each language. The translations are written using the GNU gettext package, which results in translation modules that end with the .mo filename extension. For example, the German translation file is named de.mo. These translation files are installed somewhere on your system. On Unix, they typically live in /usr/share/locale/, while on Windows they're often found in the \share\locale\ folder in Subversion's installation area. Once installed, a module is named after the program it provides translations for. For example, the de.mo file may ultimately end up installed as /usr/share/locale/de/LC_MESSAGES/subversion.mo. By browsing the installed .mo files, you can see which languages the Subversion client is able to speak.
The second way in which the locale is honored involves how svn interprets your input. The repository stores all paths, filenames, and log messages in Unicode, encoded as UTF-8. In that sense, the repository is internationalized—that is, the repository is ready to accept input in any human language. This means, however, that the Subversion client is responsible for sending only UTF-8 filenames and log messages into the repository. In order to do this, it must convert the data from the native locale into UTF-8.
For example, suppose you create a file namedcaffè.txt, and then when committing the file, you write the log message as «Adesso il caffè è più forte». Both the filename and log message contain non-ASCII characters, but because your locale is set to it_IT, the Subversion client knows to interpret them as Italian. It uses an Italian character set to convert the data to UTF-8 before sending them off to the repository.
Note that while the repository demands UTF-8 filenames and log messages, it does not pay attention to file contents. Subversion treats file contents as opaque strings of bytes, and neither client nor server makes an attempt to understand the character set or encoding of the contents.
Character set conversion errors
While using Subversion, you might get hit with an error related to character set conversions:
svn: Can't convert string from native encoding to 'UTF-8':
…
svn: Can't convert string from 'UTF-8' to native encoding:
…
Errors like this typically occur when the Subversion client has received a UTF-8 string from the repository, but not all of the characters in that string can be represented using the encoding of the current locale. For example, if your locale is en_US but a collaborator has committed a Japanese filename, you're likely to see this error when you receive the file during an svn update.
The solution is either to set your locale to something which can represent the incoming UTF-8 data, or to change the filename or log message in the repository. (And don't forget to slap your collaborator's hand—projects should decide on common languages ahead of time, so that all participants are using the same locale.)
Using External Differencing Tools
The presence of --diff-cmd and --diff3-cmd options, and similarly named runtime configuration parameters (see «Config»), can lead to a false notion of how easy it is to use external differencing (or «diff») and merge tools with Subversion. While Subversion can use most of popular such tools available, the effort invested in setting this up often turns out to be non-trivial.
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, [45] 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.
It didn't take long for folks to realize that having such easy configuration mechanisms for specifying that Subversion should use the external GNU diff and diff3 utilities located at a particular place on the system could be applied toward the use of other diff and merge tools, too. After all, Subversion didn't actually verify that the things it was being told to run were members of the GNU diffutils toolchain. But the only configurable aspect of using those external tools is their location on the system—not the option set, parameter order, etc. Subversion continues throwing all those GNU utility options at your external diff tool regardless of whether or not that program can understand those options. And that's where things get unintuitive for most users.
The key to using external diff and merge tools (other than GNU diff and diff3, of course) with Subversion is to use wrapper scripts which convert the input from Subversion into something that your differencing tool can understand, and then to convert the output of your tool back into a format which Subversion expects—the format that the GNU tools would have used. The following sections cover the specifics of those expectations.
Замечание
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 «svn:mime-type»
External diff
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 program, 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 errorcode of 0 if your program detected differences, or 1 if it did not—any other errorcode is considered a fatal error. [46]
Пример 7.2, «diffwrap.sh» and Пример 7.3, «diffwrap.bat» are templates for external diff tool wrappers in the Bourne shell and Windows batch scripting languages, respectively.
Пример 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.
External diff3
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 errorcode of 0 if the merge was successful, or 1 if unresolved conflicts remain in the output—any other errorcode is considered a fatal error.
Пример 7.4, «diff3wrap.sh» and Пример 7.5, «diff3wrap.bat» are templates for external merge tool wrappers in the Bourne shell and Windows batch scripting languages, respectively.
Пример 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.
Достарыңызбен бөлісу: |