Performing 'svn blame file_url' with SVNKit

In this example we demonstrate how you may obtain per line information describing who is the author of that particular line in what revision. The example annotates a publicly readable file, so you can just copy-paste it and run. You will see the resultant output in your console.

   1 /*
   2  * ====================================================================
   3  * Copyright (c) 2004-2008 TMate Software Ltd.  All rights reserved.
   4  *
   5  * This software is licensed as described in the file COPYING, which
   6  * you should have received as part of this distribution.  The terms
   7  * are also available at http://svnkit.com/license.html.
   8  * If newer versions of this license are posted there, you may use a
   9  * newer version instead, at your option.
  10  * ====================================================================
  11  */
  12 package org.tmatesoft.svn.examples.wc;
  13 
  14 import java.io.File;
  15 import java.util.Date;
  16 
  17 import org.tmatesoft.svn.core.SVNException;
  18 import org.tmatesoft.svn.core.SVNURL;
  19 import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
  20 import org.tmatesoft.svn.core.internal.util.SVNDate;
  21 import org.tmatesoft.svn.core.internal.util.SVNFormatUtil;
  22 import org.tmatesoft.svn.core.wc.ISVNAnnotateHandler;
  23 import org.tmatesoft.svn.core.wc.ISVNOptions;
  24 import org.tmatesoft.svn.core.wc.SVNClientManager;
  25 import org.tmatesoft.svn.core.wc.SVNLogClient;
  26 import org.tmatesoft.svn.core.wc.SVNRevision;
  27 
  28 
  29 /**
  30  * @version 1.2.0
  31  * @author  TMate Software Ltd.
  32  */
  33 public class Annotations {
  34     
  35     public static void main (String[] args) {
  36         //1. first initialize the DAV protocol
  37         DAVRepositoryFactory.setup();
  38 
  39         try {
  40             //we will annotate a publicly available file
  41             SVNURL fileURL = SVNURL.parseURIEncoded("https://svn.svnkit.com/repos/svnkit/trunk/CHANGES.txt");
  42 
  43             //SVNLogClient is the class with which you can perform annotations 
  44             SVNLogClient logClient = SVNClientManager.newInstance().getLogClient();
  45             boolean ignoreMimeType = false;
  46             boolean includeMergedRevisions = false;
  47             
  48             logClient.doAnnotate(fileURL, SVNRevision.UNDEFINED, SVNRevision.create(1), SVNRevision.HEAD, 
  49                     ignoreMimeType /*not ignoring mime type*/, includeMergedRevisions /*not including merged revisions */, 
  50                     new AnnotationHandler(includeMergedRevisions, false/*use a short form of inline information*/, 
  51                             logClient.getOptions()), null);
  52         } catch (SVNException svne) {
  53             System.out.println(svne.getMessage());
  54             System.exit(1);
  55         }
  56     }
  57 
  58     private static class AnnotationHandler implements ISVNAnnotateHandler {
  59         private boolean myIsUseMergeHistory;
  60         private boolean myIsVerbose;
  61         private ISVNOptions myOptions;
  62         
  63         public AnnotationHandler(boolean useMergeHistory, boolean verbose, ISVNOptions options) {
  64             myIsUseMergeHistory = useMergeHistory;
  65             myIsVerbose = verbose;
  66             myOptions = options;
  67         }
  68         
  69         /**
  70          * Deprecated.
  71          */
  72         public void handleLine(Date date, long revision, String author, String line) throws SVNException {
  73             handleLine(date, revision, author, line, null, -1, null, null, 0);
  74         }
  75 
  76         /**
  77          * Formats per line information and prints it out to the console.
  78          */
  79         public void handleLine(Date date, long revision, String author, String line, Date mergedDate, 
  80                 long mergedRevision, String mergedAuthor, String mergedPath, int lineNumber) throws SVNException {
  81             
  82             String mergedStr = "";
  83             if(myIsUseMergeHistory) {
  84                 if (revision != mergedRevision) {
  85                     mergedStr = "G ";
  86                 } else {
  87                     mergedStr = "  ";
  88                 }
  89 
  90                 date = mergedDate;
  91                 revision = mergedRevision;
  92                 author = mergedAuthor;
  93             } 
  94                
  95             String revStr = revision >= 0 ? SVNFormatUtil.formatString(Long.toString(revision), 6, false) : "     -";
  96             String authorStr = author != null ? SVNFormatUtil.formatString(author, 10, false) : "         -";
  97             if (myIsVerbose) {
  98                 String dateStr = "                                           -"; 
  99                 if (date != null) {
 100                     dateStr = SVNDate.formatHumanDate(date, myOptions);
 101                 }
 102 
 103                 System.out.print(mergedStr + revStr + " " + authorStr + " " + dateStr + " ");
 104                 if (myIsUseMergeHistory && mergedPath != null) {
 105                     String pathStr = SVNFormatUtil.formatString(mergedPath, 14, true);
 106                     System.out.print(pathStr + " ");
 107                 }
 108                 System.out.println(line);
 109             } else {
 110                 System.out.println(mergedStr + revStr + " " + authorStr + " " + line);
 111             }
 112         }
 113 
 114         public boolean handleRevision(Date date, long revision, String author, File contents) throws SVNException {
 115             /* We do not want our file to be annotated for each revision of the range, but only for the last 
 116              * revision of it, so we return false  
 117              */
 118             return false;
 119         }
 120 
 121         public void handleEOF() {
 122         }
 123         
 124     }
 125 }

Annotating a file (last edited 2012-01-03 18:11:47 by ip-109-80-120-205)