SVNKit學習——基於Repository的操作之print repository tree、file content、repository history(四)

来源:http://www.cnblogs.com/douJiangYouTiao888/archive/2016/12/06/6138660.html
-Advertisement-
Play Games

此篇文章同樣是參考SVNKit在wiki的官方文檔做的demo,每個類都可以單獨運行。具體的細節都寫到註釋里了~ 開發背景: SVNKit版本:1.7.14 附上官網下載鏈接:https://www.svnkit.com/org.tmatesoft.svn_1.7.14.standalone.zip ...


  此篇文章同樣是參考SVNKit在wiki的官方文檔做的demo,每個類都可以單獨運行。具體的細節都寫到註釋里了~

開發背景:

  SVNKit版本:1.7.14 附上官網下載鏈接:https://www.svnkit.com/org.tmatesoft.svn_1.7.14.standalone.zip

  jdk版本要求:我試了1.6版本是不行的,1.7版本的jdk沒有問題。

  操作:①.在官網下載SVNKit1.7.14後將lib/*.jar全部複製到工程中  ②.導入google的Gson的包,這裡我用的是gson-2.2.4.jar

  倉庫目錄結構:

    

 

  工程結構圖:

    

具體代碼:

  一、顯示svn倉庫的樹結構

package com.demo;

import org.tmatesoft.svn.core.SVNDirEntry;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
import java.io.File;
import java.util.Collection;
import java.util.Iterator;

/**
 * 顯示svn倉庫的樹結構
 */
public class PrintRepositoryTree {
    public static void main(String[] args) throws Exception{
        //1.根據訪問協議初始化工廠
        DAVRepositoryFactory.setup();;
        //2.初始化倉庫
        String url = "https://wlyfree-PC:8443/svn/svnkitRepository1/trunk";
        SVNRepository svnRepository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(url));
        //3.創建一個訪問的許可權
        String username = "wly";
        String password = "wly";
        char[] pwd = password.toCharArray();
        ISVNAuthenticationManager authenticationManager = SVNWCUtil.createDefaultAuthenticationManager(username,pwd);
        svnRepository.setAuthenticationManager(authenticationManager);
        /*輸出倉庫的根目錄和UUID*/
        System.out.println("Repository Root:" + svnRepository.getRepositoryRoot(true));
        System.out.println("Repository UUID:" + svnRepository.getRepositoryUUID(true));
        /**
         * 檢驗某個URL(可以是文件、目錄)是否在倉庫歷史的修訂版本中存在,參數:被檢驗的URL,修訂版本,這裡我們想要列印出目錄樹,所以要求必須是目錄
         * SVNNodeKind的枚舉值有以下四種:
         *  SVNNodeKind.NONE    這個node已經丟失(可能是已被刪除)
         *  SVNNodeKind.FILE    文件
         *  SVNNodeKind.DIR     目錄
         *  SVNNodeKind.UNKNOW  未知,無法解析
         * */
        /*
         *  被檢驗的URL,本例有兩種等價的寫法。
         *  1.不是以"/"開頭的是相對於倉庫驅動目錄的相對目錄,即svnRepository的url,在本例中是:空字元串(url目錄是:https://wlyfree-PC:8443/svn/svnkitRepository1/trunk)
         *  2.以"/"開頭的是相對於svnRepository root目錄的相對目錄,即svnRepository的rootUrl,在本例中是:/trunk(root目錄是https://wlyfree-pc:8443/svn/svnkitRepository1)
         */

