2424import org .tmatesoft .svn .core .auth .BasicAuthenticationManager ;
2525import org .tmatesoft .svn .core .auth .SVNAuthentication ;
2626import org .tmatesoft .svn .core .auth .SVNPasswordAuthentication ;
27- import org .tmatesoft .svn .core .internal .io .dav .DAVRepositoryFactory ;
2827import org .tmatesoft .svn .core .internal .wc .DefaultSVNOptions ;
29- import org .tmatesoft .svn .core .internal .wc .SVNFileType ;
3028import org .tmatesoft .svn .core .io .SVNRepository ;
3129import org .tmatesoft .svn .core .io .SVNRepositoryFactory ;
3230import org .tmatesoft .svn .core .wc .ISVNConflictHandler ;
4543import org .tmatesoft .svn .core .wc .SVNWCClient ;
4644import org .tmatesoft .svn .core .wc .SVNWCUtil ;
4745import org .tmatesoft .svn .core .wc2 .ISvnObjectReceiver ;
46+ import org .tmatesoft .svn .core .wc2 .SvnDiff ;
4847import org .tmatesoft .svn .core .wc2 .SvnDiffStatus ;
4948import org .tmatesoft .svn .core .wc2 .SvnDiffSummarize ;
5049import org .tmatesoft .svn .core .wc2 .SvnOperationFactory ;
@@ -92,7 +91,6 @@ public SVNVCS(IVCSRepositoryWorkspace repo, String user, String password) {
9291 if (!repoUrl .endsWith ("/" ) && !repoUrl .endsWith ("\\ " )) {
9392 repoUrl += "/" ;
9493 }
95- DAVRepositoryFactory .setup ();
9694 options = SVNWCUtil .createDefaultOptions (true );
9795 try {
9896 trunkSVNUrl = SVNURL .parseURIEncoded (repo .getRepoUrl ().replace ("\\ " , "/" ));
@@ -108,8 +106,6 @@ public SVNVCS(IVCSRepositoryWorkspace repo, String user, String password) {
108106
109107 clientManager = SVNClientManager .newInstance (
110108 options , repository .getAuthenticationManager ());
111-
112- SVNFileType .setSymlinkSupportEnabled (false );
113109 }
114110
115111 public SVNRepository getRepository () {
@@ -120,6 +116,10 @@ private SVNURL getBranchUrl(String branchPath) throws SVNException {
120116 return SVNURL .parseURIEncoded (repoUrl + (branchPath == null ? MASTER_PATH : BRANCHES_PATH + branchPath ));
121117 }
122118
119+ private String getBranchPath (String branchPath ) {
120+ return branchPath == null ? MASTER_PATH : BRANCHES_PATH + branchPath ;
121+ }
122+
123123 @ Override
124124 public void createBranch (String srcBranchName , String dstBranchName , String commitMessage ) {
125125 try {
@@ -170,7 +170,7 @@ public void deleteBranch(String branchName, String commitMessage) {
170170 }
171171
172172 @ Override
173- public VCSMergeResult merge (String srcBranchÒôüó , String dstBranchName , String commitMessage ) {
173+ public VCSMergeResult merge (String srcBranchName , String dstBranchName , String commitMessage ) {
174174 SVNDiffClient diffClient = clientManager .getDiffClient ();
175175 try {
176176 try (IVCSLockedWorkingCopy wc = repo .getVCSLockedWorkingCopy ()) {
@@ -190,7 +190,7 @@ public SVNConflictResult handleConflict(SVNConflictDescription conflictDescripti
190190
191191 try {
192192 SVNRevisionRange range = new SVNRevisionRange (SVNRevision .create (1 ), SVNRevision .HEAD );
193- diffClient .doMerge (getBranchUrl (srcBranchÒôüó ),
193+ diffClient .doMerge (getBranchUrl (srcBranchName ),
194194 SVNRevision .HEAD , Collections .singleton (range ),
195195 wc .getFolder (), SVNDepth .UNKNOWN , true , false , false , false );
196196
@@ -326,47 +326,99 @@ public void setFileContent(String branchName, String filePath, String content, S
326326 public String getRepoUrl () {
327327 return repo .getRepoUrl ();
328328 }
329-
330- @ Override
331- public List <VCSDiffEntry > getBranchesDiff (final String srcBranchName , final String dstBranchName ) {
332- try {
333- final List <SVNLogEntry > entries = new ArrayList <>();
334- repository .log (new String [] { "branches/" + srcBranchName }, -1 /* start from head descending */ ,
335- 0 , true , true , -1 , new ISVNLogEntryHandler () {
336- @ Override
337- public void handleLogEntry (SVNLogEntry logEntry ) throws SVNException {
338- entries .add (logEntry );
339- }
340- });
341- SVNLogEntry branchFirstCommit = entries .get (entries .size () - 1 );
329+
330+ private void fillUnifiedDiffs (final String srcBranchName , final String dstBranchName , List <VCSDiffEntry > entries ,
331+ IVCSLockedWorkingCopy wc ) throws SVNException {
332+ for (VCSDiffEntry entry : entries ) {
333+ ByteArrayOutputStream baos = new ByteArrayOutputStream ();
342334
343- SvnOperationFactory svnOperationFactory = new SvnOperationFactory ();
344- SvnDiffSummarize diff = svnOperationFactory .createDiffSummarize ();
345- diff .setSources (
346- SvnTarget .fromURL (getBranchUrl (srcBranchName ), SVNRevision .create (branchFirstCommit .getRevision ())),
347- SvnTarget .fromURL (getBranchUrl (srcBranchName ), SVNRevision .HEAD ));
335+ final SvnOperationFactory svnOperationFactory = new SvnOperationFactory ();
336+ final SvnDiff diff = svnOperationFactory .createDiff ();
348337
349- final List <VCSDiffEntry > res = new ArrayList <>();
350- diff .setReceiver (new ISvnObjectReceiver <SvnDiffStatus >() {
351- public void receive (SvnTarget target , SvnDiffStatus diffStatus ) throws SVNException {
352- res .add (new VCSDiffEntry (diffStatus .getPath (),
353- SVNChangeTypeToVCSChangeType (diffStatus .getModificationType ())));
354- }
338+ if (entry .getChangeType () == VCSChangeType .ADD ) {
339+ SVNLogEntry firstCommit = getBranchFirstCommit (getBranchPath (dstBranchName ));
340+ diff .setSource (SvnTarget .fromURL (getBranchUrl (srcBranchName ).appendPath (entry .getFilePath (), true ), SVNRevision .HEAD ),
341+ SVNRevision .create (firstCommit .getRevision ()),
342+ SVNRevision .create (repository .info (getBranchPath (dstBranchName ), -1 ).getRevision ()));
343+ } else if (entry .getChangeType () == VCSChangeType .DELETE ) {
344+ SVNLogEntry firstCommit = getBranchFirstCommit (getBranchPath (dstBranchName ));
345+ diff .setSource (SvnTarget .fromURL (getBranchUrl (dstBranchName ).appendPath (entry .getFilePath (), true ), SVNRevision .HEAD ),
346+ SVNRevision .create (repository .info (getBranchPath (dstBranchName ), -1 ).getRevision ()),
347+ SVNRevision .create (firstCommit .getRevision ()));
348+ } else {
349+ diff .setSources (
350+ SvnTarget .fromURL (getBranchUrl (dstBranchName ).appendPath (entry .getFilePath (), true ), SVNRevision .HEAD ),
351+ SvnTarget .fromURL (getBranchUrl (srcBranchName ).appendPath (entry .getFilePath (), true ), SVNRevision .HEAD ));
352+ }
353+ diff .setOutput (baos );
354+ diff .run ();
355355
356- private VCSChangeType SVNChangeTypeToVCSChangeType (SVNStatusType modificationType ) {
357- if (SVNStatusType .STATUS_ADDED .equals (modificationType )) {
358- return VCSChangeType .ADD ;
359- } else if (SVNStatusType .STATUS_DELETED .equals (modificationType )) {
360- return VCSChangeType .DELETE ;
361- } else if (SVNStatusType .STATUS_MODIFIED .equals (modificationType )) {
362- return VCSChangeType .MODIFY ;
363- } else {
364- return VCSChangeType .UNKNOWN ;
365- }
356+ try {
357+ entry .setUnifiedDiff (baos .toString ("UTF-8" ));
358+ } catch (UnsupportedEncodingException e ) {
359+ throw new RuntimeException (e );
360+ }
361+ }
362+ }
363+
364+ private SVNLogEntry getBranchFirstCommit (final String branchPath ) throws SVNException {
365+ final List <SVNLogEntry > logEntries = new ArrayList <>();
366+ repository .log (new String [] { branchPath }, -1 /* start from head descending */ ,
367+ 0 , true , true , -1 , new ISVNLogEntryHandler () {
368+ @ Override
369+ public void handleLogEntry (SVNLogEntry logEntry ) throws SVNException {
370+ logEntries .add (logEntry );
371+ }
372+ });
373+ return logEntries .get (logEntries .size () - 1 );
374+ }
375+
376+
377+ private List <VCSDiffEntry > getDiffEntries (final String srcBranchName , final String dstBranchName ,
378+ final IVCSLockedWorkingCopy wc ) throws SVNException {
379+ final SvnOperationFactory svnOperationFactory = new SvnOperationFactory ();
380+ final SvnDiffSummarize summarizeDiff = svnOperationFactory .createDiffSummarize ();
381+ final List <VCSDiffEntry > res = new ArrayList <>();
382+
383+ summarizeDiff .setSources (
384+ SvnTarget .fromURL (getBranchUrl (dstBranchName ), SVNRevision .HEAD ),
385+ SvnTarget .fromURL (getBranchUrl (srcBranchName ), SVNRevision .HEAD ));
386+
387+ summarizeDiff .setReceiver (new ISvnObjectReceiver <SvnDiffStatus >() {
388+ public void receive (SvnTarget target , SvnDiffStatus diffStatus ) throws SVNException {
389+ if (diffStatus .getPath ().length () == 0 ) {
390+ return ;
391+ }
392+ VCSDiffEntry entry = new VCSDiffEntry (diffStatus .getPath (),
393+ SVNChangeTypeToVCSChangeType (diffStatus .getModificationType ()));
394+ res .add (entry );
395+ }
396+
397+ private VCSChangeType SVNChangeTypeToVCSChangeType (SVNStatusType modificationType ) {
398+ if (SVNStatusType .STATUS_ADDED .equals (modificationType )) {
399+ return VCSChangeType .ADD ;
400+ } else if (SVNStatusType .STATUS_DELETED .equals (modificationType )) {
401+ return VCSChangeType .DELETE ;
402+ } else if (SVNStatusType .STATUS_MODIFIED .equals (modificationType )) {
403+ return VCSChangeType .MODIFY ;
404+ } else {
405+ return VCSChangeType .UNKNOWN ;
366406 }
367- });
368- diff .run ();
369- return res ;
407+ }
408+ });
409+
410+ return res ;
411+ }
412+
413+ @ Override
414+ public List <VCSDiffEntry > getBranchesDiff (final String srcBranchName , final String dstBranchName ) {
415+ try {
416+ try (IVCSLockedWorkingCopy wc = repo .getVCSLockedWorkingCopy ()) {
417+ checkout (getBranchUrl (dstBranchName ), wc .getFolder ());
418+ List <VCSDiffEntry > entries = getDiffEntries (srcBranchName , dstBranchName , wc );
419+ fillUnifiedDiffs (srcBranchName , dstBranchName , entries , wc );
420+ return entries ;
421+ }
370422 } catch (SVNException e ) {
371423 throw new EVCSException (e );
372424 } catch (Exception e ) {
0 commit comments