Skip to content

Commit c2443aa

Browse files
committed
Merge branch 'master' into B1
# Conflicts: # build.gradle
2 parents 49eaeae + 953ba13 commit c2443aa

26 files changed

+552
-171
lines changed

.travis.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
language: java
2+
before_install:
3+
- chmod +x gradlew
4+
before_cache:
5+
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
6+
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
7+
cache:
8+
directories:
9+
- $HOME/.gradle/caches/
10+
- $HOME/.gradle/wrapper/
11+
after_success:
12+
- ./gradlew jacocoTestReport coveralls

README.md

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
[![Release](https://jitpack.io/v/scm4j/scm4j-vcs-api.svg)](https://jitpack.io/#scm4j/scm4j-vcs-api)
1+
[![Release](https://jitpack.io/v/scm4j/scm4j-vcs-api.svg)](https://jitpack.io/#scm4j/scm4j-vcs-api)
2+
[![Build Status](https://travis-ci.org/scm4j/scm4j-ai.svg?branch=master)](https://travis-ci.org/scm4j/scm4j-ai)
3+
[![Coverage Status](https://coveralls.io/repos/github/scm4j/scm4j-vcs-api/badge.svg?branch=master)](https://coveralls.io/github/scm4j/scm4j-vcs-api?branch=master)
24

35
# Overview
46
scm4j-vcs-api is set of base classes and interfaces to build VCS support (Git, SVN, etc) libraries which exposes basic vcs-related operations: merge, branch create etc.
57
scm4j-vcs-api provides:
68
- A simple interface to implement basic VCS-related operations
7-
- Set of functional tests which are common to each VCS implementation. Functional tests for a certain VCS implementation are done by implementing few abstract methods of base test class. Implemented in [scm4j-vcs-test](https://github.com/scm4j/scm4j-vcs-test)
9+
- Set of functional tests wchich are common to each VCS implementation. Functional tests for a certain VCS implementation are done by implementing few abstract methods of base test class. Implemented in [scm4j-vcs-test](https://github.com/scm4j/scm4j-vcs-test)
810
- Working copy management for operations which must be executed on local file system
911

1012
# Terms
@@ -36,6 +38,8 @@ scm4j-vcs-api provides:
3638
- The latest commit or state of a branch
3739
- Master Branch
3840
- "Master" for Git, "Trunk" for SVN etc
41+
- `VCSTag`, Tag
42+
- Contains tag name, tag log message, tag author and `VCSCommit` instance which represents the tagged commit
3943

4044
# Using VCS interface
4145
IVCS interface consists of few basic vcs functions.
@@ -64,27 +68,38 @@ Note: null passed as a branch name is considered as Master Branch. Any non-null
6468
- `fileRelativePath` is a path to file within `branchName` branch
6569
- The Head file state is used
6670
- Use `String getFileContent(String branchName, String fileRelativePath)` overload to use UTF-8 encoding by default
67-
- `String setFileContent(String branchName, String filePath, String content, String commitMessage)`
71+
- `VCSCommit setFileContent(String branchName, String filePath, String content, String commitMessage)`
6872
- Rewrites a file with path `filePath` within branch `branchName` with content `content` and applies `commitMessage` message to commit
6973
- Creates the file and its parent folders if doesn't exists
70-
- Returns commit id (hash, revision number etc)
7174
- `List<VCSDiffEntry> getBranchesDiff(String srcBranchName, String destBranchName)`
7275
- Returns list of `VCSDiffEntry` showing what was made within branch `srcBranchName` relative to branch `destBranchName`
73-
- Note: result is a commit which would be made on merging the branch `srcBranchName` into `destBranchName`
76+
- Note: result could be considered as a commit which would be made on merging the branch `srcBranchName` into `destBranchName`
7477
- `Set<String> getBranches()`
7578
- Returns list of names of all branches. Branches here are considered as user-created branches and Master Branch. I.e. any branch for Git, "Trunk" and any branch within "Branches" branch (not "Tags" branches) for SVN etc
7679
- `List<String> getCommitMessages(Sting branchName, Integer limit)`
7780
- Returns list of commit messages of branch `branchName` limited by `limit` in descending order
7881
- `String getVCSTypeString`
7982
- Returns short name of current IVCS implementation: "git", "svn" etc
80-
- `String removeFile(String branchName, String filePath, String commitMessage)`
81-
- Removes the file located by `filePath` within branch `branchName`. Operation is executed as separate commit with `commitMessage` message attached. Note: filePath = "folder\file.txt" -> file.txt is removed, folder is kept
82-
- Returns commit id (hash, revision number etc)
83-
- `List<VCSCommit> getCommitsRange(String branchName, String afterCommitId, String untilCommitId);`
84-
- Returns ordered list of all commits located between commits specified by `aftercommitId` and `untilCommitId` within branch `branchName`
85-
- If `aftercommitId` is null then all commits until commit specified by `untilCommitId` are fetched
86-
- If `untilCommitId` is null then all commits after commit specified by `afterCommitId` are fetched
87-
83+
- `VCSCommit removeFile(String branchName, String filePath, String commitMessage)`
84+
- Removes the file with path `filePath` within branch `branchName`. Operation is executed as separate commit with `commitMessage` message attached. Note: filePath = "folder\file.txt" -> file.txt is removed, folder is kept
85+
- `List<VCSCommit> getCommitsRange(String branchName, String firstCommitId, String untilCommitId)`
86+
- Returns ordered list of all commits located between commits specified by `firstCommitId` and `untilCommitId` inclusively within branch `branchName`
87+
- If `firstCommitId` is null then all commits until commit specified by `untilCommitId` inclusively are fetched
88+
- If `untilCommitId` is null then all commits starting from commit specified by `firstCommitId` are fetched
89+
- `List<VCSCommit> getCommitsRange(String branchName, String firstCommitId, WalkDirection direction, int limit)`
90+
- Returns ordered list of `limit` commits (0 is unlimited) starting from commit specified by `firstCommitId` in direction specified by `direction`
91+
- If `firstCommitId` is null then commits are starting at branch `branchName` first commit (for ASC direction) or at head of branch (for DESC direction)
92+
- `VCSCommit getHeadCommit(String branchName)`
93+
- Returns `VCSCommit` instance pointing to the head (last) commit of the branch `branchName`
94+
- `Boolean fileExists(String branchName, String filePath)`
95+
- Returns true if the file with path `filePath` exists in repository in branch `branchName`, false otherwise
96+
- `VCSTag createTag(String branchName, String tagName, String tagMessage) throws EVCSTagExists`
97+
- Creates a tag named `tagName` with log message `tagMessage` on a Head of branch `branchName`
98+
- `List<VCSTag> getTags()`
99+
- Returns list of all tags
100+
- `VCSTag getLastTag()`
101+
- Returns the last created tag
102+
88103
# Using Locked Working Copy
89104
Let's assume we developing a multiuser server which has ability to merge branches of user's repositories. So few users could request to merge theirs branches of different repositories simultaneously. For example, Git merge operation consists of few underlying operations (check in\out, merge itself, push) which must be executed on a local file system in a certain folder. So we have following requirements:
90105
- The simple way to allocate place for vcs operations execution
@@ -186,7 +201,7 @@ Lock way: `new FileOutputStream(lockFile, false).getChannel.lock()`
186201
- Throw exceptions from scm4j.vcs.api.exceptions package. Abstract Test checks throwning of these exceptions.
187202
- Implement functional tests
188203
- Create VCSAbstractTest subclass within test package, implement all abstract methods
189-
- Normally test class should not include any test, just @After\@Before methods. All necessary functional testing is implemented within VCSAbstractTest
204+
- Normally test class should not include any test, just @After and @Before methods. All necessary functional testing is implemented within VCSAbstractTest
190205
- See [scm4j-vcs-test](https://github.com/scm4j/scm4j-vcs-test) for details
191206
- Example of gradle usage to export IVCS implementation, its sources and javadoc as separate single JARs:
192207
```gradle

build.gradle

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,36 @@
1+
plugins {
2+
id 'jacoco'
3+
id 'com.github.kt3k.coveralls' version '2.8.1'
4+
}
5+
16
apply plugin: 'java'
27
apply plugin: 'maven'
8+
apply plugin: 'eclipse'
9+
apply plugin: 'idea'
310

411
sourceCompatibility = JavaVersion.VERSION_1_7
512
targetCompatibility = JavaVersion.VERSION_1_7
613

714
group = 'org.scm4j'
8-
version = '2.0'
15+
version = '3.0'
16+
17+
jacocoTestReport {
18+
reports {
19+
xml.enabled = true // coveralls plugin depends on xml format report
20+
html.enabled = true
21+
}
22+
}
923

1024
repositories {
1125
mavenCentral()
1226
}
1327

1428
dependencies {
15-
testCompile 'junit:junit:4.12'
16-
testCompile 'org.mockito:mockito-core:2.0.62-beta'
17-
18-
compile 'commons-io:commons-io:2.5'
29+
testCompile 'junit:junit:4.12'
30+
testCompile 'org.mockito:mockito-core:2.0.62-beta'
31+
testCompile 'nl.jqno.equalsverifier:equalsverifier:2.3'
32+
33+
compile 'commons-io:commons-io:2.5'
1934
}
2035

2136
task sourcesJar(type: Jar, dependsOn: classes) {

src/main/java/org/scm4j/vcs/api/IVCS.java

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package org.scm4j.vcs.api;
22

3-
import java.util.List;
4-
import java.util.Set;
5-
3+
import org.scm4j.vcs.api.exceptions.EVCSBranchExists;
64
import org.scm4j.vcs.api.exceptions.EVCSFileNotFound;
5+
import org.scm4j.vcs.api.exceptions.EVCSTagExists;
76
import org.scm4j.vcs.api.workingcopy.IVCSWorkspace;
87

8+
import java.util.List;
9+
import java.util.Set;
10+
911
public interface IVCS {
10-
void createBranch(String srcBranchName, String dstBranchName, String commitMessage);
12+
void createBranch(String srcBranchName, String dstBranchName, String commitMessage) throws EVCSBranchExists;
1113

1214
VCSMergeResult merge(String srcBranchName, String dstBranchName, String commitMessage);
1315

@@ -23,7 +25,7 @@ public interface IVCS {
2325

2426
String getFileContent(String branchName, String fileRelativePath) throws EVCSFileNotFound;
2527

26-
String setFileContent(String branchName, String filePath, String content, String commitMessage);
28+
VCSCommit setFileContent(String branchName, String filePath, String content, String commitMessage);
2729

2830
List<VCSDiffEntry> getBranchesDiff(String srcBranchName, String destBranchName);
2931

@@ -33,9 +35,21 @@ public interface IVCS {
3335

3436
String getVCSTypeString();
3537

36-
String removeFile(String branchName, String filePath, String commitMessage);
38+
VCSCommit removeFile(String branchName, String filePath, String commitMessage);
39+
40+
List<VCSCommit> getCommitsRange(String branchName, String firstCommitId, String untilCommitId);
41+
42+
List<VCSCommit> getCommitsRange(String branchName, String firstCommitId, WalkDirection direction, int limit);
43+
44+
IVCSWorkspace getWorkspace();
45+
46+
VCSCommit getHeadCommit(String branchName);
47+
48+
Boolean fileExists(String branchName, String filePath);
49+
50+
VCSTag createTag(String branchName, String tagName, String tagMessage) throws EVCSTagExists;
3751

38-
List<VCSCommit> getCommitsRange(String branchName, String afterCommitId, String untilCommitId);
52+
List<VCSTag> getTags();
3953

40-
IVCSWorkspace getWorkspace();
54+
VCSTag getLastTag();
4155
}
Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,75 @@
11
package org.scm4j.vcs.api;
22

33
public class VCSCommit {
4-
private final String id;
4+
public static final VCSCommit EMPTY = new VCSCommit();
5+
private final String revision;
56
private final String logMessage;
67
private final String author;
7-
8+
89
public String getAuthor() {
910
return author;
1011
}
1112

12-
public String getId() {
13-
return id;
13+
public String getRevision() {
14+
return revision;
1415
}
1516

1617
public String getLogMessage() {
1718
return logMessage;
1819
}
1920

20-
public VCSCommit(String id, String logMessage, String author) {
21-
super();
22-
this.id = id;
21+
@Override
22+
public int hashCode() {
23+
final int prime = 31;
24+
int result = 1;
25+
result = prime * result + ((author == null) ? 0 : author.hashCode());
26+
result = prime * result + ((logMessage == null) ? 0 : logMessage.hashCode());
27+
result = prime * result + ((revision == null) ? 0 : revision.hashCode());
28+
return result;
29+
}
30+
31+
@Override
32+
public boolean equals(Object obj) {
33+
if (this == obj)
34+
return true;
35+
if (obj == null)
36+
return false;
37+
if (getClass() != obj.getClass())
38+
return false;
39+
VCSCommit other = (VCSCommit) obj;
40+
if (author == null) {
41+
if (other.author != null)
42+
return false;
43+
} else if (!author.equals(other.author))
44+
return false;
45+
if (logMessage == null) {
46+
if (other.logMessage != null)
47+
return false;
48+
} else if (!logMessage.equals(other.logMessage))
49+
return false;
50+
if (revision == null) {
51+
if (other.revision != null)
52+
return false;
53+
} else if (!revision.equals(other.revision))
54+
return false;
55+
return true;
56+
}
57+
58+
protected VCSCommit() {
59+
revision = null;
60+
logMessage = null;
61+
author = null;
62+
}
63+
64+
public VCSCommit(String revision, String logMessage, String author) {
65+
this.revision = revision;
2366
this.logMessage = logMessage;
2467
this.author = author;
2568
}
2669

2770
@Override
2871
public String toString() {
29-
return "VCSCommit [id=" + id + ", logMessage=" + logMessage + ", author=" + author + "]";
72+
return this == EMPTY ? "EMPTY"
73+
: "VCSCommit [revision=" + revision + ", logMessage=" + logMessage + ", author=" + author + "]";
3074
}
3175
}

src/main/java/org/scm4j/vcs/api/VCSDiffEntry.java

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,69 +2,30 @@
22

33
public class VCSDiffEntry {
44

5-
private String filePath;
6-
private VCSChangeType changeType;
7-
private String unifiedDiff;
8-
5+
private final String filePath;
6+
private final VCSChangeType changeType;
7+
private final String unifiedDiff;
8+
99
public String getUnifiedDiff() {
1010
return unifiedDiff;
1111
}
1212

13-
public void setUnifiedDiff(String unifiedDiff) {
14-
this.unifiedDiff = unifiedDiff;
15-
}
16-
1713
public String getFilePath() {
1814
return filePath;
1915
}
2016

21-
public void setFilePath(String filePath) {
22-
this.filePath = filePath;
23-
}
24-
2517
public VCSChangeType getChangeType() {
2618
return changeType;
2719
}
2820

29-
public void setChangeType(VCSChangeType changeType) {
30-
this.changeType = changeType;
31-
}
32-
33-
public VCSDiffEntry(String filePath, VCSChangeType changeType) {
21+
public VCSDiffEntry(String filePath, VCSChangeType changeType, String unifiedDiff) {
3422
this.filePath = filePath;
3523
this.changeType = changeType;
24+
this.unifiedDiff = unifiedDiff;
3625
}
3726

3827
@Override
3928
public String toString() {
4029
return "VCSDiffEntry [filePath=" + filePath + ", changeType=" + changeType + "]";
4130
}
42-
43-
@Override
44-
public int hashCode() {
45-
final int prime = 31;
46-
int result = 1;
47-
result = prime * result + ((changeType == null) ? 0 : changeType.hashCode());
48-
result = prime * result + ((filePath == null) ? 0 : filePath.hashCode());
49-
return result;
50-
}
51-
52-
@Override
53-
public boolean equals(Object obj) {
54-
if (this == obj)
55-
return true;
56-
if (obj == null)
57-
return false;
58-
if (getClass() != obj.getClass())
59-
return false;
60-
VCSDiffEntry other = (VCSDiffEntry) obj;
61-
if (changeType != other.changeType)
62-
return false;
63-
if (filePath == null) {
64-
if (other.filePath != null)
65-
return false;
66-
} else if (!filePath.equals(other.filePath))
67-
return false;
68-
return true;
69-
}
7031
}
Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,22 @@
11
package org.scm4j.vcs.api;
22

3-
import java.util.ArrayList;
43
import java.util.List;
54

65
public class VCSMergeResult {
76

8-
private Boolean success;
9-
private List<String> conflictingFiles = new ArrayList<>();
7+
private final Boolean success;
8+
private final List<String> conflictingFiles;
109

1110
public Boolean getSuccess() {
1211
return success;
1312
}
1413

15-
public void setSuccess(Boolean success) {
16-
this.success = success;
17-
}
18-
1914
public List<String> getConflictingFiles() {
2015
return conflictingFiles;
2116
}
2217

23-
public void setConflictingFiles(List<String> conflictingFiles) {
18+
public VCSMergeResult(Boolean success, List<String> conflictingFiles) {
19+
this.success = success;
2420
this.conflictingFiles = conflictingFiles;
2521
}
2622
}

0 commit comments

Comments
 (0)