Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

ComparePage.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /*
  2. * Copyright 2013 gitblit.com.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.gitblit.wicket.pages;
  17. import java.text.MessageFormat;
  18. import java.util.ArrayList;
  19. import java.util.List;
  20. import org.apache.wicket.PageParameters;
  21. import org.apache.wicket.markup.html.basic.Label;
  22. import org.apache.wicket.markup.html.form.DropDownChoice;
  23. import org.apache.wicket.markup.html.form.TextField;
  24. import org.apache.wicket.markup.html.link.BookmarkablePageLink;
  25. import org.apache.wicket.markup.html.link.ExternalLink;
  26. import org.apache.wicket.markup.html.panel.Fragment;
  27. import org.apache.wicket.markup.repeater.Item;
  28. import org.apache.wicket.markup.repeater.data.DataView;
  29. import org.apache.wicket.markup.repeater.data.ListDataProvider;
  30. import org.apache.wicket.model.IModel;
  31. import org.apache.wicket.model.Model;
  32. import org.apache.wicket.protocol.http.RequestUtils;
  33. import org.apache.wicket.request.target.basic.RedirectRequestTarget;
  34. import org.eclipse.jgit.diff.DiffEntry.ChangeType;
  35. import org.eclipse.jgit.lib.Repository;
  36. import org.eclipse.jgit.revwalk.RevCommit;
  37. import com.gitblit.models.PathModel.PathChangeModel;
  38. import com.gitblit.models.RefModel;
  39. import com.gitblit.models.RepositoryModel;
  40. import com.gitblit.models.SubmoduleModel;
  41. import com.gitblit.utils.DiffUtils;
  42. import com.gitblit.utils.DiffUtils.DiffOutput;
  43. import com.gitblit.utils.DiffUtils.DiffOutputType;
  44. import com.gitblit.utils.JGitUtils;
  45. import com.gitblit.utils.StringUtils;
  46. import com.gitblit.wicket.SessionlessForm;
  47. import com.gitblit.wicket.WicketUtils;
  48. import com.gitblit.wicket.panels.CommitLegendPanel;
  49. import com.gitblit.wicket.panels.DiffStatPanel;
  50. import com.gitblit.wicket.panels.LinkPanel;
  51. import com.gitblit.wicket.panels.LogPanel;
  52. /**
  53. * The compare page allows you to compare two branches, tags, or hash ids.
  54. *
  55. * @author James Moger
  56. *
  57. */
  58. public class ComparePage extends RepositoryPage {
  59. IModel<String> fromCommitId = new Model<String>("");
  60. IModel<String> toCommitId = new Model<String>("");
  61. IModel<String> fromRefId = new Model<String>("");
  62. IModel<String> toRefId = new Model<String>("");
  63. public ComparePage(PageParameters params) {
  64. super(params);
  65. Repository r = getRepository();
  66. RepositoryModel repository = getRepositoryModel();
  67. if (StringUtils.isEmpty(objectId)) {
  68. // seleciton form
  69. add(new Label("comparison").setVisible(false));
  70. } else {
  71. // active comparison
  72. Fragment comparison = new Fragment("comparison", "comparisonFragment", this);
  73. add(comparison);
  74. RevCommit fromCommit;
  75. RevCommit toCommit;
  76. String[] parts = objectId.split("\\.\\.");
  77. if (parts[0].startsWith("refs/") && parts[1].startsWith("refs/")) {
  78. // set the ref models
  79. fromRefId.setObject(parts[0]);
  80. toRefId.setObject(parts[1]);
  81. fromCommit = getCommit(r, fromRefId.getObject());
  82. toCommit = getCommit(r, toRefId.getObject());
  83. } else {
  84. // set the id models
  85. fromCommitId.setObject(parts[0]);
  86. toCommitId.setObject(parts[1]);
  87. fromCommit = getCommit(r, fromCommitId.getObject());
  88. toCommit = getCommit(r, toCommitId.getObject());
  89. }
  90. // prepare submodules
  91. getSubmodules(toCommit);
  92. final String startId = fromCommit.getId().getName();
  93. final String endId = toCommit.getId().getName();
  94. // commit ids
  95. fromCommitId.setObject(startId);
  96. toCommitId.setObject(endId);
  97. final DiffOutput diff = DiffUtils.getDiff(r, fromCommit, toCommit, DiffOutputType.HTML);
  98. // add compare diffstat
  99. int insertions = 0;
  100. int deletions = 0;
  101. for (PathChangeModel pcm : diff.stat.paths) {
  102. insertions += pcm.insertions;
  103. deletions += pcm.deletions;
  104. }
  105. comparison.add(new DiffStatPanel("diffStat", insertions, deletions));
  106. // compare page links
  107. // comparison.add(new BookmarkablePageLink<Void>("patchLink", PatchPage.class,
  108. // WicketUtils.newRangeParameter(repositoryName, fromCommitId.toString(), toCommitId.getObject())));
  109. // display list of commits
  110. comparison.add(new LogPanel("commitList", repositoryName, objectId, r, 0, 0, repository.showRemoteBranches));
  111. // changed paths list
  112. comparison.add(new CommitLegendPanel("commitLegend", diff.stat.paths));
  113. ListDataProvider<PathChangeModel> pathsDp = new ListDataProvider<PathChangeModel>(diff.stat.paths);
  114. DataView<PathChangeModel> pathsView = new DataView<PathChangeModel>("changedPath", pathsDp) {
  115. private static final long serialVersionUID = 1L;
  116. int counter;
  117. @Override
  118. public void populateItem(final Item<PathChangeModel> item) {
  119. final PathChangeModel entry = item.getModelObject();
  120. Label changeType = new Label("changeType", "");
  121. WicketUtils.setChangeTypeCssClass(changeType, entry.changeType);
  122. setChangeTypeTooltip(changeType, entry.changeType);
  123. item.add(changeType);
  124. item.add(new DiffStatPanel("diffStat", entry.insertions, entry.deletions, true));
  125. boolean hasSubmodule = false;
  126. String submodulePath = null;
  127. if (entry.isTree()) {
  128. // tree
  129. item.add(new LinkPanel("pathName", null, entry.path, TreePage.class,
  130. WicketUtils
  131. .newPathParameter(repositoryName, endId, entry.path)));
  132. } else if (entry.isSubmodule()) {
  133. // submodule
  134. String submoduleId = entry.objectId;
  135. SubmoduleModel submodule = getSubmodule(entry.path);
  136. submodulePath = submodule.gitblitPath;
  137. hasSubmodule = submodule.hasSubmodule;
  138. // add relative link
  139. item.add(new LinkPanel("pathName", "list", entry.path + " @ " + getShortObjectId(submoduleId), "#" + entry.path));
  140. } else {
  141. // add relative link
  142. item.add(new LinkPanel("pathName", "list", entry.path, "#" + entry.path));
  143. }
  144. // quick links
  145. if (entry.isSubmodule()) {
  146. // submodule
  147. item.add(new ExternalLink("patch", "").setEnabled(false));
  148. item.add(new BookmarkablePageLink<Void>("view", CommitPage.class, WicketUtils
  149. .newObjectParameter(submodulePath, entry.objectId)).setEnabled(hasSubmodule));
  150. item.add(new ExternalLink("blame", "").setEnabled(false));
  151. item.add(new BookmarkablePageLink<Void>("history", HistoryPage.class, WicketUtils
  152. .newPathParameter(repositoryName, endId, entry.path))
  153. .setEnabled(!entry.changeType.equals(ChangeType.ADD)));
  154. } else {
  155. // tree or blob
  156. item.add(new BookmarkablePageLink<Void>("patch", PatchPage.class, WicketUtils
  157. .newBlobDiffParameter(repositoryName, startId, endId, entry.path))
  158. .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
  159. item.add(new BookmarkablePageLink<Void>("view", BlobPage.class, WicketUtils
  160. .newPathParameter(repositoryName, endId, entry.path))
  161. .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
  162. item.add(new BookmarkablePageLink<Void>("raw", RawPage.class, WicketUtils
  163. .newPathParameter(repositoryName, endId, entry.path))
  164. .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
  165. item.add(new BookmarkablePageLink<Void>("blame", BlamePage.class, WicketUtils
  166. .newPathParameter(repositoryName, endId, entry.path))
  167. .setEnabled(!entry.changeType.equals(ChangeType.ADD)
  168. && !entry.changeType.equals(ChangeType.DELETE)));
  169. item.add(new BookmarkablePageLink<Void>("history", HistoryPage.class, WicketUtils
  170. .newPathParameter(repositoryName, endId, entry.path))
  171. .setEnabled(!entry.changeType.equals(ChangeType.ADD)));
  172. }
  173. WicketUtils.setAlternatingBackground(item, counter);
  174. counter++;
  175. }
  176. };
  177. comparison.add(pathsView);
  178. comparison.add(new Label("diffText", diff.content).setEscapeModelStrings(false));
  179. }
  180. //
  181. // ref selection form
  182. //
  183. SessionlessForm<Void> refsForm = new SessionlessForm<Void>("compareRefsForm", getClass(), getPageParameters()) {
  184. private static final long serialVersionUID = 1L;
  185. @Override
  186. public void onSubmit() {
  187. String from = ComparePage.this.fromRefId.getObject();
  188. String to = ComparePage.this.toRefId.getObject();
  189. PageParameters params = WicketUtils.newRangeParameter(repositoryName, from, to);
  190. String relativeUrl = urlFor(ComparePage.class, params).toString();
  191. String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl);
  192. getRequestCycle().setRequestTarget(new RedirectRequestTarget(absoluteUrl));
  193. }
  194. };
  195. List<String> refs = new ArrayList<String>();
  196. for (RefModel ref : JGitUtils.getLocalBranches(r, true, -1)) {
  197. refs.add(ref.getName());
  198. }
  199. if (repository.showRemoteBranches) {
  200. for (RefModel ref : JGitUtils.getRemoteBranches(r, true, -1)) {
  201. refs.add(ref.getName());
  202. }
  203. }
  204. for (RefModel ref : JGitUtils.getTags(r, true, -1)) {
  205. refs.add(ref.getName());
  206. }
  207. refsForm.add(new DropDownChoice<String>("fromRef", fromRefId, refs).setEnabled(refs.size() > 0));
  208. refsForm.add(new DropDownChoice<String>("toRef", toRefId, refs).setEnabled(refs.size() > 0));
  209. add(refsForm);
  210. //
  211. // manual ids form
  212. //
  213. SessionlessForm<Void> idsForm = new SessionlessForm<Void>("compareIdsForm", getClass(), getPageParameters()) {
  214. private static final long serialVersionUID = 1L;
  215. @Override
  216. public void onSubmit() {
  217. String from = ComparePage.this.fromCommitId.getObject();
  218. String to = ComparePage.this.toCommitId.getObject();
  219. PageParameters params = WicketUtils.newRangeParameter(repositoryName, from, to);
  220. String relativeUrl = urlFor(ComparePage.class, params).toString();
  221. String absoluteUrl = RequestUtils.toAbsolutePath(relativeUrl);
  222. getRequestCycle().setRequestTarget(new RedirectRequestTarget(absoluteUrl));
  223. }
  224. };
  225. TextField<String> fromIdField = new TextField<String>("fromId", fromCommitId);
  226. WicketUtils.setInputPlaceholder(fromIdField, getString("gb.from") + "...");
  227. idsForm.add(fromIdField);
  228. TextField<String> toIdField = new TextField<String>("toId", toCommitId);
  229. WicketUtils.setInputPlaceholder(toIdField, getString("gb.to") + "...");
  230. idsForm.add(toIdField);
  231. add(idsForm);
  232. r.close();
  233. }
  234. @Override
  235. protected String getPageName() {
  236. return getString("gb.compare");
  237. }
  238. @Override
  239. protected Class<? extends BasePage> getRepoNavPageClass() {
  240. return ComparePage.class;
  241. }
  242. private RevCommit getCommit(Repository r, String rev)
  243. {
  244. RevCommit otherCommit = JGitUtils.getCommit(r, rev);
  245. if (otherCommit == null) {
  246. error(MessageFormat.format(getString("gb.failedToFindCommit"), rev, repositoryName, getPageName()), true);
  247. }
  248. return otherCommit;
  249. }
  250. }