import com.gitblit.utils.JGitUtils.MergeStatus;\r
import com.gitblit.utils.RefLogUtils;\r
import com.gitblit.utils.StringUtils;\r
+import com.google.common.collect.Lists;\r
\r
\r
/**\r
\r
if (patchset.commits > 1) {\r
sendError("");\r
- sendError("To create a proposal ticket, please squash your commits and");\r
- sendError("provide a meaningful commit message with a short title &");\r
- sendError("an optional description/body.");\r
+ sendError("You may not create a ''{0}'' branch proposal ticket from {1} commits!",\r
+ forBranch, patchset.commits);\r
sendError("");\r
- sendError(minTitle);\r
- sendError(maxTitle);\r
+ // display an ellipsized log of the commits being pushed\r
+ RevWalk walk = getRevWalk();\r
+ walk.reset();\r
+ walk.sort(RevSort.TOPO);\r
+ int boundary = 3;\r
+ int count = 0;\r
+ try {\r
+ walk.markStart(tipCommit);\r
+ walk.markUninteresting(mergeBase);\r
+\r
+ for (;;) {\r
+\r
+ RevCommit c = walk.next();\r
+ if (c == null) {\r
+ break;\r
+ }\r
+\r
+ if (count < boundary || count >= (patchset.commits - boundary)) {\r
+\r
+ walk.parseBody(c);\r
+ sendError(" {0} {1}", c.getName().substring(0, shortCommitIdLen),\r
+ StringUtils.trimString(c.getShortMessage(), 60));\r
+\r
+ } else if (count == boundary) {\r
+\r
+ sendError(" ... more commits ...");\r
+\r
+ }\r
+\r
+ count++;\r
+ }\r
+\r
+ } catch (IOException e) {\r
+ // Should never happen, the core receive process would have\r
+ // identified the missing object earlier before we got control.\r
+ LOGGER.error("failed to get commit count", e);\r
+ } finally {\r
+ walk.release();\r
+ }\r
+\r
+ sendError("");\r
+ sendError("Possible Solutions:");\r
+ sendError("");\r
+ int solution = 1;\r
+ String forSpec = cmd.getRefName().substring(Constants.R_FOR.length());\r
+ if (forSpec.equals("default") || forSpec.equals("new")) {\r
+ try {\r
+ // determine other possible integration targets\r
+ List<String> bases = Lists.newArrayList();\r
+ for (Ref ref : getRepository().getRefDatabase().getRefs(Constants.R_HEADS).values()) {\r
+ if (!ref.getName().startsWith(Constants.R_TICKET)\r
+ && !ref.getName().equals(forBranchRef.getName())) {\r
+ if (JGitUtils.isMergedInto(getRepository(), ref.getObjectId(), tipCommit)) {\r
+ bases.add(Repository.shortenRefName(ref.getName()));\r
+ }\r
+ }\r
+ }\r
+\r
+ if (!bases.isEmpty()) {\r
+\r
+ if (bases.size() == 1) {\r
+ // suggest possible integration targets\r
+ String base = bases.get(0);\r
+ sendError("{0}. Propose this change for the ''{1}'' branch.", solution++, base);\r
+ sendError("");\r
+ sendError(" git push origin HEAD:refs/for/{0}", base);\r
+ sendError(" pt propose {0}", base);\r
+ sendError("");\r
+ } else {\r
+ // suggest possible integration targets\r
+ sendError("{0}. Propose this change for a different branch.", solution++);\r
+ sendError("");\r
+ for (String base : bases) {\r
+ sendError(" git push origin HEAD:refs/for/{0}", base);\r
+ sendError(" pt propose {0}", base);\r
+ sendError("");\r
+ }\r
+ }\r
+\r
+ }\r
+ } catch (IOException e) {\r
+ LOGGER.error(null, e);\r
+ }\r
+ }\r
+ sendError("{0}. Squash your changes into a single commit with a meaningful message.", solution++);\r
+ sendError("");\r
+ sendError("{0}. Open a ticket for your changes and then push your {1} commits to the ticket.",\r
+ solution++, patchset.commits);\r
+ sendError("");\r
+ sendError(" git push origin HEAD:refs/for/{id}");\r
+ sendError(" pt propose {id}");\r
sendError("");\r
- sendRejection(cmd, "please squash to one commit");\r
+ sendRejection(cmd, "too many commits");\r
return null;\r
}\r
\r