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 }