        String checkUrl = "";
        //修訂版本號,-1代表一個無效的修訂版本號,代表必須是最新的修訂版
        long revisionNum = -1;
        SVNNodeKind svnNodeKind = svnRepository.checkPath(checkUrl,revisionNum);
        if(svnNodeKind == SVNNodeKind.NONE){
            System.err.println("This is no entry at " + checkUrl);
            System.exit(1);
        }else if(svnNodeKind == SVNNodeKind.FILE){
            System.err.println("The entry at '" + checkUrl + "' is a file while a directory was expected.");
            System.exit(1);
        }else{
            System.err.println("SVNNodeKind的值:" + svnNodeKind);
        }
        //列印出目錄樹結構
        listEntries(svnRepository,checkUrl);
        //列印最新修訂版的版本號
        System.err.println("最新修訂版版本號:" + svnRepository.getLatestRevision());
    }
    private static void listEntries(SVNRepository svnRepository,String path) throws Exception{
        System.err.println("path:" + path);
        Collection entry =  svnRepository.getDir(path, -1 ,null,(Collection)null);
        Iterator iterator = entry.iterator();
        while(iterator.hasNext()){
            SVNDirEntry svnDirEntry = (SVNDirEntry)iterator.next();
            System.out.println("path:" + "/" + (path.equals("") ? "" : path + "/") + svnDirEntry.getName() + ",(author:" + svnDirEntry.getAuthor() + ",revision:" + svnDirEntry.getRevision() + ",date:" + svnDirEntry.getDate() + ")");
            if(svnDirEntry.getKind() == SVNNodeKind.DIR){
                String tempPath = (path.equals("") ? svnDirEntry.getName() : path + "/" + svnDirEntry.getName()) ;
                listEntries(svnRepository,tempPath);
            }
        }
    }
}

  運行效果:

Repository Root:https://wlyfree-pc:8443/svn/svnkitRepository1
Repository UUID:62e76a57-4b9a-d34b-92c0-4551f8669da5
SVNNodeKind的值:dir
path:
path:test
path:/init1.txt,(author:wly,revision:8,date:Tue Nov 29 15:36:47 CST 2016)
path:/init2.txt,(author:wly,revision:8,date:Tue Nov 29 15:36:47 CST 2016)
path:/test,(author:wly,revision:10,date:Tue Dec 06 13:50:53 CST 2016)
path:/test/init11.txt,(author:wly,revision:10,date:Tue Dec 06 13:50:53 CST 2016)
path:/test/init22.txt,(author:wly,revision:9,date:Tue Dec 06 12:13:42 CST 2016)
path:/test/test2,(author:wly,revision:9,date:Tue Dec 06 12:13:42 CST 2016)
path:test/test2
path:/test/test2/init111.txt,(author:wly,revision:9,date:Tue Dec 06 12:13:42 CST 2016)
path:/test/test2/init222.txt,(author:wly,revision:9,date:Tue Dec 06 12:13:42 CST 2016)
最新修訂版版本號:10

Process finished with exit code 0

 

 

 

  二、列印文件內容

  獲取文件的類型,如果文件是二進位文件,則只輸出文件屬性;如果文件是一個文本文件,輸出文件屬性和文件內容

package com.demo;

import com.google.gson.Gson;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
import java.io.ByteArrayOutputStream;
import java.util.Iterator;
import java.util.Map;

/**
 *  獲取文件的類型,如果文件是二進位文件,則只輸出文件屬性;如果文件是一個文本文件,輸出文件屬性和文件內容
 */
public class PrintFileContent {
    public static void main(String[] args) throws Exception {
        //===========================前面幾步和列印樹是一樣的START===================================
        //1.根據訪問協議初始化工廠
        DAVRepositoryFactory.setup();;
        //2.初始化倉庫
        String url = "https://wlyfree-PC:8443/svn/svnkitRepository1/trunk";
        SVNRepository svnRepository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(url));
        //3.創建一個訪問的許可權
        String username = "wly";
        String password = "wly";
        char[] pwd = password.toCharArray();
        ISVNAuthenticationManager authenticationManager = SVNWCUtil.createDefaultAuthenticationManager(username,pwd);
        svnRepository.setAuthenticationManager(authenticationManager);
        //===========================前面幾步和列印樹是一樣的END===================================
        //這裡我們要讀取的是其中的一個文件
        String filePath = "test/init11.txt";
        //修訂版本號,-1代表一個無效的修訂版本號,代表必須是最新的修訂版
        long revisionNum = -1;
        SVNNodeKind svnNodeKind = svnRepository.checkPath(filePath,revisionNum);
        if(svnNodeKind == SVNNodeKind.NONE){
            System.err.println("This is no entry at " + filePath);
            System.exit(1);
        }else if(svnNodeKind == SVNNodeKind.DIR){
            System.err.println("The entry at '" + filePath + "' is a directory while a file was expected.");
            System.exit(1);
        }else{
            System.err.println("SVNNodeKind的值:" + svnNodeKind);
        }
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        SVNProperties svnProperties = new SVNProperties();
        //若svnProperties對象非空,使用vnProperties屬性接收文件的屬性
        svnRepository.getFile(filePath,-1,svnProperties ,byteArrayOutputStream);
        /*
         * 輸出文件屬性
         */
        System.err.println("文件屬性:");
        Map<String,SVNPropertyValue> svnPropertiesMap = svnProperties.asMap();
        Iterator<String> it = svnPropertiesMap.keySet().iterator();
        while(it.hasNext()){
            String key = it.next();
            System.err.println(key + " : " + svnPropertiesMap.get(key));
        }
        //序列化看下svnProperrties中的數據
        Gson gson = new Gson();
        System.err.println(gson.toJson(svnProperties));
        /*
         *  文件是否是文本類型的文件,文本類型文件輸出文件內容
         */
        System.err.println("文件內容:");
        String mimeType = svnProperties.getStringValue(SVNProperty.MIME_TYPE);
        System.err.println("mimeType is :" + mimeType);
        boolean isTextType = SVNProperty.isTextMimeType(mimeType);
        if(isTextType){
            System.err.println("The file is a text file,this is contents:");
            byteArrayOutputStream.writeTo(System.err);
        }else{
            System.err.println("The file is not a text file,we can't read content of it.");
        }
    }
}

  運行效果:

