1
0
mirror of https://github.com/vitalif/viewvc-4intranet synced 2019-04-16 04:14:59 +03:00

Compare commits

...

38 Commits

Author SHA1 Message Date
cmpilato
030d381b88 Tag the 1.1.13 final release.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/tags/1.1.13@2725 8cb11bc2-c004-0410-86c3-e597b4017df7
2012-01-23 18:45:03 +00:00
cmpilato
22d1e72c66 Let's shoot for a 1.1.13 release today, shall we?
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2724 8cb11bc2-c004-0410-86c3-e597b4017df7
2012-01-23 18:44:16 +00:00
cmpilato
0e7d4061ed Bump copyright years.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2723 8cb11bc2-c004-0410-86c3-e597b4017df7
2012-01-23 18:40:36 +00:00
cmpilato
56dd2dcf28 Bump copyright years. (Merged /trunk:r2716)
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2717 8cb11bc2-c004-0410-86c3-e597b4017df7
2012-01-23 16:42:49 +00:00
cmpilato
5932f24a68 Merge from trunk r2713 (disallowing relative rootpaths) and r2714
(fixing -- no, really fixing this time -- path-to-url calculation for
annotations on Windows).

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2715 8cb11bc2-c004-0410-86c3-e597b4017df7
2012-01-06 22:01:36 +00:00
cmpilato
161421a20f Merge from trunk r2709.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2710 8cb11bc2-c004-0410-86c3-e597b4017df7
2012-01-03 20:08:39 +00:00
cmpilato
2a297c5361 Merge from trunk r2707, which at some point in time carried a log
message that read like so:

   * lib/vclib/svn/svn_repos.py
     (_rootpath2url): Try a different approach that should actually
       handle spaces in the "in-repos" path, too, and maybe (if I'm super
       lucky) also work on Windows.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2708 8cb11bc2-c004-0410-86c3-e597b4017df7
2012-01-03 15:22:31 +00:00
cmpilato
f43117b10f Merge from trunk r2702, whose log message read like so:
* lib/viewvc.py
     (): Stop importing the pygments stuff at the module-global scope,
       and go back to doing so...
     (markup_stream): ...here.
     (markup_or_annotate): No longer consider access to Pygments when
       making the first pass at colorizing -- if we don't have it,
       markup_stream() will fail quickly and we can take the second
       (non-colorizing) pass.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2703 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-12-12 20:07:58 +00:00
cmpilato
a025237f7e Tweak CHANGES line in light of r2700.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2701 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-12-06 14:50:02 +00:00
cmpilato
228db2fadb Merge from trunk r2679 and r2699, which is the reintroduction of the
issue #495 ("Syntax highlight/colorize scripts without extensions")
feature, plus a fix to help the prefer_markup flag get set more
accurately for the markup and annotate views.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2700 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-12-06 14:48:17 +00:00
cmpilato
0cd26cc79f Merge from trunk r2688, whose log message read like so:
* lib/viewvc.py
     (markup_or_annotate): Don't show annotation warnings for markup
       views of images.

Also:

* CHANGES
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2689 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-12-02 18:36:32 +00:00
cmpilato
b808d5d1e8 Merge from trunk r2686.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2687 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-12-02 18:30:31 +00:00
cmpilato
f843c054b7 Merge from trunk r2684, whose log message read like so:
Revert r2657, r2680, and r2681, effectively removing support for
   Pygments' lexer guessing functionality (closing the REOPENED bug issue
   #501, and necessitating that feature issue #495 be itself REOPENED).

Also:

* CHANGES
  Note that at this point, the lexer guessing stuff added in 1.1.12 has
  been effectively removed.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2685 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-12-02 17:55:43 +00:00
cmpilato
cf06a971e8 Merge from trunk r2680 and r2681, whose combined log message might
read something like this:

   * lib/viewvc.py
     (markup_stream_pygments): Rework the Pygments lexer-choosing logic a
       bit.  First, don't try any of it when syntax highlighting is
       disabled.  Secondly, don't guess at a lexer if we know the file's
       MIME type isn't text-y and have already failed to get a matching lexer.

Also:

* CHANGES
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2682 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-11-29 15:40:59 +00:00
cmpilato
bc8f3bdd4f Merge from trunk r2674, whose log message read like so:
Fix annotate views of files in Subversion repository whose paths
   contain non-URI-safe characters (spaces, non-ASCII stuff, etc.)
   
   * lib/vclib/svn/svn_repos.py
     (_rootpath2url): Use urllib.pathname2url to URL-encode the path
       portion of the URL we are building.

Also:

* CHANGES
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2675 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-11-14 21:34:14 +00:00
cmpilato
a6fcab67b0 Merge from trunk r2671, whose log message went a little something like this:
Fix issue #499 ("svndbadmin fails on deleted files").
   
   * bin/svndbadmin
     (SvnRev.__init__): Update the logic used to calculate change types
       and diff objects to no longer assume that deleted paths have None
       for their change.path.  (Subversion's 1.7 bindings always populate
       change.path.)

Also:

