SVNKit學習——使用低級別的API(ISVNEditor接口)直接操作Repository的目錄和文件(五)
阿新 • • 發佈:2018-02-24
gen pro 內容 windows cut ext key run exception
本文是參考官方文檔的實現,官方wiki:https://wiki.svnkit.com/Committing_To_A_Repository
本文核心使用的是ISVNEditor這個接口直接對Repository進行各種AM操作~
以下兩張示例圖分別代表我們操作前、操作後倉庫的結構:
具體實現:
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.ISVNEditor;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.io.diff.SVNDeltaGenerator;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
/**
* 提交到倉庫
* 這塊看官方demno的意思如果不用權限認證,會使用a session user name作為提交的author,但是我試了會報錯401,author required~
* 本例是基於初始倉庫圖A轉換為目標倉庫圖B的過程,我們需要執行的操作有:
* 1.刪除nodeB/itemB1
* 2.編輯nodeC/itemC1
* 3.新增nodeC/itemC2,並設置itemC2的文件屬性
* 4.新增nodeB子節點nodeD
*/
public class CommitToRepository {
public static void main(String[] args) throws Exception{
//1.根據訪問協議初始化工廠
DAVRepositoryFactory.setup();;
//2.初始化倉庫,由於我們所有的操作都是基於nodeB節點以下的,所以我們將nodeB作為本次操作的root節點
String url = "https://wlyfree-PC:8443/svn/svnkitRepository2/trunk/nodeB";
SVNRepository svnRepository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(url));
//3.初始化權限
String username = "wly";
String password = "wly";
char[] pwd = password.toCharArray();
ISVNAuthenticationManager isvnAuthenticationManager = SVNWCUtil.createDefaultAuthenticationManager(username,pwd);
svnRepository.setAuthenticationManager(isvnAuthenticationManager);
//====================================DEMO START=========================================
ISVNEditor editor = null;
long revisionNo = -1; //指定版本號為最新版本
//4.1.刪除nodeB/itemB1
try{
//獲取編輯器
editor = svnRepository.getCommitEditor("delete file",null,true,null);
String itemB1Path = "itemB1";//要刪除的文件路徑
SVNCommitInfo svnCommitInfo = deleteFile(editor,revisionNo);//執行刪除並返回執行結果
System.out.println("執行刪除操作的返回結果:" + svnCommitInfo);
}catch (SVNException e){
//發生異常需要終止操作
editor.abortEdit();
e.printStackTrace();;
}
//4.2.編輯nodeC/itemC1
try{
//獲取編輯器
editor = svnRepository.getCommitEditor("modify file",null,true,null);
SVNCommitInfo svnCommitInfo = modifyFile(editor,revisionNo);
System.out.println("執行編輯操作的返回結果:" + svnCommitInfo);
}catch(SVNException e){
//發生異常需要終止操作
editor.abortEdit();
e.printStackTrace();;
}
//4.3.新增nodeC/itemC2,並設置itemC2的文件屬性
try{
editor = svnRepository.getCommitEditor("add file",null,true,null);
SVNCommitInfo svnCommitInfo = addFile(editor,revisionNo);
System.out.println("執行新增文件操作的返回結果:" + svnCommitInfo);
//校驗nodeC/itemC2的屬性是否成功設置進去
SVNProperties s = new SVNProperties();
svnRepository.getFile("nodeC/itemC2",-1,s,null);
Gson gson = new Gson();
System.err.println(gson.toJson(s));
}catch (SVNException e){
editor.abortEdit();
e.printStackTrace();
}
//4.4.新增nodeB子節點nodeD
try{
editor = svnRepository.getCommitEditor("add dir",null,true,null);
SVNCommitInfo svnCommitInfo = addDir(editor,revisionNo);
System.out.println("執行新增目錄操作的返回結果:" + svnCommitInfo);
}catch (SVNException e){
editor.abortEdit();
e.printStackTrace();
}
}
/**
* 刪除文件
* @param editor 編輯器
* @param revisionNo 修訂版版本號
* @return SVNCommitInfo 提交結果信息
* @throws SVNException
*/
private static SVNCommitInfo deleteFile(ISVNEditor editor,long revisionNo) throws SVNException{
// 進入Root節點,即nodeB
editor.openRoot(revisionNo);
//4.3.刪除文件
editor.deleteEntry("itemB1",revisionNo);
//操作完成要關閉編輯器,並返回操作結果
return editor.closeEdit();
}
/**
* 編輯文件
* @param editor 編輯器
* @param revisionNo 修訂版版本號
* @return SVNCommitInfo 提交結果信息
* @throws SVNException
*/
private static SVNCommitInfo modifyFile(ISVNEditor editor,long revisionNo) throws SVNException{
// 進入Root節點,即nodeB
editor.openRoot(revisionNo);
//.進入nodeC節點
editor.openDir("nodeC",revisionNo);
// 編輯nodeC/itemC1的內容
String itemC1Path = "nodeC/itemC1";//路徑都是相對於root的
editor.openFile(itemC1Path,revisionNo);
//確保客戶端這個文件的內容和服務端的是一樣的,如果不一致的話是不允許提交的。底層實現使用MD5
String baseChecksum = null;
editor.applyTextDelta(itemC1Path,baseChecksum);
//提交文件變更的數據,windows默認是100kb大小
byte[] oldData = new byte[]{};
byte[] newData = null;
try {
newData = "我來測試一下編輯2".getBytes("utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
ByteArrayInputStream baseData = new ByteArrayInputStream(oldData);
ByteArrayInputStream workingData = new ByteArrayInputStream(newData);
SVNDeltaGenerator svnDeltaGenerator = new SVNDeltaGenerator();//100KB-windows generator
String checksum = svnDeltaGenerator.sendDelta(itemC1Path,baseData,0,workingData,editor,true);
// 關閉文件
editor.closeFile(itemC1Path,checksum);
// 關閉目錄nodeC
editor.closeDir();
// 關閉根目錄nodeB
editor.closeDir();
// 關閉編輯器,並返回執行結果
return editor.closeEdit();
}
/**
* 新增文件
* @param editor
* @param revisionNo
* @return
* @throws SVNException
*/
private static SVNCommitInfo addFile(ISVNEditor editor,long revisionNo) throws SVNException{
// 進入Root節點,即nodeB
editor.openRoot(revisionNo);
//.進入nodeC節點
editor.openDir("nodeC",revisionNo);
// 新增itemC2文件
editor.addFile("nodeC/itemC2",null,revisionNo);
//確保客戶端這個文件的內容和服務端的是一樣的,如果不一致的話是不允許提交的。底層實現使用MD5
String itemC2Path = "nodeC/itemC2"