[Notice] Announcing the End of Demo Server [Read me]

code: Improve the error handling for oversized diff
Now, If one or both of the files are too big to show or get the difference from them, Yobi show an error message different from one for the case if the difference is oversized. This also fixes an error have occured when render small diff of an oversized file because FileDiff.getError returns A_SIZE_EXCEEDED or B_SIZE_EXCEEDED if the file is larger than the FileDiff.LINE_LIMIT. If the diff is not larger than the limit, it should be able to rendered even if the file is larger than the limit but small enough not to raise org.eclipse.jgit.errors.LargeObjectException. And add tests for some exceptional cases.
@c9fc265c1492e08698a999939e963f4e42c68b2d
--- app/playRepository/FileDiff.java
+++ app/playRepository/FileDiff.java
... | ... | @@ -17,7 +17,7 @@ |
17 | 17 |
public class FileDiff { |
18 | 18 |
public static final int SIZE_LIMIT = 500 * 1024; |
19 | 19 |
public static final int LINE_LIMIT = 5000; |
20 |
- private Error error; |
|
20 |
+ private Set<Error> errors = new HashSet<>(); |
|
21 | 21 |
public enum Error {A_SIZE_EXCEEDED, B_SIZE_EXCEEDED, DIFF_SIZE_EXCEEDED, OTHERS_SIZE_EXCEEDED } |
22 | 22 |
public RawText a; |
23 | 23 |
public RawText b; |
... | ... | @@ -226,21 +226,44 @@ |
226 | 226 |
return oldMode.getBits() != newMode.getBits(); |
227 | 227 |
} |
228 | 228 |
|
229 |
- public void setError(Error error) { |
|
230 |
- this.error = error; |
|
229 |
+ public void addError(Error error) { |
|
230 |
+ this.errors.add(error); |
|
231 | 231 |
} |
232 | 232 |
|
233 |
- public Error getError() { |
|
234 |
- if (error != null) { |
|
235 |
- return error; |
|
236 |
- } else if (a != null && isRawTextSizeExceeds(a)) { |
|
237 |
- return Error.A_SIZE_EXCEEDED; |
|
238 |
- } else if (b != null && isRawTextSizeExceeds(b)) { |
|
239 |
- return Error.B_SIZE_EXCEEDED; |
|
240 |
- } else if (getHunks() instanceof SizeExceededHunks) { |
|
241 |
- return Error.DIFF_SIZE_EXCEEDED; |
|
242 |
- } else { |
|
243 |
- return null; |
|
233 |
+ public boolean hasAnyError(Error ... errors) { |
|
234 |
+ refreshErrors(); |
|
235 |
+ |
|
236 |
+ for (Error error : errors) { |
|
237 |
+ if (this.errors.contains(error)) { |
|
238 |
+ return true; |
|
239 |
+ } |
|
244 | 240 |
} |
241 |
+ |
|
242 |
+ return false; |
|
243 |
+ } |
|
244 |
+ |
|
245 |
+ private void refreshErrors() { |
|
246 |
+ if (getHunks() instanceof SizeExceededHunks) { |
|
247 |
+ addError(Error.DIFF_SIZE_EXCEEDED); |
|
248 |
+ } |
|
249 |
+ |
|
250 |
+ // If editList is already produced, there is no need to concern about |
|
251 |
+ // the size of the raw text a or b |
|
252 |
+ if (editList == null && a != null && isRawTextSizeExceeds(a)) { |
|
253 |
+ addError(Error.A_SIZE_EXCEEDED); |
|
254 |
+ } |
|
255 |
+ if (editList == null && b != null && isRawTextSizeExceeds(b)) { |
|
256 |
+ addError(Error.B_SIZE_EXCEEDED); |
|
257 |
+ } |
|
258 |
+ } |
|
259 |
+ |
|
260 |
+ public boolean hasError(Error error) { |
|
261 |
+ refreshErrors(); |
|
262 |
+ return this.errors.contains(error); |
|
263 |
+ } |
|
264 |
+ |
|
265 |
+ public boolean hasError() { |
|
266 |
+ refreshErrors(); |
|
267 |
+ return !this.errors.isEmpty(); |
|
245 | 268 |
} |
246 | 269 |
} |
--- app/playRepository/GitRepository.java
+++ app/playRepository/GitRepository.java
... | ... | @@ -678,6 +678,16 @@ |
678 | 678 |
return getFileDiffs(repository, repository, commitIdA, commit.getId()); |
679 | 679 |
} |
680 | 680 |
|
681 |
+ public static List<FileDiff> getDiff(Repository repository, RevCommit commit) throws IOException { |
|
682 |
+ ObjectId commitIdA = null; |
|
683 |
+ if (commit.getParentCount() > 0) { |
|
684 |
+ commitIdA = commit.getParent(0).getId(); |
|
685 |
+ } |
|
686 |
+ |
|
687 |
+ return getFileDiffs(repository, repository, commitIdA, commit.getId()); |
|
688 |
+ } |
|
689 |
+ |
|
690 |
+ |
|
681 | 691 |
/** |
682 | 692 |
* {@code untilRevName}에 해당하는 리비전까지의 커밋 목록을 반환한다. |
683 | 693 |
* {@code untilRevName}이 null이면 HEAD 까지의 커밋 목록을 반환한다. |
... | ... | @@ -1689,17 +1699,15 @@ |
1689 | 1699 |
&& Arrays.asList(DELETE, MODIFY, RENAME, COPY).contains(diff.getChangeType())) { |
1690 | 1700 |
TreeWalk t1 = TreeWalk.forPath(repositoryA, pathA, treeA); |
1691 | 1701 |
ObjectId blobA = t1.getObjectId(0); |
1702 |
+ fileDiff.pathA = pathA; |
|
1692 | 1703 |
|
1693 | 1704 |
try { |
1694 | 1705 |
rawA = repositoryA.open(blobA).getBytes(); |
1706 |
+ fileDiff.isBinaryA = RawText.isBinary(rawA); |
|
1707 |
+ fileDiff.a = fileDiff.isBinaryA ? null : new RawText(rawA); |
|
1695 | 1708 |
} catch (org.eclipse.jgit.errors.LargeObjectException e) { |
1696 |
- result.add(fileDiff); |
|
1697 |
- continue; |
|
1709 |
+ fileDiff.addError(FileDiff.Error.A_SIZE_EXCEEDED); |
|
1698 | 1710 |
} |
1699 |
- |
|
1700 |
- fileDiff.isBinaryA = RawText.isBinary(rawA); |
|
1701 |
- fileDiff.a = fileDiff.isBinaryA ? null : new RawText(rawA); |
|
1702 |
- fileDiff.pathA = pathA; |
|
1703 | 1711 |
} |
1704 | 1712 |
|
1705 | 1713 |
byte[] rawB = null; |
... | ... | @@ -1707,26 +1715,28 @@ |
1707 | 1715 |
&& Arrays.asList(ADD, MODIFY, RENAME, COPY).contains(diff.getChangeType())) { |
1708 | 1716 |
TreeWalk t2 = TreeWalk.forPath(repositoryB, pathB, treeB); |
1709 | 1717 |
ObjectId blobB = t2.getObjectId(0); |
1718 |
+ fileDiff.pathB = pathB; |
|
1710 | 1719 |
|
1711 | 1720 |
try { |
1712 | 1721 |
rawB = repositoryB.open(blobB).getBytes(); |
1722 |
+ fileDiff.isBinaryB = RawText.isBinary(rawB); |
|
1723 |
+ fileDiff.b = fileDiff.isBinaryB ? null : new RawText(rawB); |
|
1713 | 1724 |
} catch (org.eclipse.jgit.errors.LargeObjectException e) { |
1714 |
- result.add(fileDiff); |
|
1715 |
- continue; |
|
1725 |
+ fileDiff.addError(FileDiff.Error.B_SIZE_EXCEEDED); |
|
1716 | 1726 |
} |
1717 |
- |
|
1718 |
- fileDiff.isBinaryB = RawText.isBinary(rawB); |
|
1719 |
- fileDiff.b = fileDiff.isBinaryB ? null : new RawText(rawB); |
|
1720 |
- fileDiff.pathB = pathB; |
|
1721 | 1727 |
} |
1722 | 1728 |
|
1723 | 1729 |
if (size > DIFF_SIZE_LIMIT || lines > DIFF_LINE_LIMIT) { |
1724 |
- fileDiff.setError(FileDiff.Error.OTHERS_SIZE_EXCEEDED); |
|
1730 |
+ fileDiff.addError(FileDiff.Error.OTHERS_SIZE_EXCEEDED); |
|
1725 | 1731 |
result.add(fileDiff); |
1726 | 1732 |
continue; |
1727 | 1733 |
} |
1728 | 1734 |
|
1729 |
- if (!(fileDiff.isBinaryA || fileDiff.isBinaryB) && Arrays.asList(MODIFY, RENAME).contains(diff.getChangeType())) { |
|
1735 |
+ // Get diff if necessary |
|
1736 |
+ if (fileDiff.a != null |
|
1737 |
+ && fileDiff.b != null |
|
1738 |
+ && !(fileDiff.isBinaryA || fileDiff.isBinaryB) |
|
1739 |
+ && Arrays.asList(MODIFY, RENAME).contains(diff.getChangeType())) { |
|
1730 | 1740 |
DiffAlgorithm diffAlgorithm = DiffAlgorithm.getAlgorithm( |
1731 | 1741 |
repositoryB.getConfig().getEnum( |
1732 | 1742 |
ConfigConstants.CONFIG_DIFF_SECTION, null, |
... | ... | @@ -1738,16 +1748,19 @@ |
1738 | 1748 |
lines += fileDiff.getHunks().lines; |
1739 | 1749 |
} |
1740 | 1750 |
|
1741 |
- if (!fileDiff.isBinaryB && diff.getChangeType().equals(ADD)) { |
|
1751 |
+ // update lines and sizes |
|
1752 |
+ if (fileDiff.b != null && !fileDiff.isBinaryB && diff.getChangeType().equals(ADD)) { |
|
1742 | 1753 |
lines += fileDiff.b.size(); |
1743 | 1754 |
size += rawB.length; |
1744 | 1755 |
} |
1745 | 1756 |
|
1746 |
- if (!fileDiff.isBinaryA && diff.getChangeType().equals(DELETE)) { |
|
1757 |
+ // update lines and sizes |
|
1758 |
+ if (fileDiff.a != null && !fileDiff.isBinaryA && diff.getChangeType().equals(DELETE)) { |
|
1747 | 1759 |
lines += fileDiff.a.size(); |
1748 |
- size += rawA.length; |
|
1760 |
+ size += rawA.length; |
|
1749 | 1761 |
} |
1750 | 1762 |
|
1763 |
+ // Stop if exceeds the limit for total number of files |
|
1751 | 1764 |
if (result.size() > DIFF_FILE_LIMIT) { |
1752 | 1765 |
break; |
1753 | 1766 |
} |
--- app/views/partial_filediff.scala.html
+++ app/views/partial_filediff.scala.html
... | ... | @@ -12,6 +12,7 @@ |
12 | 12 |
@import scala.collection.immutable.List |
13 | 13 |
@import scala.collection.JavaConversions._ |
14 | 14 |
@import org.apache.commons.lang.StringEscapeUtils.escapeHtml; |
15 |
+@import FileDiff.Error._ |
|
15 | 16 |
|
16 | 17 |
@** |
17 | 18 |
* 변경 내용(Diff) 표시 |
... | ... | @@ -23,10 +24,12 @@ |
23 | 24 |
@if(diff.isFileModeChanged) { |
24 | 25 |
<tr><td class="linenum"><div class="line-number" data-line-num="@diff.oldMode"></div><span class="hidden">@diff.oldMode</span></td><td class="linenum"><div class="line-number" data-line-num="@diff.newMode"></div><span class="hidden">@diff.newMode</span></td><td class="isBinary">@Messages("code.fileModeChanged")</td></tr> |
25 | 26 |
} |
26 |
- @diff.getError match { |
|
27 |
- case FileDiff.Error.OTHERS_SIZE_EXCEEDED => { <tr><td colspan=3>@Messages("code.skipDiff")</td></tr> } |
|
28 |
- case FileDiff.Error.DIFF_SIZE_EXCEEDED => { <tr><td colspan=3>@Messages("code.tooBigDiff")</td></tr> } |
|
29 |
- case null => { |
|
27 |
+ @null match { |
|
28 |
+ case _ if diff.hasError(OTHERS_SIZE_EXCEEDED) => { <tr><td colspan=3>@Messages("code.skipDiff")</td></tr> } |
|
29 |
+ case _ if diff.hasAnyError(A_SIZE_EXCEEDED, B_SIZE_EXCEEDED) => { <tr><td colspan=3>@Messages("code.tooBigFile")</td></tr> } |
|
30 |
+ case _ if diff.hasError(DIFF_SIZE_EXCEEDED) => { <tr><td colspan=3>@Messages("code.tooBigDiff")</td></tr> } |
|
31 |
+ case _ if diff.hasError => { <tr><td colspan=3>@Messages("code.unknownError")</td></tr> } |
|
32 |
+ case _ => { |
|
30 | 33 |
@diff.getHunks match { |
31 | 34 |
case hunks if (hunks.size <= 0) => { |
32 | 35 |
@diff.isFileModeChanged match { |
... | ... | @@ -42,7 +45,6 @@ |
42 | 45 |
} |
43 | 46 |
} |
44 | 47 |
} |
45 |
- case _ => { <tr><td colspan=3>@Messages("code.unknownError")</td></tr> } |
|
46 | 48 |
} |
47 | 49 |
} |
48 | 50 |
|
... | ... | @@ -96,14 +98,14 @@ |
96 | 98 |
* @param isBinaryOverwritten 기존 데이터가 바이너리인 경우 true |
97 | 99 |
**@ |
98 | 100 |
@renderAddedLines(diff: FileDiff, comments:Map[String, List[_ <: CodeComment]], isBinaryOverwritten: Boolean = false) = { |
99 |
- @diff.getError match { |
|
100 |
- case FileDiff.Error.OTHERS_SIZE_EXCEEDED => { <tr><td colspan=3>@Messages("code.skipDiff")</td></tr> } |
|
101 |
- case FileDiff.Error.B_SIZE_EXCEEDED => { <tr><td colspan=3>@Messages("code.tooBigDiff")</td></tr> } |
|
101 |
+ @null match { |
|
102 |
+ case _ if diff.hasError(OTHERS_SIZE_EXCEEDED) => { <tr><td colspan=3>@Messages("code.skipDiff")</td></tr> } |
|
103 |
+ case _ if diff.hasError(B_SIZE_EXCEEDED) => { <tr><td colspan=3>@Messages("code.tooBigFile")</td></tr> } |
|
104 |
+ case _ if diff.hasError => { <tr><td colspan=3>@Messages("code.unknownError")</td></tr> } |
|
102 | 105 |
case null => { <tr class="range"><td class="linenum"><div class="line-number" data-line-num="..."><span class="hidden">...</span></div></td><td class="linenum"><div class="line-number" data-line-num="..."><span class="hidden">...</span></div></td><td class="hunk">@@@@ -0,0 +1,@diff.b.size @@@@</td></tr> |
103 | 106 |
@if(isBinaryOverwritten ) { @renderCodeIsBinary("remove", "-") } |
104 | 107 |
@renderRawFile("add", diff.pathB, diff.b, CodeComment.Side.B, "+", comments) |
105 | 108 |
} |
106 |
- case _ => { <tr><td colspan=3>@Messages("code.unknownError")</td></tr> } |
|
107 | 109 |
} |
108 | 110 |
} |
109 | 111 |
|
... | ... | @@ -115,14 +117,14 @@ |
115 | 117 |
* @param isOverwrittenByBinary 새 데이터가 바이너리인 경우 true |
116 | 118 |
**@ |
117 | 119 |
@renderRemovedLines(diff: FileDiff, comments:Map[String, List[_ <: CodeComment]], isOverwrittenByBinary: Boolean = false) = { |
118 |
- @diff.getError match { |
|
119 |
- case FileDiff.Error.OTHERS_SIZE_EXCEEDED => { <tr><td colspan=3>@Messages("code.skipDiff")</td></tr> } |
|
120 |
- case FileDiff.Error.A_SIZE_EXCEEDED => { <tr><td colspan=3>@Messages("code.tooBigDiff")</td></tr> } |
|
121 |
- case null => { <tr class="range"><td class="linenum"><div class="line-number" data-line-num="..."><span class="hidden">...</span></div></td><td class="linenum"><div class="line-number" data-line-num="..."><span class="hidden">...</span></div></td><td class="hunk">@@@@ -1,@diff.a.size +0,0 @@@@</td></tr> |
|
120 |
+ @null match { |
|
121 |
+ case _ if diff.hasError(OTHERS_SIZE_EXCEEDED) => { <tr><td colspan=3>@Messages("code.skipDiff")</td></tr> } |
|
122 |
+ case _ if diff.hasError(A_SIZE_EXCEEDED) => { <tr><td colspan=3>@Messages("code.tooBigFile")</td></tr> } |
|
123 |
+ case _ if diff.hasError => { <tr><td colspan=3>@Messages("code.unknownError")</td></tr> } |
|
124 |
+ case _ => { <tr class="range"><td class="linenum"><div class="line-number" data-line-num="..."><span class="hidden">...</span></div></td><td class="linenum"><div class="line-number" data-line-num="..."><span class="hidden">...</span></div></td><td class="hunk">@@@@ -1,@diff.a.size +0,0 @@@@</td></tr> |
|
122 | 125 |
@renderRawFile("remove", diff.pathA, diff.a, CodeComment.Side.A, "-", comments) |
123 | 126 |
@if(isOverwrittenByBinary) { @renderCodeIsBinary("add", "+") } |
124 | 127 |
} |
125 |
- case _ => { <tr><td colspan=3>@Messages("code.unknownError")</td></tr> } |
|
126 | 128 |
} |
127 | 129 |
} |
128 | 130 |
|
--- conf/messages
+++ conf/messages
... | ... | @@ -110,6 +110,7 @@ |
110 | 110 |
code.showcomments = Show Comments |
111 | 111 |
code.skipDiff = This diff is skipped because others are too many. |
112 | 112 |
code.tooBigDiff = This diff is too big to show. |
113 |
+code.tooBigFile = This file is too big to show. |
|
113 | 114 |
code.unknownError = Unknown error |
114 | 115 |
common.attach.attachIfYouSave = will be attached when you save |
115 | 116 |
common.attach.clickToPost = Click to post |
--- conf/messages.ko
+++ conf/messages.ko
... | ... | @@ -110,6 +110,7 @@ |
110 | 110 |
code.showcomments = 댓글 표시하기 |
111 | 111 |
code.skipDiff = 다른 파일의 변경내역이 너무 많아서 이 파일의 변경내역은 생략합니다. |
112 | 112 |
code.tooBigDiff = 이 파일의 변경내역은 너무 커서 보여드릴 수 없습니다. |
113 |
+code.tooBigFile = 이 파일은 너무 커서 보여드릴 수 없습니다. |
|
113 | 114 |
code.unknownError = 알 수 없는 에러가 발생하였습니다. |
114 | 115 |
common.attach.attachIfYouSave = 표시된 파일은 글을 저장하면 첨부됩니다. |
115 | 116 |
common.attach.clickToPost = 본문에 넣기 |
--- test/playRepository/GitRepositoryTest.java
+++ test/playRepository/GitRepositoryTest.java
... | ... | @@ -685,4 +685,173 @@ |
685 | 685 |
return repository.open(treeWalk.getObjectId(0)).getBytes(); |
686 | 686 |
} |
687 | 687 |
} |
688 |
+ |
|
689 |
+ @Test |
|
690 |
+ public void getDiff_bigFile() throws IOException, GitAPIException { |
|
691 |
+ // given |
|
692 |
+ String userName = "yobi"; |
|
693 |
+ String projectName = "testProject"; |
|
694 |
+ String wcPath = GitRepository.getRepoPrefix() + userName + "/" + projectName; |
|
695 |
+ |
|
696 |
+ String repoPath = wcPath + "/.git"; |
|
697 |
+ File repoDir = new File(repoPath); |
|
698 |
+ Repository repo = new RepositoryBuilder().setGitDir(repoDir).build(); |
|
699 |
+ repo.create(false); |
|
700 |
+ |
|
701 |
+ Git git = new Git(repo); |
|
702 |
+ String testFilePath = wcPath + "/readme.txt"; |
|
703 |
+ BufferedWriter out = new BufferedWriter(new FileWriter(testFilePath)); |
|
704 |
+ |
|
705 |
+ char[] cbuf = new char[FileDiff.SIZE_LIMIT + 1]; |
|
706 |
+ java.util.Arrays.fill(cbuf, 'a'); |
|
707 |
+ out.write(cbuf); // Add a big file |
|
708 |
+ out.flush(); |
|
709 |
+ git.add().addFilepattern("readme.txt").call(); |
|
710 |
+ RevCommit commit = git.commit().setMessage("commit 1").call(); |
|
711 |
+ |
|
712 |
+ // When |
|
713 |
+ FileDiff diff = GitRepository.getDiff(repo, commit).get(0); |
|
714 |
+ |
|
715 |
+ // Then |
|
716 |
+ assertThat(diff.a).describedAs("a").isNull(); |
|
717 |
+ assertThat(diff.b).describedAs("b").isNotNull(); |
|
718 |
+ assertThat(diff.hasError(FileDiff.Error.A_SIZE_EXCEEDED)) |
|
719 |
+ .describedAs("a exceeds the size limit.").isFalse(); |
|
720 |
+ assertThat(diff.hasError(FileDiff.Error.B_SIZE_EXCEEDED)) |
|
721 |
+ .describedAs("b exceeds the size limit.").isTrue(); |
|
722 |
+ assertThat(diff.hasError(FileDiff.Error.DIFF_SIZE_EXCEEDED)) |
|
723 |
+ .describedAs("The diff exceeds the size limit.").isFalse(); |
|
724 |
+ assertThat(diff.hasError(FileDiff.Error.OTHERS_SIZE_EXCEEDED)) |
|
725 |
+ .describedAs("The others exceeds the size limit.").isFalse(); |
|
726 |
+ } |
|
727 |
+ |
|
728 |
+ @Test |
|
729 |
+ public void getDiff_manyLines() throws IOException, GitAPIException { |
|
730 |
+ // given |
|
731 |
+ String userName = "yobi"; |
|
732 |
+ String projectName = "testProject"; |
|
733 |
+ String wcPath = GitRepository.getRepoPrefix() + userName + "/" + projectName; |
|
734 |
+ |
|
735 |
+ String repoPath = wcPath + "/.git"; |
|
736 |
+ File repoDir = new File(repoPath); |
|
737 |
+ Repository repo = new RepositoryBuilder().setGitDir(repoDir).build(); |
|
738 |
+ repo.create(false); |
|
739 |
+ |
|
740 |
+ Git git = new Git(repo); |
|
741 |
+ String testFilePath = wcPath + "/readme.txt"; |
|
742 |
+ BufferedWriter out = new BufferedWriter(new FileWriter(testFilePath)); |
|
743 |
+ |
|
744 |
+ for (int i = 0; i < FileDiff.LINE_LIMIT + 1; i++) { |
|
745 |
+ out.write("a\n"); // Add a big file |
|
746 |
+ } |
|
747 |
+ out.flush(); |
|
748 |
+ git.add().addFilepattern("readme.txt").call(); |
|
749 |
+ RevCommit commit = git.commit().setMessage("commit 1").call(); |
|
750 |
+ |
|
751 |
+ // When |
|
752 |
+ FileDiff diff = GitRepository.getDiff(repo, commit).get(0); |
|
753 |
+ |
|
754 |
+ // Then |
|
755 |
+ assertThat(diff.hasError(FileDiff.Error.A_SIZE_EXCEEDED)) |
|
756 |
+ .describedAs("a exceeds the size limit.").isFalse(); |
|
757 |
+ assertThat(diff.hasError(FileDiff.Error.B_SIZE_EXCEEDED)) |
|
758 |
+ .describedAs("b exceeds the size limit.").isTrue(); |
|
759 |
+ assertThat(diff.hasError(FileDiff.Error.DIFF_SIZE_EXCEEDED)) |
|
760 |
+ .describedAs("The diff exceeds the size limit.").isFalse(); |
|
761 |
+ assertThat(diff.hasError(FileDiff.Error.OTHERS_SIZE_EXCEEDED)) |
|
762 |
+ .describedAs("The others exceeds the size limit.").isFalse(); |
|
763 |
+ |
|
764 |
+ } |
|
765 |
+ |
|
766 |
+ @Test |
|
767 |
+ public void getDiff_smallChangeOfBigFile() throws IOException, GitAPIException { |
|
768 |
+ // given |
|
769 |
+ String userName = "yobi"; |
|
770 |
+ String projectName = "testProject"; |
|
771 |
+ String wcPath = GitRepository.getRepoPrefix() + userName + "/" + projectName; |
|
772 |
+ |
|
773 |
+ String repoPath = wcPath + "/.git"; |
|
774 |
+ File repoDir = new File(repoPath); |
|
775 |
+ Repository repo = new RepositoryBuilder().setGitDir(repoDir).build(); |
|
776 |
+ repo.create(false); |
|
777 |
+ |
|
778 |
+ Git git = new Git(repo); |
|
779 |
+ String testFilePath = wcPath + "/readme.txt"; |
|
780 |
+ BufferedWriter out = new BufferedWriter(new FileWriter(testFilePath)); |
|
781 |
+ |
|
782 |
+ // Commit a big file |
|
783 |
+ for (int i = 0; i < FileDiff.LINE_LIMIT + 1; i++) { |
|
784 |
+ out.write("a\n"); // Add a big file |
|
785 |
+ } |
|
786 |
+ out.flush(); |
|
787 |
+ git.add().addFilepattern("readme.txt").call(); |
|
788 |
+ git.commit().setMessage("commit 1").call(); |
|
789 |
+ |
|
790 |
+ // Modify the file |
|
791 |
+ out.write("b\n"); |
|
792 |
+ out.flush(); |
|
793 |
+ git.add().addFilepattern("readme.txt").call(); |
|
794 |
+ RevCommit commit = git.commit().setMessage("commit 2").call(); |
|
795 |
+ |
|
796 |
+ // When |
|
797 |
+ FileDiff diff = GitRepository.getDiff(repo, commit).get(0); |
|
798 |
+ |
|
799 |
+ // Then |
|
800 |
+ assertThat(diff.hasError(FileDiff.Error.A_SIZE_EXCEEDED)) |
|
801 |
+ .describedAs("a exceeds the size limit.").isFalse(); |
|
802 |
+ assertThat(diff.hasError(FileDiff.Error.B_SIZE_EXCEEDED)) |
|
803 |
+ .describedAs("b exceeds the size limit.").isFalse(); |
|
804 |
+ assertThat(diff.hasError(FileDiff.Error.DIFF_SIZE_EXCEEDED)) |
|
805 |
+ .describedAs("The diff exceeds the size limit.").isFalse(); |
|
806 |
+ assertThat(diff.hasError(FileDiff.Error.OTHERS_SIZE_EXCEEDED)) |
|
807 |
+ .describedAs("The others exceeds the size limit.").isFalse(); |
|
808 |
+ } |
|
809 |
+ |
|
810 |
+ @Test |
|
811 |
+ public void getDiff_manyFiles() throws IOException, GitAPIException { |
|
812 |
+ // given |
|
813 |
+ String userName = "yobi"; |
|
814 |
+ String projectName = "testProject"; |
|
815 |
+ String wcPath = GitRepository.getRepoPrefix() + userName + "/" + projectName; |
|
816 |
+ |
|
817 |
+ String repoPath = wcPath + "/.git"; |
|
818 |
+ File repoDir = new File(repoPath); |
|
819 |
+ Repository repo = new RepositoryBuilder().setGitDir(repoDir).build(); |
|
820 |
+ repo.create(false); |
|
821 |
+ |
|
822 |
+ Git git = new Git(repo); |
|
823 |
+ |
|
824 |
+ // Add four big files |
|
825 |
+ for(int i = 0; i < 4; i++) { |
|
826 |
+ String testFilePath = wcPath + "/" + i + ".txt"; |
|
827 |
+ BufferedWriter out = new BufferedWriter(new FileWriter(testFilePath)); |
|
828 |
+ char[] cbuf = new char[FileDiff.SIZE_LIMIT - 1]; |
|
829 |
+ java.util.Arrays.fill(cbuf, 'a'); |
|
830 |
+ out.write(cbuf); |
|
831 |
+ out.flush(); |
|
832 |
+ git.add().addFilepattern(i + ".txt").call(); |
|
833 |
+ } |
|
834 |
+ |
|
835 |
+ // Add a small file |
|
836 |
+ String testFilePath = wcPath + "/readme.txt"; |
|
837 |
+ BufferedWriter out = new BufferedWriter(new FileWriter(testFilePath)); |
|
838 |
+ out.write("hello"); |
|
839 |
+ out.flush(); |
|
840 |
+ git.add().addFilepattern("readme.txt").call(); |
|
841 |
+ RevCommit commit = git.commit().setMessage("commit 1").call(); |
|
842 |
+ |
|
843 |
+ // When |
|
844 |
+ List<FileDiff> diffs = GitRepository.getDiff(repo, commit); |
|
845 |
+ FileDiff diff = diffs.get(4); |
|
846 |
+ |
|
847 |
+ // Then |
|
848 |
+ assertThat(diff.hasError(FileDiff.Error.A_SIZE_EXCEEDED)) |
|
849 |
+ .describedAs("a exceeds the size limit.").isFalse(); |
|
850 |
+ assertThat(diff.hasError(FileDiff.Error.B_SIZE_EXCEEDED)) |
|
851 |
+ .describedAs("b exceeds the size limit.").isFalse(); |
|
852 |
+ assertThat(diff.hasError(FileDiff.Error.DIFF_SIZE_EXCEEDED)) |
|
853 |
+ .describedAs("The diff exceeds the size limit.").isFalse(); |
|
854 |
+ assertThat(diff.hasError(FileDiff.Error.OTHERS_SIZE_EXCEEDED)) |
|
855 |
+ .describedAs("The others exceeds the size limit.").isTrue(); |
|
856 |
+ } |
|
688 | 857 |
} |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?