* CHANGES
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2672 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-11-14 20:16:01 +00:00
cmpilato
4069208316 Merge from trunk r2668 (a doc tweak).
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2669 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-11-03 14:44:33 +00:00
cmpilato
cfaa30b40f Begin a new release cycle.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2667 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-11-03 14:40:51 +00:00
cmpilato
97c5a82b7b Let's release 1.1.12 today.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2664 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-11-03 14:27:51 +00:00
cmpilato
21bd391d62 Document a missing template data item (patch_href).
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2663 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-11-03 14:22:25 +00:00
cmpilato
9d1476ef1d Merge from trunk r2657, whose log message read like so:
Finish issue #495 ("Syntax highlight/colorize scripts without
   extensions").
   
   * lib/viewvc.py
     (markup_stream_pygments): Failing all else, use the Pygments
       guess_lexer() function to guess a file's content type from the
       first line of its text.  (Most of this patch is compensation for
       the first that if this heuristic codepath is traversed, we've eaten
       a line of text from the file object that we don't expect to have
       been eaten.
   
   Patch by: Chris Mayo <cjmayo{__AT__}tigris.org>
             (Tweaked by me.)

Also:

* CHANGES:
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2658 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-10-31 21:42:38 +00:00
cmpilato
151fcd05e6 Merge from trunk r2653, which did the following:
Finish issue #470 ("No links to repository root logs").
   
   * lib/viewvc.py
     (view_roots): Generate a log_href -- the revision log for the root
       directory of the repository -- where it makes sense to do so.
   
   * templates/roots.ezt
     Markup the last-modified-revision as a link to the log view where
     we can.

   * docs/template-authoring-guide.html
     Note the additional data dictionary item.

Also:

* CHANGES
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2654 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-10-28 19:30:36 +00:00
cmpilato
22400ddcfb * docs/template-authoring-guide.html
Update <title> and <h1> to reflect that this document is for ViewVC
  1.1, not 1.0.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2636 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-10-21 14:02:23 +00:00
cmpilato
ae55530edc Record the change made in r2630.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2631 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-10-17 20:06:02 +00:00
cmpilato
112700a12c * lib/sapi.py
(WsgiServer.escape): Remove as unnecessary and, indeed, incorrect
    per issue #454.

Reported by: Ennio Zarlenga <wzzxo{__AT__}yahoo.fr>


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2630 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-10-17 20:04:07 +00:00
cmpilato
cecffecf39 Merge from trunk r2609 (fixed pointer to Subversion website).
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2610 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-10-04 15:00:01 +00:00
cmpilato
bdac8697fe Merge from trunk r2599:
Loop until receiving a definitive answer to the interactive overwrite
   query, rather than croaking on an empty response.
   
   * viewvc-install
     (install_file): If raw_input() return an empty string, re-ask the
       question.
   
   Patch by: Alexey Neyman <stilor@att.net>


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2600 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-09-30 19:11:27 +00:00
cmpilato
3d9404b67d Merge from trunk r2597, whose log message read like so:
Fix issue #494 ("allow override config from in mod_python").  This
   commit allows environmental overrides to trump programmatically
   passed-in configuration paths.
   
   * INSTALL
     Mention the VIEWVC_CONF_PATHNAME override environment variable.
   
   * lib/viewvc.py
     (load_config): Document this function and the order in which it
       searches for a configuration path.  Use server.getenv() instead of
       os.environ.get() where we can so that environmental overrides work
       in mod_python.
   
   Patch by: Alon Bar-Lev <alon.barlev@gmail.com>
             (Tweaked by me.)

Also:

* CHANGES
  Note this change.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2598 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-09-30 15:50:31 +00:00
cmpilato
7c50f55153 Merge from trunk r2593:
* conf/viewvc.conf.dist
  Note the importance of the MIME type maps for syntax coloration, and
  point folks to the 'mime_types_files' option.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2594 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-09-14 17:54:10 +00:00
cmpilato
368e4dc360 Merge from trunk r2591, which added to viewvc.conf.dist descriptions
of the various optionally "allowed_views".


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2592 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-09-07 17:44:18 +00:00
cmpilato
964d8bb5f9 Merge from trunk r2588, whose log message went a little som'thin' like this:
* bin/svndbadmin
     Fix a minor buglet in the usage message.

   Reported by: Jean-Yves Avenard <jyavenard@gmail.com>


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2589 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-07-01 17:58:19 +00:00
cmpilato
846e8e46c5 Merge from trunk r2586, whose log message read like so:
(More) gracefully handle some errorful input conditions.
   
   * lib/vclib/svn/svn_ra.py
     (RemoteSubversionRepository._getrev): Re-raise all exceptions as
       InvalidRevision exceptions.
   
   * lib/vclib/svn/svn_repos.py
     (LocalSubversionRepository._getrev): Re-raise all exceptions as
       InvalidRevision exceptions.
   
   Found by:  Daniel Shahaf <d.s@daniel.shahaf.name>


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2587 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-06-23 15:25:59 +00:00
cmpilato
75c719bcde Merge from trunk r2405:
Finish issue #441: Allow "rNNN" formatting for Subversion revision
   specifiers.
   
   * lib/vclib/svn/svn_repos.py (LocalSubversionRepository._getrev),
   * lib/vclib/svn/svn_ra.py (RemoteSubversionRepository._getrev):
     Now accept revision strings that begin with 'r'.
   
   Patch by: Daniel Shahaf <d.s{__AT__}daniel.shahaf.name>
             (Tweaked by me.)
   
and r2584:

   Fix issue #488 ("Allow 'rrNNN' formatting for Subversion revision
   specifiers (with multiple 'r')").
   
   * lib/vclib/svn/svn_ra.py
     (RemoteSubversionRepository._getrev): Accept multiple leading 'r's
       in revision specifiers.
   
   * lib/vclib/svn/svn_repos.py
     (LocalSubversionRepository._getrev): Accept multiple leading 'r's
       in revision specifiers.
   
   Patch by:  Daniel Shahaf <d.s@daniel.shahaf.name>

Also:

* CHANGES
  Note this change.

git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2585 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-06-23 15:14:57 +00:00
cmpilato
fc8793bf15 Merge from trunk r2582 which contained only doc tweaks.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2583 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-06-14 13:31:35 +00:00
cmpilato
65935c40fd Merge from trunk r2580, whose log message read like so:
Fix issue #486 ("OperationError raised when trying to do a glob search").
   
   Add code to workaround the fact that in Python 2.6,
   fnmatch.translate() stopped returning strings that ended with '$'
   (which work fine as MySQL regular expressions) and started instead
   returning strings that ended with '\Z(?ms)' (which... don't).
   
   * lib/cvsdb.py
     (CheckinDatabase.SQLQueryListString): If the returned regexp ends
       with '\Z(?ms)', replace those characters with a single '$'

Also:

* CHANGES
  Note this change.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2581 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-06-06 20:05:27 +00:00
cmpilato
a30d0b44cc Merge from trunk r2577, whose log message read like so:
Fix issue #485 ("Patch view hiding path details").
   
   * lib/viewvc.py
     (diff_parse_headers): Add 'path1' and 'path2' parameters, and use
       those paths in the returned header lines.
     (view_patch, view_diff): Pass paths into diff_parse_headers() now.

Also:

* CHANGES
  Record this change.


git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2578 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-05-27 19:00:20 +00:00
cmpilato
fded8462d2 Add placeholder for 1.1.12 changes.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2576 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-05-17 12:50:37 +00:00
cmpilato
b1095ac763 Begin a new release cycle.
git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/1.1.x@2575 8cb11bc2-c004-0410-86c3-e597b4017df7
2011-05-17 12:38:54 +00:00
59 changed files with 436 additions and 208 deletions

19
CHANGES
View File

@@ -1,3 +1,20 @@
Version 1.1.13 (released 23-Jan-2012)
* fix svndbadmin failure on deleted paths under Subversion 1.7 (issue #499)
* fix annotation of files in svn roots with non-URI-safe paths
* fix stray annotation warning in markup display of images
* more gracefully handle attempts to display binary content (issue #501)
Version 1.1.12 (released 03-Nov-2011)
* fix path display in patch and certain diff views (issue #485)
* fix broken cvsdb glob searching (issue 486)
* allow svn revision specifiers to have leading r's (issue #441, #448)
* allow environmental override of configuration location (issue #494)
* fix exception HTML-escaping non-string data under WSGI (issue #454)
* add links to root logs from roots view (issue #470)
* use Pygments lexer-guessing functionality (issue #495)
Version 1.1.11 (released 17-May-2011)
* security fix: remove user-reachable override of cvsdb row limit
@@ -6,7 +23,7 @@ Version 1.1.11 (released 17-May-2011)
* fix stack trace when asked to checkout a directory (issue #478)
* improve memory usage and speed of revision log markup (issue #477)
* fix broken annotation view in CVS keyword-bearing files (issue #479)
* warn users when query results are incomplete (issue #443)
* warn users when query results are incomplete (issue #433)
* avoid parsing errors on RCS newphrases in the admin section (issue #483)
* make rlog parsing code more robust in certain error cases (issue #444)

55
INSTALL
View File

@@ -34,7 +34,7 @@ Congratulations on getting this far. :-)
(http://www.python.org/)
* Subversion, Version Control System, 1.3.1 or later
(binary installation and Python bindings)
(http://subversion.tigris.org/)
(http://subversion.apache.org/)
Optional:
@@ -176,7 +176,24 @@ APACHE CONFIGURATION
or /etc/local. Use the vendor documentation or the find utility if
in doubt.
2) Configure Apache to expose ViewVC to users at the URL of your choice.
2) Depending on how your Apache configuration is setup by default, you
might need to explicitly allow high-level access to the ViewVC
install location.
<Directory <VIEWVC_INSTALLATION_DIRECTORY>>
Order allow,deny
Allow from all
</Directory>
For example, if ViewVC is installed in /usr/local/viewvc-1.0 on
your system:
<Directory /usr/local/viewvc-1.0>
Order allow,deny
Allow from all
</Directory>
3) Configure Apache to expose ViewVC to users at the URL of your choice.
ViewVC provides several different ways to do this. Choose one of
the following methods:
@@ -187,13 +204,13 @@ APACHE CONFIGURATION
The ScriptAlias directive is very useful for pointing
directly to the viewvc.cgi script. Simply insert a line containing
ScriptAlias /viewvc <VIEWVC_INSTALLATION_DIRECTORY>/bin/cgi/viewvc.cgi
ScriptAlias /viewvc <VIEWVC_INSTALLATION_DIRECTORY>/bin/cgi/viewvc.cgi
into your httpd.conf file. Choose the location in httpd.conf where
also the other ScriptAlias lines reside. Some examples:
ScriptAlias /viewvc /usr/local/viewvc-1.0/bin/cgi/viewvc.cgi
ScriptAlias /query /usr/local/viewvc-1.0/bin/cgi/query.cgi
ScriptAlias /viewvc /usr/local/viewvc-1.0/bin/cgi/viewvc.cgi
ScriptAlias /query /usr/local/viewvc-1.0/bin/cgi/query.cgi
----------------------------------------
METHOD B: CGI mode in cgi-bin directory
@@ -201,6 +218,10 @@ APACHE CONFIGURATION
Copy the CGI scripts from
<VIEWVC_INSTALLATION_DIRECTORY>/bin/cgi/*.cgi
to the /cgi-bin/ directory configured in your httpd.conf file.
You can override configuration file location using:
SetEnv VIEWVC_CONF_PATHNAME /etc/viewvc.conf
------------------------------------------
METHOD C: CGI mode in ExecCGI'd directory
@@ -210,8 +231,8 @@ APACHE CONFIGURATION
to the directory of your choosing in the Document Root adding the following
Apache directives for the directory in httpd.conf or an .htaccess file:
Options +ExecCGI
AddHandler cgi-script .cgi
Options +ExecCGI
AddHandler cgi-script .cgi
Note: For this to work mod_cgi has to be loaded. And for the .htaccess file
to be effective, "AllowOverride All" or "AllowOverride Options FileInfo"
@@ -227,6 +248,10 @@ APACHE CONFIGURATION
In httpd.conf, make sure that "AllowOverride All" or at least
"AllowOverride FileInfo Options" are enabled for the directory
you copied the files to.
You can override configuration file location using:
SetEnv VIEWVC_CONF_PATHNAME /etc/viewvc.conf
Note: If you are using Mod_Python under Apache 1.3 the tarball generation
feature may not work because it uses multithreading. This works fine
@@ -278,13 +303,6 @@ APACHE CONFIGURATION
ScriptAlias /viewvc /usr/local/viewvc/bin/wsgi/viewvc.fcgi
ScriptAlias /query /usr/local/viewvc/bin/wsgi/query.fcgi
3) Restart Apache.
The commands to do this vary. "httpd -k restart" and "apache -k
restart" are two common variants. On RedHat Linux it is done using
the command "/sbin/service httpd restart" and on SuSE Linux it is
done with "rcapache restart". Other systems use "apachectl restart".
4) [Optional] Add access control.
In your httpd.conf you can control access to certain modules by
@@ -306,7 +324,14 @@ APACHE CONFIGURATION
http://<server_name>/viewvc/~checkout~/<module_name>
http://<server_name>/viewvc/<module_name>.tar.gz?view=tar
5) Optional: Protect your ViewVC instance from server-whacking webcrawlers.
5) Restart Apache.
The commands to do this vary. "httpd -k restart" and "apache -k
restart" are two common variants. On RedHat Linux it is done using
the command "/sbin/service httpd restart" and on SuSE Linux it is
done with "rcapache restart". Other systems use "apachectl restart".
6) Optional: Protect your ViewVC instance from server-whacking webcrawlers.
As ViewVC is a web-based application which each page containing various
links to other pages and views, you can expect your server's performance

View File

@@ -15,7 +15,7 @@
<blockquote>
<p><strong>Copyright &copy; 1999-2011 The ViewCVS Group. All rights
<p><strong>Copyright &copy; 1999-2012 The ViewCVS Group. All rights
reserved.</strong></p>
<p>By using ViewVC, you agree to the terms and conditions set forth
@@ -62,6 +62,7 @@
<li>March 18, 2009 &mdash; copyright years updated</li>
<li>March 29, 2010 &mdash; copyright years updated</li>
<li>February 18, 2011 &mdash; copyright years updated</li>
<li>January 23, 2012 &mdash; copyright years updated</li>
</ul>
</body>

View File

@@ -3,7 +3,7 @@
# -*-python-*-
#
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -3,7 +3,7 @@
# -*-python-*-
#
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2009 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 2004-2008 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2004-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2004-2007 James Henstridge
#
# By using this file, you agree to the terms and conditions set forth in
@@ -153,7 +153,7 @@ class SvnRev:
fsroot = self._get_root_for_rev(rev)
# find changes in the revision
editor = svn.repos.RevisionChangeCollector(repo.fs, rev)
editor = svn.repos.ChangeCollector(repo.fs, fsroot)
e_ptr, e_baton = svn.delta.make_editor(editor)
svn.repos.svn_repos_replay(fsroot, e_ptr, e_baton)
@@ -164,21 +164,33 @@ class SvnRev:
continue
# deal with the change types we handle
action = None
base_root = None
base_path = change.base_path
if change.base_path:
base_root = self._get_root_for_rev(change.base_rev)
if not change.path:
# figure out what kind of change this is, and get a diff
# object for it. note that prior to 1.4 Subversion's
# bindings didn't give us change.action, but that's okay
# because back then deleted paths always had a change.path
# of None.
if hasattr(change, 'action') \
and change.action == svn.repos.CHANGE_ACTION_DELETE:
action = 'remove'
elif not change.path:
action = 'remove'
elif change.added:
action = 'add'
else:
action = 'change'
diffobj = svn.fs.FileDiff(base_root and base_root or None,
base_root and change.base_path or None,
change.path and fsroot or None,
change.path and change.path or None)
if action == 'remove':
diffobj = svn.fs.FileDiff(base_root, base_path, None, None)
else:
diffobj = svn.fs.FileDiff(base_root, base_path,
fsroot, change.path)
diff_fp = diffobj.get_pipe()
plus, minus = _get_diff_counts(diff_fp)
self.changes.append((path, action, plus, minus))
@@ -288,7 +300,7 @@ def usage():
located at REPOS-PATH.
Usage: 1. %s [-v] rebuild REPOS-PATH
2. %s [-v] update REPOS-PATH [REV:[REV2]] [--force]
2. %s [-v] update REPOS-PATH [REV[:REV2]] [--force]
3. %s [-v] purge REPOS-PATH
1. Rebuild the commit database information for the repository located

View File

@@ -1,7 +1,7 @@
#!/usr/bin/python
# -*-python-*-
#
# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/python
# -*-python-*-
#
# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2009 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -86,8 +86,8 @@
## cvs_roots: Specifies each of the CVS roots on your system and
## assigns names to them. Each root should be given by a "name: path"
## value. Multiple roots should be separated by commas and can be
## placed on separate lines.
## value (where the path is an absolute filesystem path). Multiple roots
## should be separated by commas and can be placed on separate lines.
##
## Example:
## cvs_roots = cvsroot: /opt/cvs/repos1,
@@ -97,8 +97,13 @@
## svn_roots: Specifies each of the Subversion roots (repositories) on
## your system and assigns names to them. Each root should be given by
## a "name: path" value. Multiple roots should be separated by commas
## and can be placed on separate lines.
## a "name: path" value (where the path is an absolute filesystem path).
## Multiple roots should be separated by commas and can be placed on
## separate lines.
##
## NOTE: ViewVC offers *experimental* support for displaying remote
## Subversion repositories. Simply use the repository's URL instead
## of a local filesystem path when defining the root.
##
## Example:
## svn_roots = svnrepos: /opt/svn/,
@@ -109,7 +114,8 @@
## root_parents: Specifies a list of directories under which any
## number of repositories may reside. You can specify multiple root
## parents separated by commas or new lines, each of which is of the
## form "path: type" (where type is either "cvs" or "svn").
## form "path: type" (where the type is either "cvs" or "svn", and
## the path is an absolute filesystem path).
##
## Rather than force you to add a new entry to 'cvs_roots' or
## 'svn_roots' each time you create a new repository, ViewVC rewards
@@ -345,7 +351,43 @@
## allowed_views: List the ViewVC views which are enabled. Views not
## in this comma-delited list will not be served (or, will return an
## error on attempted access).
## Possible values: "annotate", "co", "diff", "markup", "roots", "tar"
##
## Valid items for this list include: "annotate", "co", "diff", "markup",
## "roots", "tar".
##
## ----------+---------------------------------------------------------
## VIEW | DESCRIPTION
## ----------+---------------------------------------------------------
## annotate | The 'annotate' view shows the contents of a single
## | revision of a versioned file in exactly the same way as
## | the markup view, but with additional line-by-line
## | change attribution (the revision number, author, etc.
## | the most recent edit to that line of text as of the
## | displayed version).
## ----------+---------------------------------------------------------
## co | The 'co' (aka "checkout" or "download") view isn't
## | really a branded view at all, but allows for direct
## | downloading of the contents of a single revision of a
## | versioned file.
## ----------+---------------------------------------------------------
## diff | The 'diff' view displays line-based differences between
## | two revisions of a versioned file in a variety of
## | different user-selectable formats.
## ----------+---------------------------------------------------------
## markup | The 'markup' view shows the contents of a single
## | revision of a versioned file, with syntax highlighting
## | where possible and enabled. It can also optionally
## | show change log information for that revision of the
## | file.
## ----------+---------------------------------------------------------
## roots | The 'roots' view is a simple listing of the various
## | repositories which ViewVC has been configured to serve
## | to users.
## ----------+---------------------------------------------------------
## tar | The 'tar' view isn't a branded view, but generates
## | a GNU Tar archive file containing a single versioned
## | directory and its contents (recursively).
## ----------+---------------------------------------------------------
##
#allowed_views = annotate, diff, markup, roots
@@ -603,7 +645,13 @@
#short_log_len = 80
## enable_syntax_coloration: Should we colorize known file content
## syntaxes? [Requires Pygments Python module]
## syntaxes?
##
## NOTE: This feature requires the Pygments Python module
## (http://pygments.org) and works only when ViewVC can determine the
## MIME content type of the file whose contents it wishes to colorize.
## Use the 'mime_types_files' configuration option to specify MIME
## type mapping files useful for making that determination.
##
#enable_syntax_coloration = 1

View File

@@ -1,6 +1,6 @@
<html>
<head>
<title>ViewVC 1.0 Template Authoring Guide</title>
<title>ViewVC 1.1 Template Authoring Guide</title>
<style>
body {
background-color: rgb(180,193,205);
@@ -38,13 +38,13 @@ td {
</head>
<body>
<h1>ViewVC 1.0 Template Authoring Guide</h1>
<h1>ViewVC 1.1 Template Authoring Guide</h1>
<div class="h2">
<h2 id="introduction">Introduction</h2>
<p>This document represents an (unfinished) attempt at providing
documentation for how to customize ViewVC 1.0-dev's HTML output via
instructions for how to customize ViewVC's HTML output via
modification of its templates.</p>
</div>
@@ -802,6 +802,11 @@ td {
<td>String</td>
<td>This is a URL for the markup view of the left file.</td>
</tr>
<tr class="varlevel1">
<td class="varname">patch_href</td>
<td>String</td>
<td>URL of the patch view for the file.</td>
</tr>
<tr class="varlevel1">
<td class="varname">raw_diff</td>
<td>String</td>
@@ -2178,6 +2183,12 @@ td {
<td>String</td>
<td>Log message of last modification to the root.</td>
</tr>
<tr class="varlevel2">
<td class="varname">roots.log_href</td>
<td>String</td>
<td>URL of log revision view for the top-most (root) directory of
the root (repository).</td>
</tr>
<tr class="varlevel2">
<td class="varname">roots.name</td>
<td>String</td>

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2009 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2000 Curt Hagenlocher <curt@hagenlocher.org>
#
# By using this file, you agree to the terms and conditions set forth in
@@ -74,7 +74,8 @@ class HTMLBlameSource:
self.path_parts = path_parts
self.diff_url = diff_url
self.include_url = include_url
self.annotation, self.revision = self.repos.annotate(path_parts, opt_rev)
self.annotation, self.revision = self.repos.annotate(path_parts, opt_rev,
True)
def __getitem__(self, idx):
item = self.annotation.__getitem__(idx)

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2007 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -352,9 +352,17 @@ class CheckinDatabase:
match = " LIKE "
elif query_entry.match == "glob":
match = " REGEXP "
# use fnmatch to translate the glob into a regexp
# Use fnmatch to translate the glob into a regular
# expression. Sadly, we have to account for the fact
# that in Python 2.6, fnmatch.translate() started
# sticking '\Z(?ms)' at the end of the regular
# expression instead of just '$', and doesn't prepend
# the '^'.
data = fnmatch.translate(data)
if data[0] != '^': data = '^' + data
if data[0] != '^':
data = '^' + data
if data[-7:] == '\Z(?ms)':
data = data[:-7] + '$'
elif query_entry.match == "regex":
match = " REGEXP "
elif query_entry.match == "notregex":

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2009 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -233,9 +233,6 @@ class WsgiServer(Server):
self.header(status='301 Moved')
self._wsgi_write('This document is located <a href="%s">here</a>.' % url)
def escape(self, s, quote = None):
return cgi.escape(s, quote)
def getenv(self, name, value=None):
return self._environ.get(name, value)

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 2006-2010 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2006-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 2006-2010 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2006-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 2008-2010 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2008-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 2006-2011 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2006-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -170,12 +170,19 @@ class Repository:
Return value is a python file object
"""
def annotate(self, path_parts, rev):
"""Return a list of annotate file content lines and a revision.
def annotate(self, path_parts, rev, include_text=False):
"""Return a list of Annotation object, sorted by their
"line_number" components, which describe the lines of given
version of a file.
The result is a list of Annotation objects, sorted by their
line_number components.
"""
The file path is specified as a list of components, relative to
the root of the repository. e.g. ["subdir1", "subdir2", "filename"]
rev is the revision of the item to return information about.
If include_text is true, populate the Annotation objects' "text"
members with the corresponding line of file content; otherwise,
leave that member set to None."""
def revinfo(self, rev):
"""Return information about a global revision

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -14,6 +14,7 @@ import os.path
def canonicalize_rootpath(rootpath):
assert os.path.isabs(rootpath)
return os.path.normpath(rootpath)
@@ -22,6 +23,7 @@ def expand_root_parent(parent_path):
# "CVSROOT/config" is added the set of returned roots. Or, if the
# PARENT_PATH itself contains a child "CVSROOT/config", then all its
# subdirectories are returned as roots.
assert os.path.isabs(parent_path)
roots = {}
subpaths = os.listdir(parent_path)
cvsroot = os.path.exists(os.path.join(parent_path, "CVSROOT", "config"))

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -332,13 +332,13 @@ class BinCVSRepository(BaseCVSRepository):
args = rcs_args
return popen.popen(cmd, args, mode, capture_err)
def annotate(self, path_parts, rev=None):
def annotate(self, path_parts, rev=None, include_text=False):
if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check
raise vclib.Error("Path '%s' is not a file."
% (string.join(path_parts, "/")))
from vclib.ccvs import blame
source = blame.BlameSource(self.rcsfile(path_parts, 1), rev)
source = blame.BlameSource(self.rcsfile(path_parts, 1), rev, include_text)
return source, source.revision
def revinfo(self, rev):

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*-python-*-
#
# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 2000 Curt Hagenlocher <curt@hagenlocher.org>
#
# By using this file, you agree to the terms and conditions set forth in
@@ -414,7 +414,7 @@ class CVSParser(rcsparse.Sink):
class BlameSource:
def __init__(self, rcs_file, opt_rev=None):
def __init__(self, rcs_file, opt_rev=None, include_text=False):
# Parse the CVS file
parser = CVSParser()
revision = parser.parse_cvs_file(rcs_file, opt_rev)
@@ -428,6 +428,7 @@ class BlameSource:
self.lines = lines
self.num_lines = count
self.parser = parser
self.include_text = include_text
# keep track of where we are during an iteration
self.idx = -1
@@ -447,6 +448,8 @@ class BlameSource:
line_number = idx + 1
author = self.parser.revision_author[rev]
thisline = self.lines[idx]
if not self.include_text:
thisline = None
### TODO: Put a real date in here.
item = vclib.Annotation(thisline, line_number, rev, prev_rev, author, None)
self.last = item

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -142,11 +142,11 @@ class CCVSRepository(BaseCVSRepository):
return vclib._diff_fp(temp1, temp2, info1, info2,
self.utilities.diff or 'diff', diff_args)
def annotate(self, path_parts, rev=None):
def annotate(self, path_parts, rev=None, include_text=False):
if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check
raise vclib.Error("Path '%s' is not a file."
% (string.join(path_parts, "/")))
source = blame.BlameSource(self.rcsfile(path_parts, 1), rev)
source = blame.BlameSource(self.rcsfile(path_parts, 1), rev, include_text)
return source, source.revision
def revinfo(self, rev):

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -38,6 +38,7 @@ def canonicalize_rootpath(rootpath):
return os.path.normpath(urllib.unquote(rootpath[7:]))
if re.search(_re_url, rootpath):
return rootpath.rstrip('/')
assert os.path.isabs(rootpath)
return os.path.normpath(rootpath)
@@ -48,6 +49,7 @@ def expand_root_parent(parent_path):
else:
# Any subdirectories of PARENT_PATH which themselves have a child
# "format" are returned as roots.
assert os.path.isabs(parent_path)
subpaths = os.listdir(parent_path)
for rootname in subpaths:
rootpath = os.path.join(parent_path, rootname)

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -338,7 +338,7 @@ class RemoteSubversionRepository(vclib.Repository):
_rev2optrev(rev), 0, self.ctx)
return pairs and pairs[0][1] or {}
def annotate(self, path_parts, rev):
def annotate(self, path_parts, rev, include_text=False):
path = self._getpath(path_parts)
if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check
raise vclib.Error("Path '%s' is not a file." % path)
@@ -352,12 +352,13 @@ class RemoteSubversionRepository(vclib.Repository):
prev_rev = None
if revision > 1:
prev_rev = revision - 1
blame_data.append(vclib.Annotation(line, line_no+1, revision, prev_rev,
if not include_text:
line = None
blame_data.append(vclib.Annotation(line, line_no + 1, revision, prev_rev,
author, None))
client.svn_client_blame(url, _rev2optrev(1), _rev2optrev(rev),
_blame_cb, self.ctx)
return blame_data, rev
def revinfo(self, rev):
@@ -407,8 +408,11 @@ class RemoteSubversionRepository(vclib.Repository):
if rev is None or rev == 'HEAD':
return self.youngest
try:
if type(rev) == type(''):
while rev[0] == 'r':
rev = rev[1:]
rev = int(rev)
except ValueError:
except:
raise vclib.InvalidRevision(rev)
if (rev < 0) or (rev > self.youngest):
raise vclib.InvalidRevision(rev)

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -22,6 +22,7 @@ import time
import tempfile
import popen
import re
import urllib
from svn import fs, repos, core, client, delta
@@ -108,11 +109,15 @@ def _rev2optrev(rev):
def _rootpath2url(rootpath, path):
rootpath = os.path.abspath(rootpath)
if rootpath and rootpath[0] != '/':
rootpath = '/' + rootpath
drive, rootpath = os.path.splitdrive(rootpath)
if os.sep != '/':
rootpath = string.replace(rootpath, os.sep, '/')
return 'file://' + string.join([rootpath, path], "/")
rootpath = urllib.quote(rootpath)
path = urllib.quote(path)
if drive:
return 'file:///' + drive + rootpath + '/' + path
else:
return 'file://' + rootpath + '/' + path
# Given a dictionary REVPROPS of revision properties, pull special
@@ -282,10 +287,11 @@ class FileContentsPipe:
class BlameSource:
def __init__(self, local_url, rev, first_rev, config_dir):
def __init__(self, local_url, rev, first_rev, include_text, config_dir):
self.idx = -1
self.first_rev = first_rev
self.blame_data = []
self.include_text = include_text
ctx = client.svn_client_create_context()
core.svn_config_ensure(config_dir)
@@ -306,6 +312,8 @@ class BlameSource:
prev_rev = None
if rev > self.first_rev:
prev_rev = rev - 1
if not self.include_text:
text = None
self.blame_data.append(vclib.Annotation(text, line_no + 1, rev,
prev_rev, author, None))
@@ -521,7 +529,7 @@ class LocalSubversionRepository(vclib.Repository):
fsroot = self._getroot(rev)
return fs.node_proplist(fsroot, path)
def annotate(self, path_parts, rev):
def annotate(self, path_parts, rev, include_text=False):
path = self._getpath(path_parts)
path_type = self.itemtype(path_parts, rev) # does auth-check
if path_type != vclib.FILE:
@@ -532,8 +540,8 @@ class LocalSubversionRepository(vclib.Repository):
{'svn_cross_copies': 1})
youngest_rev, youngest_path = history[0]
oldest_rev, oldest_path = history[-1]
source = BlameSource(_rootpath2url(self.rootpath, path),
youngest_rev, oldest_rev, self.config_dir)
source = BlameSource(_rootpath2url(self.rootpath, path), youngest_rev,
oldest_rev, include_text, self.config_dir)
return source, youngest_rev
def revinfo(self, rev):
@@ -809,8 +817,11 @@ class LocalSubversionRepository(vclib.Repository):
if rev is None or rev == 'HEAD':
return self.youngest
try:
if type(rev) == type(''):
while rev[0] == 'r':
rev = rev[1:]
rev = int(rev)
except ValueError:
except:
raise vclib.InvalidRevision(rev)
if (rev < 0) or (rev > self.youngest):
raise vclib.InvalidRevision(rev)

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -14,7 +14,7 @@
#
# -----------------------------------------------------------------------
__version__ = '1.1.11-dev'
__version__ = '1.1.13'
# this comes from our library; measure the startup time
import debug
@@ -1547,33 +1547,36 @@ def markup_escaped_urls(s):
return "<a href=\"%s\">%s</a>" % (unescaped_url, url)
return re.sub(_re_rewrite_escaped_url, _url_repl, s)
def markup_stream_pygments(request, cfg, blame_data, fp, filename,
mime_type, encoding):
# Determine if we should use Pygments to highlight our output.
# Reasons not to include a) being told not to by the configuration,
# b) not being able to import the Pygments modules, and c) Pygments
# not having a lexer for our file's format.
blame_source = []
if blame_data:
for i in blame_data:
i.text = sapi.escape(i.text)
i.diff_href = None
if i.prev_rev:
i.diff_href = request.get_url(view_func=view_diff,
params={'r1': i.prev_rev,
'r2': i.rev},
escape=1, partial=1)
blame_source.append(i)
blame_data = blame_source
lexer = None
use_pygments = cfg.options.enable_syntax_coloration
try:
def markup_stream(request, cfg, blame_data, file_lines, filename,
mime_type, encoding, colorize):
"""Return the contents of a versioned file as a list of
vclib.Annotation objects, each representing one line of the file's
contents. Use BLAME_DATA as the annotation information for the file
if provided. Use FILE_LINES as the lines of file content text
themselves. MIME_TYPE is the MIME content type of the file;
ENCODING is its character encoding. If COLORIZE is true, attempt to
apply syntax coloration to the file contents, and use the
HTML-marked-up results as the text in the return vclib.Annotation
objects."""
# Nothing to mark up? So be it.
if not file_lines:
return []
# Determine if we should (and can) use Pygments to highlight our
# output. Reasons not to include a) being told not to by the
# configuration, b) not being able to import the Pygments modules,
# and c) Pygments not having a lexer for our file's format.
pygments_lexer = None
if colorize:
from pygments import highlight
from pygments.formatters import HtmlFormatter
from pygments.lexers import ClassNotFound, \
get_lexer_by_name, \
get_lexer_for_mimetype, \
get_lexer_for_filename
get_lexer_for_filename, \
guess_lexer
if not encoding:
encoding = 'guess'
if cfg.options.detect_encoding:
@@ -1582,50 +1585,50 @@ def markup_stream_pygments(request, cfg, blame_data, fp, filename,
encoding = 'chardet'
except (SyntaxError, ImportError):
pass
try:
lexer = get_lexer_for_mimetype(mime_type,
encoding=encoding,
tabsize=cfg.options.tabsize,
stripnl=False)
except ClassNotFound:
try:
lexer = get_lexer_for_filename(filename,
encoding=encoding,
tabsize=cfg.options.tabsize,
stripnl=False)
except ClassNotFound:
use_pygments = 0
except ImportError:
use_pygments = 0
# If we aren't going to be highlighting anything, just return the
# BLAME_SOURCE. If there's no blame_source, we'll generate a fake
# one from the file contents we fetch with PATH and REV.
if not use_pygments:
if blame_source:
class BlameSourceTabsizeWrapper:
def __init__(self, blame_source, tabsize):
self.blame_source = blame_source
self.tabsize = cfg.options.tabsize
def __getitem__(self, idx):
item = self.blame_source.__getitem__(idx)
item.text = string.expandtabs(item.text, self.tabsize)
item.text = markup_escaped_urls(item.text)
return item
return BlameSourceTabsizeWrapper(blame_source, cfg.options.tabsize)
else:
lines = []
line_no = 0
while 1:
line = fp.readline()
if not line:
break
line_no = line_no + 1
line = sapi.escape(string.expandtabs(line, cfg.options.tabsize))
line = markup_escaped_urls(line)
item = vclib.Annotation(line, line_no, None, None, None, None)
item.diff_href = None
lines.append(item)
# First, see if there's a Pygments lexer associated with MIME_TYPE.
if mime_type:
try:
pygments_lexer = get_lexer_for_mimetype(mime_type,
encoding=encoding,
tabsize=cfg.options.tabsize,
stripnl=False)
except ClassNotFound:
pygments_lexer = None
# If we've no lexer thus far, try to find one based on the FILENAME.
if not pygments_lexer:
try:
pygments_lexer = get_lexer_for_filename(filename,
encoding=encoding,
tabsize=cfg.options.tabsize,
stripnl=False)
except ClassNotFound:
pygments_lexer = None
# Still no lexer? If we've reason to believe this is a text
# file, try to guess the lexer based on the file's content.
if not pygments_lexer and is_text(mime_type) and file_lines:
try:
pygments_lexer = guess_lexer(file_lines[0])
except ClassNotFound:
pygments_lexer = None
# If we aren't highlighting, just return an amalgamation of the
# BLAME_DATA (if any) and the FILE_LINES.
if not pygments_lexer:
lines = []
for i in range(len(file_lines)):
line = file_lines[i]
line = sapi.escape(string.expandtabs(line, cfg.options.tabsize))
line = markup_escaped_urls(line)
if blame_data:
blame_item = blame_data[i]
blame_item.text = line
else:
blame_item = vclib.Annotation(line, i + 1, None, None, None, None)
blame_item.diff_href = None
lines.append(blame_item)
return lines
# If we get here, we're highlighting something.
@@ -1649,8 +1652,9 @@ def markup_stream_pygments(request, cfg, blame_data, fp, filename,
item.diff_href = None
self.blame_data.append(item)
self.line_no = self.line_no + 1
ps = PygmentsSink(blame_source)
highlight(fp.read(), lexer,
ps = PygmentsSink(blame_data)
highlight(string.join(file_lines, ''), pygments_lexer,
HtmlFormatter(nowrap=True,
classprefix="pygments-",
encoding='utf-8'), ps)
@@ -1748,34 +1752,71 @@ def markup_or_annotate(request, is_annotate):
fp.close()
if check_freshness(request, None, revision, weak=1):
return
annotation = 'binary'
if is_annotate:
annotation = 'binary'
image_src_href = request.get_url(view_func=view_checkout,
params={'revision': rev}, escape=1)
# Not a viewable image.
else:
blame_source = None
blame_data = None
# If this was an annotation request, try to annotate this file.
# If something goes wrong, that's okay -- we'll gracefully revert
# to a plain markup display.
if is_annotate:
# Try to annotate this file, but don't croak if we fail.
try:
blame_source, revision = request.repos.annotate(path, rev)
annotation = 'annotated'
blame_source, revision = request.repos.annotate(path, rev, False)
if check_freshness(request, None, revision, weak=1):
return
# Create BLAME_DATA list from BLAME_SOURCE, adding diff_href
# items to each relevant "line".
blame_data = []
for item in blame_source:
item.diff_href = None
if item.prev_rev:
item.diff_href = request.get_url(view_func=view_diff,
params={'r1': item.prev_rev,
'r2': item.rev},
escape=1, partial=1)
blame_data.append(item)
annotation = 'annotated'
except vclib.NonTextualFileContents:
annotation = 'binary'
except:
annotation = 'error'
# Grab the file contents.
fp, revision = request.repos.openfile(path, rev, {'cvs_oldkeywords' : 1})
if check_freshness(request, None, revision, weak=1):
fp.close()
return
lines = markup_stream_pygments(request, cfg, blame_source, fp,
path[-1], mime_type, encoding)
file_lines = fp.readlines()
fp.close()
data = common_template_data(request, revision)
# Do we have a differing number of file content lines and
# annotation items? That's no good. Call it an error and don't
# bother attempting the annotation display.
if blame_data and (len(file_lines) != len(blame_data)):
annotation = 'error'
blame_data = None
# Try to markup the file contents/annotation. If we get an error
# and we were colorizing the stream, try once more without the
# colorization enabled.
colorize = cfg.options.enable_syntax_coloration
try:
lines = markup_stream(request, cfg, blame_data, file_lines,
path[-1], mime_type, encoding, colorize)
except:
if colorize:
lines = markup_stream(request, cfg, blame_data, file_lines,
path[-1], mime_type, encoding, False)
else:
raise debug.ViewVCException('Error displaying file contents',
'500 Internal Server Error')
data = common_template_data(request, revision, mime_type)
data.merge(ezt.TemplateData({
'mime_type' : mime_type,
'log' : None,
@@ -1922,20 +1963,27 @@ def view_roots(request):
rootnames = allroots.keys()
rootnames.sort(icmp)
for rootname in rootnames:
root_path, root_type, lastmod = allroots[rootname]
href = request.get_url(view_func=view_directory,
where='', pathtype=vclib.DIR,
params={'root': rootname}, escape=1)
lastmod = allroots[rootname][2]
if root_type == vclib.SVN:
log_href = request.get_url(view_func=view_log,
where='', pathtype=vclib.DIR,
params={'root': rootname}, escape=1)
else:
log_href = None
roots.append(_item(name=request.server.escape(rootname),
type=allroots[rootname][1],
path=allroots[rootname][0],
type=root_type,
path=root_path,
author=lastmod and lastmod.author or None,
ago=lastmod and lastmod.ago or None,
date=lastmod and lastmod.date or None,
log=lastmod and lastmod.log or None,
short_log=lastmod and lastmod.short_log or None,
rev=lastmod and lastmod.rev or None,
href=href))
href=href,
log_href=log_href))
data = common_template_data(request)
data.merge(ezt.TemplateData({
@@ -2986,7 +3034,8 @@ class DiffSource:
class DiffSequencingError(Exception):
pass
def diff_parse_headers(fp, diff_type, rev1, rev2, sym1=None, sym2=None):
def diff_parse_headers(fp, diff_type, path1, path2, rev1, rev2,
sym1=None, sym2=None):
date1 = date2 = log_rev1 = log_rev2 = flag = None
header_lines = []
@@ -3015,15 +3064,15 @@ def diff_parse_headers(fp, diff_type, rev1, rev2, sym1=None, sym2=None):
if match:
date1 = match.group(1)
log_rev1 = match.group(2)
if sym1:
line = line[:-1] + ' %s\n' % sym1
line = '%s%s\t%s\t%s%s\n' % (f1, path1, date1, log_rev1,
sym1 and ' ' + sym1 or '')
elif line[:len(f2)] == f2:
match = _re_extract_rev.match(line)
if match:
date2 = match.group(1)
log_rev2 = match.group(2)
if sym2:
line = line[:-1] + ' %s\n' % sym2
line = '%s%s\t%s\t%s%s\n' % (f2, path2, date2, log_rev2,
sym2 and ' ' + sym2 or '')
parsing = 0
elif line[:3] == 'Bin':
flag = _RCSDIFF_IS_BINARY
@@ -3151,8 +3200,11 @@ def view_patch(request):
raise debug.ViewVCException('Invalid path(s) or revision(s) passed '
'to diff', '400 Bad Request')
date1, date2, flag, headers = diff_parse_headers(fp, diff_type, rev1, rev2,
sym1, sym2)
path_left = _path_join(p1)
path_right = _path_join(p2)
date1, date2, flag, headers = diff_parse_headers(fp, diff_type,
path_left, path_right,
rev1, rev2, sym1, sym2)
server_fp = get_writeready_server_file(request, 'text/plain')
server_fp.write(headers)
@@ -3248,6 +3300,7 @@ def view_diff(request):
changes = []
if fp:
date1, date2, flag, headers = diff_parse_headers(fp, diff_type,
path_left, path_right,
rev1, rev2, sym1, sym2)
if human_readable:
if flag is not None:
@@ -4405,14 +4458,35 @@ def locate_root(cfg, rootname):
return None, None
def load_config(pathname=None, server=None):
"""Load the ViewVC configuration file. SERVER is the server object
that will be using this configuration. Consult the environment for
the variable VIEWVC_CONF_PATHNAME and VIEWCVS_CONF_PATHNAME (its
legacy name) and, if set, use its value as the path of the
configuration file; otherwise, use PATHNAME (if provided). Failing
all else, use a hardcoded default configuration path."""
debug.t_start('load-config')
if pathname is None:
pathname = (os.environ.get("VIEWVC_CONF_PATHNAME")
or os.environ.get("VIEWCVS_CONF_PATHNAME")
or os.path.join(os.path.dirname(os.path.dirname(__file__)),
"viewvc.conf"))
# See if the environment contains overrides to the configuration
# path. If we have a SERVER object, consult its environment; use
# the OS environment otherwise.
env_pathname = None
if server is not None:
env_pathname = (server.getenv("VIEWVC_CONF_PATHNAME")
or server.getenv("VIEWCVS_CONF_PATHNAME"))
else:
env_pathname = (os.environ.get("VIEWVC_CONF_PATHNAME")
or os.environ.get("VIEWCVS_CONF_PATHNAME"))
# Try to find the configuration pathname by searching these ordered
# locations: the environment, the passed-in PATHNAME, the hard-coded
# default.
pathname = (env_pathname
or pathname
or os.path.join(os.path.dirname(os.path.dirname(__file__)),
"viewvc.conf"))
# Load the configuration!
cfg = config.Config()
cfg.set_defaults()
cfg.load_config(pathname, server and server.getenv("HTTP_HOST"))

View File

@@ -1,6 +1,6 @@
# -*-python-*-
#
# Copyright (C) 1999-2007 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -113,3 +113,6 @@ numbers, and not literal):
18. Send to the announce@ list a message explaining all the cool new
features, and post similar announcements to other places interested
in this sort of stuff, such as Freshmeat (http://www.freshmeat.net).
19. Merge CHANGES for this release into the CHANGES file for newer
release lines.

View File

@@ -27,7 +27,7 @@
[roots.name]</a>
</td>
[is cfg.options.show_roots_lastmod "1"]
<td style="width:20">&nbsp;[roots.rev]</td>
<td style="width:20">&nbsp;[if-any roots.log_href]<a href="[roots.log_href]">[roots.rev]</a>[else][roots.rev][end]</td>
<td style="width:20">&nbsp;[roots.ago]</td>
<td style="width:20">&nbsp;[roots.author]</td>
<td style="width:20">&nbsp;[roots.short_log]</td>

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (C) 1999-2007 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,5 +1,5 @@
/*
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,5 +1,5 @@
/*
# Copyright (C) 1999-2007 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,5 +1,5 @@
/*
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,5 +1,5 @@
/*
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- Mode: python -*-
#
# Copyright (C) 1999-2009 The ViewCVS Group. All Rights Reserved.
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
#
# By using this file, you agree to the terms and conditions set forth in
# the LICENSE.html file which can be found at the top level of the ViewVC
@@ -209,6 +209,8 @@ def install_file(src_path, dst_path, mode, subst_path_vars,
temp = raw_input("Do you want to [O]verwrite, [D]o "
"not overwrite, or [V]iew "
"differences? ")
if len(temp) == 0:
continue
temp = string.lower(temp[0])
if temp == "v" and ext not in BINARY_FILE_EXTS:
print """