SVNNodeKind的值:file
文件屬性:
svn:entry:uuid : 62e76a57-4b9a-d34b-92c0-4551f8669da5
svn:entry:revision : 10
svn:entry:committed-date : 2016-12-06T05:50:53.160008Z
svn:wc:ra_dav:version-url : /svn/svnkitRepository1/!svn/ver/10/trunk/test/init11.txt
svn:entry:checksum : 8217e71c38f5c42e3fd4e8ac8dc75c4f
svn:entry:committed-rev : 10
svn:entry:last-author : wly
{"myProperties":{"svn:entry:uuid":{"myValue":"62e76a57-4b9a-d34b-92c0-4551f8669da5"},"svn:entry:revision":{"myValue":"10"},"svn:entry:committed-date":{"myValue":"2016-12-06T05:50:53.160008Z"},"svn:wc:ra_dav:version-url":{"myValue":"/svn/svnkitRepository1/!svn/ver/10/trunk/test/init11.txt"},"svn:entry:checksum":{"myValue":"8217e71c38f5c42e3fd4e8ac8dc75c4f"},"svn:entry:committed-rev":{"myValue":"10"},"svn:entry:last-author":{"myValue":"wly"}}}
文件內容:
mimeType is :null
The file is a text file,this is contents:
init
aa
bb
cc
dd
11
22
33
44

Process finished with exit code 0

 

  三、列印歷史記錄

package com.demo;

import com.google.gson.Gson;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNLogEntryPath;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

/**
 * 列印歷史記錄
 */
public class PrintRepositoryHistory {
    public static void main(String[] args) throws Exception{
        //===========================前面幾步和列印樹是一樣的START===================================
        //1.根據訪問協議初始化工廠
        DAVRepositoryFactory.setup();;
        //2.初始化倉庫
        String url = "https://wlyfree-PC:8443/svn/svnkitRepository1/trunk";
        SVNRepository svnRepository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(url));
        //3.創建一個訪問的許可權
        String username = "wly";
        String password = "wly";
        char[] pwd = password.toCharArray();
        ISVNAuthenticationManager authenticationManager = SVNWCUtil.createDefaultAuthenticationManager(username,pwd);
        svnRepository.setAuthenticationManager(authenticationManager);
        //===========================前面幾步和列印樹是一樣的END===================================
        long startVersion = 10;
        long endVersion = 8;
        /*
         *  參數:
         *  1.接收日誌
         *  2.接收history對象,每個修訂版的信息都代表一個SVNLogEntry對象。如果我們不需要傳入一個已經存在的history對象,就傳入null值
         *  3.開始修訂版本號,0、-1代表最新版本
         *  4.結束修訂版本號,0、-1代表最新版本
         *  5.如果需要列印改變路徑的信息,則設置為true。會使用每個SVNLogEntry對象記錄改變路徑的信息getchangedpaths()會返回一個Map<String改變路徑,SVNLogEntryPath> 對象
         *  6.strictNode設置為true,複製history的時候不會跳過每個path的修訂版日誌
         */
        Collection logEntries = svnRepository.log(new String[]{""}, null,8,8,true,true);
        Gson gson = new Gson();
        if(logEntries != null){
            Iterator it = logEntries.iterator();
            while (it.hasNext()){
                SVNLogEntry svnLogEntry = (SVNLogEntry)it.next();
                System.err.println("序列化數據:" + gson.toJson(svnLogEntry));
                if(svnLogEntry.getChangedPaths().size() > 0){
                    System.err.println("Change path:");
                    Set changePathSet = svnLogEntry.getChangedPaths().keySet();
                    if(changePathSet != null && changePathSet.size() > 0){
                        for(Iterator changePaths = changePathSet.iterator();changePaths.hasNext();){
                            SVNLogEntryPath svnLogEntryPath = svnLogEntry.getChangedPaths().get(changePaths.next());
                            System.err.println(gson.toJson(svnLogEntryPath));
                        }
                    }
                }
            }
        }
    }
}

  運行效果:

序列化數據:{"myRevision":8,"myChangedPaths":{"/trunk/init1.txt":{"myPath":"/trunk/init1.txt","myType":"A","myCopyRevision":-1,"myNodeKind":{"myID":1}},"/trunk/init2.txt":{"myPath":"/trunk/init2.txt","myType":"A","myCopyRevision":-1,"myNodeKind":{"myID":1}}},"myRevisionProperties":{"myProperties":{"svn:log":{"myValue":"初始化導入目錄-myRepository1"},"svn:author":{"myValue":"wly"},"svn:date":{"myValue":"2016-11-29T07:36:47.737654Z"}}},"myHasChildren":false,"myIsSubtractiveMerge":false,"myIsNonInheritable":false}
Change path:
{"myPath":"/trunk/init1.txt","myType":"A","myCopyRevision":-1,"myNodeKind":{"myID":1}}
{"myPath":"/trunk/init2.txt","myType":"A","myCopyRevision":-1,"myNodeKind":{"myID":1}}

Process finished with exit code 0

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.IOE ...
  • [1]安裝 [2]連接 [3]增刪改查 [4]分散式 [5]狀態 [6]安全 [7]應用 ...
  • ssm整合地址:http://www.cnblogs.com/xiaohuihui96/p/6104351.html 接下講解一個插入語句的流程和順帶講解freemarker+jsp視圖的整合 初次接觸,如果有錯誤請評論指出,謝謝 表單界面:add.jsp spring-mvc.xml 業務類的配置 ...
  • C++使用如下方法遍歷一個容器: 其中auto用到了C++11的類型推導。同時我們也可以使用std::for_each完成同樣的功能: 現在C++11的for迴圈有了一種新的用法: 上述方式是只讀,如果需要修改arr裡邊的值,可以使用for(auto& n:arr),for迴圈的這種使用方式的內在實 ...
  • 在用python的bottle框架開發時,前端使用ajax跨域訪問時,js代碼老是進入不了success,而是進入了error,而返回的狀態卻是200。url直接在瀏覽器訪問也是正常的,瀏覽器按F12後會發現下麵這個錯誤提示 通過搜索引擎查詢錯誤,會發現幾乎查找出來的答案都說是跨域問題,只需要在主文 ...
  • Django基本配置 Python的WEB框架有Django、Tornado、Flask 等多種,Django相較與其他WEB框架其優勢為:大而全,框架本身集成了ORM、模型綁定、模板引擎、緩存、Session等諸多功能 1、安裝 2、創建Django工程 其他命令: mysite目錄結構: Dja ...
  • 1.寫一條sql關聯兩個表要求顯示欄位如下 城市id 城市名稱=name 省份名稱=name select c.id,c.name,p.name from city as c join province as p on c.pid=p.id; 結果: 2.用thinkphp實現 關聯兩個表要求顯示字 ...
  • 博客一:轉載自http://shmilyaw-hotmail-com.iteye.com/blog/1825171 java stack的詳細實現分析 簡介 我們最常用的數據結構之一大概就是stack了。在實際的程式執行,方法調用的過程中都離不開stack。那麼,在一個成熟的類庫裡面,它的實現是怎麼 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...