private String createChangeSetLabel(GitModelCommit commit) { String format = store.getString(UIPreferences.SYNC_VIEW_CHANGESET_LABEL_FORMAT); RevCommit baseCommit = commit.getBaseCommit(); Map<String, String> bindings = new HashMap<String, String>(); bindings.put(BINDING_CHANGESET_DATE, DATE_FORMAT.format(baseCommit.getAuthorIdent().getWhen())); bindings.put(BINDING_CHANGESET_AUTHOR, baseCommit.getAuthorIdent().getName()); bindings.put(BINDING_CHANGESET_COMMITTER, baseCommit.getCommitterIdent().getName()); bindings.put(BINDING_CHANGESET_SHORT_MESSAGE, baseCommit.getShortMessage()); return formatName(format, bindings); }
public CommitHeaderPanel(String id, String repositoryName, RevCommit c) { super(id); add( new LinkPanel( "shortmessage", "title", c.getShortMessage(), CommitPage.class, WicketUtils.newObjectParameter(repositoryName, c.getName()))); add(new Label("commitid", "(" + c.getName().substring(0, 8) + ")")); add(new Label("author", c.getAuthorIdent().getName())); add(WicketUtils.createDateLabel("date", c.getAuthorIdent().getWhen(), getTimeZone())); }
@Test public void testSomeCommits() throws NoHeadException, NoMessageException, UnmergedPathException, ConcurrentRefUpdateException, JGitInternalException, WrongRepositoryStateException { // do 4 commits Git git = new Git(db); git.commit().setMessage("initial commit").call(); git.commit().setMessage("second commit").setCommitter(committer).call(); git.commit().setMessage("third commit").setAuthor(author).call(); git.commit().setMessage("fourth commit").setAuthor(author).setCommitter(committer).call(); Iterable<RevCommit> commits = git.log().call(); // check that all commits came in correctly PersonIdent defaultCommitter = new PersonIdent(db); PersonIdent expectedAuthors[] = new PersonIdent[] {defaultCommitter, committer, author, author}; PersonIdent expectedCommitters[] = new PersonIdent[] {defaultCommitter, committer, defaultCommitter, committer}; String expectedMessages[] = new String[] {"initial commit", "second commit", "third commit", "fourth commit"}; int l = expectedAuthors.length - 1; for (RevCommit c : commits) { assertEquals(expectedAuthors[l].getName(), c.getAuthorIdent().getName()); assertEquals(expectedCommitters[l].getName(), c.getCommitterIdent().getName()); assertEquals(c.getFullMessage(), expectedMessages[l]); l--; } assertEquals(l, -1); }
@Test public void testCommitRange() throws NoHeadException, NoMessageException, UnmergedPathException, ConcurrentRefUpdateException, JGitInternalException, WrongRepositoryStateException, IncorrectObjectTypeException, MissingObjectException { // do 4 commits and set the range to the second and fourth one Git git = new Git(db); git.commit().setMessage("first commit").call(); RevCommit second = git.commit().setMessage("second commit").setCommitter(committer).call(); git.commit().setMessage("third commit").setAuthor(author).call(); RevCommit last = git.commit().setMessage("fourth commit").setAuthor(author).setCommitter(committer).call(); Iterable<RevCommit> commits = git.log().addRange(second.getId(), last.getId()).call(); // check that we have the third and fourth commit PersonIdent defaultCommitter = new PersonIdent(db); PersonIdent expectedAuthors[] = new PersonIdent[] {author, author}; PersonIdent expectedCommitters[] = new PersonIdent[] {defaultCommitter, committer}; String expectedMessages[] = new String[] {"third commit", "fourth commit"}; int l = expectedAuthors.length - 1; for (RevCommit c : commits) { assertEquals(expectedAuthors[l].getName(), c.getAuthorIdent().getName()); assertEquals(expectedCommitters[l].getName(), c.getCommitterIdent().getName()); assertEquals(c.getFullMessage(), expectedMessages[l]); l--; } assertEquals(l, -1); }
private PersonIdent authorOf(final RevCommit c) { if (lastCommit != c) { lastCommit = c; lastAuthor = c.getAuthorIdent(); } return lastAuthor; }
@Override public PageData getRevisionData(FileSystemPage page, String label) { // Workaround for CachingPage if (label == null) { return persistence.getRevisionData(page, null); } String content, propertiesXml; RevCommit revCommit; Repository repository = getRepository(page); try { String fileSystemPath = getPath(page, repository); ObjectId rev = repository.resolve(label); RevWalk walk = new RevWalk(repository); revCommit = walk.parseCommit(rev); content = getRepositoryContent(repository, revCommit, fileSystemPath + "/" + contentFilename); propertiesXml = getRepositoryContent(repository, revCommit, fileSystemPath + "/" + propertiesFilename); } catch (IOException e) { throw new RuntimeException("Unable to get data for revision " + label, e); } final PageData pageData = new PageData(page); pageData.setContent(content); pageData.setProperties( parsePropertiesXml(propertiesXml, revCommit.getAuthorIdent().getWhen().getTime())); return pageData; }
public CodeReviewCommit createCherryPickFromCommit( Repository repo, ObjectInserter inserter, RevCommit mergeTip, RevCommit originalCommit, PersonIdent cherryPickCommitterIdent, String commitMsg, CodeReviewRevWalk rw) throws MissingObjectException, IncorrectObjectTypeException, IOException, MergeIdenticalTreeException, MergeConflictException { final ThreeWayMerger m = newThreeWayMerger(repo, inserter); m.setBase(originalCommit.getParent(0)); if (m.merge(mergeTip, originalCommit)) { ObjectId tree = m.getResultTreeId(); if (tree.equals(mergeTip.getTree())) { throw new MergeIdenticalTreeException("identical tree"); } CommitBuilder mergeCommit = new CommitBuilder(); mergeCommit.setTreeId(tree); mergeCommit.setParentId(mergeTip); mergeCommit.setAuthor(originalCommit.getAuthorIdent()); mergeCommit.setCommitter(cherryPickCommitterIdent); mergeCommit.setMessage(commitMsg); return rw.parseCommit(commit(inserter, mergeCommit)); } else { throw new MergeConflictException("merge conflict"); } }
@Override public List<CommitDB> getCommits() { try { Iterable<RevCommit> revCommits; revCommits = git.log().all().call(); List<CommitDB> commits = new ArrayList<CommitDB>(); for (RevCommit revCommit : revCommits) { PersonIdent author = revCommit.getAuthorIdent(); CommitDB commit = new CommitDB(0, author.getWhen(), revCommit.getFullMessage(), revCommit.getName()); CommitterDB committerDb = new CommitterDB(0, author.getEmailAddress(), author.getName()); commit.setCommitter(committerDb); commits.add(commit); } return commits; } catch (GitAPIException e) { throw new VisMinerAPIException(e.getMessage(), e); } catch (IOException e) { throw new VisMinerAPIException(e.getMessage(), e); } }
@Override public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException { try { String localPath = args[0].getStringValue(); if (!(localPath.endsWith("/"))) localPath += File.separator; // Repository localRepo = new FileRepository(localPath + ".git"); // Git git = new Git(localRepo); Git git = Git.open(new Resource(localPath), FS); MemTreeBuilder builder = context.getDocumentBuilder(); AttributesImpl attribs = new AttributesImpl(); attribs.addAttribute(NAMESPACE_URI, "local-path", PREFIX + ":local-path", "CDATA", localPath); int nodeNr = builder.startElement(LOG_ELEMENT, attribs); for (RevCommit commit : git.log().call()) { // commit.getParentCount(); // commit.getParents(); attribs = new AttributesImpl(); attribs.addAttribute(NAMESPACE_URI, "id", PREFIX + ":id", "CDATA", commit.name()); attribs.addAttribute( NAMESPACE_URI, "time", PREFIX + ":time", "CDATA", String.valueOf(commit.getCommitTime())); builder.startElement(COMMIT_ELEMENT, attribs); PersonIdent authorIdent = commit.getAuthorIdent(); builder.startElement(AUTHOR_ELEMENT, null); builder.startElement(AUTHOR_NAME_ELEMENT, null); builder.characters(authorIdent.getName()); builder.endElement(); builder.startElement(AUTHOR_EMAIL_ELEMENT, null); builder.characters(authorIdent.getEmailAddress()); builder.endElement(); builder.endElement(); builder.startElement(MESSAGE_ELEMENT, null); builder.characters(commit.getFullMessage()); builder.endElement(); builder.endElement(); } builder.endElement(); return builder.getDocument().getNode(nodeNr); } catch (Throwable e) { throw new XPathException(this, Module.EXGIT001, e); } }
private GitVersionInfo makeVersionInfo(RevCommit revCommit) { PersonIdent authorIdent = revCommit.getAuthorIdent(); return new GitVersionInfo( revCommit.name(), authorIdent.getName(), authorIdent.getWhen(), revCommit.getShortMessage()); }
private Revision asRevision(final RevCommit commit) { final PersonIdent author = commit.getAuthorIdent(); return new RevisionImpl( commit.name(), author.getName(), author.getEmailAddress(), author.getWhen(), commit.getFullMessage()); }
@Override public List<CommitInfo> log( String objectId, final String path, int limit, int pageOffset, boolean showRemoteRefs, int itemsPerPage) { try { if (itemsPerPage <= 1) { itemsPerPage = 50; } boolean pageResults = limit <= 0; Repository r = git.getRepository(); // TODO not sure if this is the right String we should use for the sub module stuff... String repositoryName = getConfigDirectory().getPath(); objectId = defaultObjectId(objectId); final Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(r, showRemoteRefs); List<RevCommit> commits; if (pageResults) { // Paging result set commits = JGitUtils.getRevLog(r, objectId, pageOffset * itemsPerPage, itemsPerPage); } else { // Fixed size result set commits = JGitUtils.getRevLog(r, objectId, 0, limit); } List<CommitInfo> answer = new ArrayList<CommitInfo>(); for (RevCommit entry : commits) { final Date date = JGitUtils.getCommitDate(entry); String author = entry.getAuthorIdent().getName(); boolean merge = entry.getParentCount() > 1; // short message String shortMessage = entry.getShortMessage(); String trimmedMessage = shortMessage; if (allRefs.containsKey(entry.getId())) { trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG_REFS); } else { trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG); } String name = entry.getName(); String commitHash = getShortCommitHash(name); answer.add( new CommitInfo( commitHash, name, "log", author, date, merge, trimmedMessage, shortMessage)); } return answer; } catch (Exception e) { throw new RuntimeIOException(e); } }
public PatchSetInfo get(RevWalk rw, RevCommit src, PatchSet.Id psi) throws IOException { rw.parseBody(src); PatchSetInfo info = new PatchSetInfo(psi); info.setSubject(src.getShortMessage()); info.setMessage(src.getFullMessage()); info.setAuthor(toUserIdentity(src.getAuthorIdent())); info.setCommitter(toUserIdentity(src.getCommitterIdent())); info.setRevId(src.getName()); return info; }
public CommitInfo createCommitInfo(RevCommit entry) { final Date date = GitFacade.getCommitDate(entry); String author = entry.getAuthorIdent().getName(); boolean merge = entry.getParentCount() > 1; String shortMessage = entry.getShortMessage(); String trimmedMessage = Strings.trimString(shortMessage, 78); String name = entry.getName(); String commitHashText = getShortCommitHash(name); return new CommitInfo(commitHashText, name, author, date, merge, trimmedMessage, shortMessage); }
@Test public void testCommit() throws Exception { try (Git git = new Git(db)) { revCommit = git.commit().setMessage("squash_me").call(); Ref master = db.exactRef("refs/heads/master"); String message = msgFormatter.format(Arrays.asList(revCommit), master); assertEquals( "Squashed commit of the following:\n\ncommit " + revCommit.getName() + "\nAuthor: " + revCommit.getAuthorIdent().getName() + " <" + revCommit.getAuthorIdent().getEmailAddress() + ">\nDate: " + dateFormatter.formatDate(author) + "\n\n\tsquash_me\n", message); } }
@Override public Date getLastCommitDate(String treeName) { try { RevCommit lastCommit = revWalk.parseCommit(repository.resolve(treeName)); return lastCommit.getAuthorIdent().getWhen(); } catch (IOException e) { throw new VisMinerAPIException(e.getMessage(), e); } }
@Test public void submitWithFastForward() throws Exception { RevCommit oldHead = getRemoteHead(); PushOneCommit.Result change = createChange(); submit(change.getChangeId()); RevCommit head = getRemoteHead(); assertThat(head.getId()).isEqualTo(change.getCommitId()); assertThat(head.getParent(0)).isEqualTo(oldHead); assertSubmitter(change.getChangeId(), 1); assertPersonEquals(admin.getIdent(), head.getAuthorIdent()); assertPersonEquals(admin.getIdent(), head.getCommitterIdent()); }
private Git.Head getHead(final Repository repository) throws IOException { ObjectId revision = repository.resolve(Constants.HEAD); RevCommit commit = new RevWalk(repository).parseCommit(revision); Git.Head head = new Git.Head( revision.getName(), commit.getAuthorIdent().getName(), commit.getAuthorIdent().getEmailAddress(), commit.getCommitterIdent().getName(), commit.getCommitterIdent().getEmailAddress(), commit.getFullMessage()); return head; }
private void createHeaderArea(Composite parent, FormToolkit toolkit, int span) { RevCommit commit = getCommit().getRevCommit(); Composite top = toolkit.createComposite(parent); GridDataFactory.fillDefaults().grab(true, false).span(span, 1).applyTo(top); GridLayoutFactory.fillDefaults().numColumns(2).applyTo(top); Composite userArea = toolkit.createComposite(top); GridLayoutFactory.fillDefaults().spacing(2, 2).numColumns(1).applyTo(userArea); GridDataFactory.fillDefaults().grab(true, false).applyTo(userArea); PersonIdent author = commit.getAuthorIdent(); if (author != null) createUserArea(userArea, toolkit, author, true); PersonIdent committer = commit.getCommitterIdent(); if (committer != null && !committer.equals(author)) createUserArea(userArea, toolkit, committer, false); int count = commit.getParentCount(); if (count > 0) { Composite parents = toolkit.createComposite(top); GridLayoutFactory.fillDefaults().spacing(2, 2).numColumns(2).applyTo(parents); GridDataFactory.fillDefaults().grab(false, false).applyTo(parents); for (int i = 0; i < count; i++) { final RevCommit parentCommit = commit.getParent(i); toolkit .createLabel(parents, UIText.CommitEditorPage_LabelParent) .setForeground(toolkit.getColors().getColor(IFormColors.TB_TOGGLE)); final Hyperlink link = toolkit.createHyperlink( parents, parentCommit.abbreviate(PARENT_LENGTH).name(), SWT.NONE); link.addHyperlinkListener( new HyperlinkAdapter() { public void linkActivated(HyperlinkEvent e) { try { CommitEditor.open( new RepositoryCommit(getCommit().getRepository(), parentCommit)); if ((e.getStateMask() & SWT.MOD1) != 0) getEditor().close(false); } catch (PartInitException e1) { Activator.logError("Error opening commit editor", e1); // $NON-NLS-1$ } } }); } } createTagsArea(userArea, toolkit, 2); }
@Test public void submitMultipleChanges() throws Exception { RevCommit initialHead = getRemoteHead(); testRepo.reset(initialHead); PushOneCommit.Result change2 = createChange("Change 2", "b", "b"); testRepo.reset(initialHead); PushOneCommit.Result change3 = createChange("Change 3", "c", "c"); testRepo.reset(initialHead); PushOneCommit.Result change4 = createChange("Change 4", "d", "d"); // Change 2 stays untouched. approve(change2.getChangeId()); // Change 3 is a fast-forward, no need to merge. submit(change3.getChangeId()); RevCommit tip = getRemoteLog().get(0); assertThat(tip.getShortMessage()).isEqualTo(change3.getCommit().getShortMessage()); assertThat(tip.getParent(0).getId()).isEqualTo(initialHead.getId()); assertPersonEquals(admin.getIdent(), tip.getAuthorIdent()); assertPersonEquals(admin.getIdent(), tip.getCommitterIdent()); // We need to merge change 4. submit(change4.getChangeId()); tip = getRemoteLog().get(0); assertThat(tip.getParent(1).getShortMessage()).isEqualTo(change4.getCommit().getShortMessage()); assertThat(tip.getParent(0).getShortMessage()).isEqualTo(change3.getCommit().getShortMessage()); assertPersonEquals(admin.getIdent(), tip.getAuthorIdent()); assertPersonEquals(serverIdent.get(), tip.getCommitterIdent()); assertNew(change2.getChangeId()); }
// format the output like in --pretty="%H<#>%aN<#>%at<#>%cN<#>%ct<#>%s private String printCommit(RevCommit c) { String out = ""; PersonIdent author = c.getAuthorIdent(); PersonIdent committer = c.getCommitterIdent(); // long commitTime = (long)c.getCommitTime() == committer.getWhen().getTime() / 1000 (in // seconds) out += "" + c.name() + GitWorks.log_sep + author.getName() + GitWorks.log_sep + author.getWhen().getTime() + GitWorks.log_sep + committer.getName() + GitWorks.log_sep + committer.getWhen().getTime() + GitWorks.log_sep + c.getShortMessage(); // c.getFullMessage(); c.getShortMessage(); return out; }
private static void lastCommit(Git git, String path, AnyObjectId revId, JSONObject jsonObject) { JSONObject latestCommitObj = new JSONObject(); JSONObject authorObj = new JSONObject(); JSONObject committerObj = new JSONObject(); Iterable<RevCommit> log = null; try { if (path != null) { log = git.log().addPath(path).setMaxCount(1).call(); } else if (revId != null) { log = git.log().add(revId).setMaxCount(1).call(); } Iterator<RevCommit> it = log.iterator(); while (it.hasNext()) { RevCommit rev = (RevCommit) it.next(); PersonIdent committer = rev.getCommitterIdent(); committerObj.put("Name", committer.getName()); committerObj.put("Email", committer.getEmailAddress()); committerObj.put("Date", committer.getWhen().toString()); PersonIdent author = rev.getAuthorIdent(); authorObj.put("Name", author.getName()); String authorEmail = author.getEmailAddress(); authorObj.put("Email", authorEmail); authorObj.put("Date", author.getWhen().toString()); latestCommitObj.put("Author", authorObj); latestCommitObj.put("Committer", committerObj); latestCommitObj.put("Message", rev.getFullMessage()); latestCommitObj.put("SHA1", rev.getId().getName()); latestCommitObj.put("AvatarURL", getImageLink(authorEmail)); jsonObject.put("LastCommit", latestCommitObj); } } catch (GitAPIException e) { } catch (MissingObjectException e) { } catch (IncorrectObjectTypeException e) { } catch (JSONException e) { } }
public List<CommitDB> getCommitsByTree(String treeName, TreeType type) { Iterable<RevCommit> revCommits = null; if (type == TreeType.BRANCH) { revCommits = getCommitsFromBranch(treeName); } else if (type == TreeType.TAG) { revCommits = getCommitsFromTag(treeName); } List<CommitDB> commits = new ArrayList<CommitDB>(); for (RevCommit revCommit : revCommits) { CommitDB commit = new CommitDB( 0, revCommit.getAuthorIdent().getWhen(), revCommit.getFullMessage(), revCommit.getName()); commits.add(commit); } return commits; }
private void createMessageArea(Composite parent, FormToolkit toolkit, int span) { Section messageSection = createSection(parent, toolkit, span); Composite messageArea = createSectionClient(messageSection, toolkit); messageSection.setText(UIText.CommitEditorPage_SectionMessage); RevCommit commit = getCommit().getRevCommit(); String message = commit.getFullMessage(); PersonIdent author = commit.getAuthorIdent(); if (author != null) message = replaceSignedOffByLine(message, author); PersonIdent committer = commit.getCommitterIdent(); if (committer != null) message = replaceSignedOffByLine(message, committer); SpellcheckableMessageArea textContent = new SpellcheckableMessageArea(messageArea, message, true, toolkit.getBorderStyle()) { @Override protected IAdaptable getDefaultTarget() { return new PlatformObject() { public Object getAdapter(Class adapter) { return Platform.getAdapterManager().getAdapter(getEditorInput(), adapter); } }; } protected void createMarginPainter() { // Disabled intentionally } }; if ((toolkit.getBorderStyle() & SWT.BORDER) == 0) textContent.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER); GridDataFactory.fillDefaults().hint(SWT.DEFAULT, 80).grab(true, true).applyTo(textContent); updateSectionClient(messageSection, messageArea, toolkit); }
protected void addInformationForPath( Repository repository, Git git, DocumentWriter writer, RevCommit commit, String path, CallSpecification spec, Values values) throws GitAPIException, IOException { // Make sure the path is in the canonical form we need ... if (path.startsWith("/")) { if (path.length() == 1) path = ""; else path = path.substring(1); } // Now see if we're actually referring to the "jcr:content" node ... boolean isContentNode = false; if (path.endsWith(JCR_CONTENT_SUFFIX)) { isContentNode = true; path = path.substring(0, path.length() - JCR_CONTENT_SUFFIX.length()); } // Create the TreeWalk that we'll use to navigate the files/directories ... final TreeWalk tw = new TreeWalk(repository); tw.addTree(commit.getTree()); if ("".equals(path)) { // This is the top-level directory, so we don't need to pre-walk to find anything ... tw.setRecursive(false); while (tw.next()) { String childName = tw.getNameString(); String childId = spec.childId(childName); writer.addChild(childId, childName); } } else { // We need to first find our path *before* we can walk the children ... PathFilter filter = PathFilter.create(path); tw.setFilter(filter); while (tw.next()) { if (filter.isDone(tw)) { break; } else if (tw.isSubtree()) { tw.enterSubtree(); } } // Now that the TreeWalk is the in right location given by the 'path', we can get the if (tw.isSubtree()) { // The object at the 'path' is a directory, so go into it ... tw.enterSubtree(); // Find the commit in which this folder was last modified ... // This may not be terribly efficient, but it seems to work faster on subsequent runs ... RevCommit folderCommit = git.log().addPath(path).call().iterator().next(); // Add folder-related properties ... String committer = folderCommit.getCommitterIdent().getName(); String author = folderCommit.getAuthorIdent().getName(); DateTime committed = values.dateFrom(folderCommit.getCommitTime()); writer.setPrimaryType(GitLexicon.FOLDER); writer.addProperty(JcrLexicon.CREATED, committed); writer.addProperty(JcrLexicon.CREATED_BY, committer); writer.addProperty(GitLexicon.OBJECT_ID, folderCommit.getId().name()); writer.addProperty(GitLexicon.AUTHOR, author); writer.addProperty(GitLexicon.COMMITTER, committer); writer.addProperty(GitLexicon.COMMITTED, committed); writer.addProperty(GitLexicon.TITLE, folderCommit.getShortMessage()); // And now walk the contents of the directory ... while (tw.next()) { String childName = tw.getNameString(); String childId = spec.childId(childName); writer.addChild(childId, childName); } } else { // The path specifies a file (or a content node) ... // Find the commit in which this folder was last modified ... // This may not be terribly efficient, but it seems to work faster on subsequent runs ... RevCommit fileCommit = git.log().addPath(path).call().iterator().next(); // Add file-related properties ... String committer = fileCommit.getCommitterIdent().getName(); String author = fileCommit.getAuthorIdent().getName(); DateTime committed = values.dateFrom(fileCommit.getCommitTime()); if (isContentNode) { writer.setPrimaryType(GitLexicon.RESOURCE); writer.addProperty(JcrLexicon.LAST_MODIFIED, committed); writer.addProperty(JcrLexicon.LAST_MODIFIED_BY, committer); writer.addProperty(GitLexicon.OBJECT_ID, fileCommit.getId().name()); writer.addProperty(GitLexicon.AUTHOR, author); writer.addProperty(GitLexicon.COMMITTER, committer); writer.addProperty(GitLexicon.COMMITTED, committed); writer.addProperty(GitLexicon.TITLE, fileCommit.getShortMessage()); // Create the BinaryValue ... ObjectId fileObjectId = tw.getObjectId(0); ObjectLoader fileLoader = repository.open(fileObjectId); BinaryKey key = new BinaryKey(fileObjectId.getName()); BinaryValue value = values.binaryFor(key, fileLoader.getSize()); if (value == null) { // It wasn't found in the binary store ... if (fileLoader.isLarge()) { // Too large to hold in memory, so use the binary store (which reads the file // immediately) ... value = values.binaryFrom(fileLoader.openStream()); } else { // This is small enough to fit into a byte[], but it still may be pretty big ... value = new GitBinaryValue( fileObjectId, fileLoader, connector.getSourceName(), name, connector.getMimeTypeDetector()); } } writer.addProperty(JcrLexicon.DATA, value); if (connector.includeMimeType()) { try { String filename = spec.parameter(spec.parameterCount() - 1); // the last is 'jcr:content' String mimeType = value.getMimeType(filename); if (mimeType != null) writer.addProperty(JcrLexicon.MIMETYPE, mimeType); } catch (RepositoryException e) { // do nothing } catch (IOException e) { // do nothing } } } else { writer.setPrimaryType(GitLexicon.FILE); writer.addProperty(JcrLexicon.CREATED, committed); writer.addProperty(JcrLexicon.CREATED_BY, committer); writer.addProperty(GitLexicon.OBJECT_ID, fileCommit.getId().name()); writer.addProperty(GitLexicon.AUTHOR, author); writer.addProperty(GitLexicon.COMMITTER, committer); writer.addProperty(GitLexicon.COMMITTED, committed); writer.addProperty(GitLexicon.TITLE, fileCommit.getShortMessage()); // Add the "jcr:content" child node ... String childId = spec.childId(JCR_CONTENT); writer.addChild(childId, JCR_CONTENT); } } } }
/** * Executes the {@code commit} command with all the options and parameters collected by the setter * methods of this class. Each instance of this class should only be used for one invocation of * the command (means: one call to {@link #call()}) * * @return a {@link RevCommit} object representing the successful commit. * @throws NoHeadException when called on a git repo without a HEAD reference * @throws NoMessageException when called without specifying a commit message * @throws UnmergedPathsException when the current index contained unmerged paths (conflicts) * @throws ConcurrentRefUpdateException when HEAD or branch ref is updated concurrently by someone * else * @throws WrongRepositoryStateException when repository is not in the right state for committing * @throws AbortedByHookException if there are either pre-commit or commit-msg hooks present in * the repository and one of them rejects the commit. */ public RevCommit call() throws GitAPIException, NoHeadException, NoMessageException, UnmergedPathsException, ConcurrentRefUpdateException, WrongRepositoryStateException, AbortedByHookException { checkCallable(); Collections.sort(only); try (RevWalk rw = new RevWalk(repo)) { RepositoryState state = repo.getRepositoryState(); if (!state.canCommit()) throw new WrongRepositoryStateException( MessageFormat.format(JGitText.get().cannotCommitOnARepoWithState, state.name())); if (!noVerify) { Hooks.preCommit(repo, hookOutRedirect).call(); } processOptions(state, rw); if (all && !repo.isBare() && repo.getWorkTree() != null) { try (Git git = new Git(repo)) { git.add() .addFilepattern(".") // $NON-NLS-1$ .setUpdate(true) .call(); } catch (NoFilepatternException e) { // should really not happen throw new JGitInternalException(e.getMessage(), e); } } Ref head = repo.getRef(Constants.HEAD); if (head == null) throw new NoHeadException(JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported); // determine the current HEAD and the commit it is referring to ObjectId headId = repo.resolve(Constants.HEAD + "^{commit}"); // $NON-NLS-1$ if (headId == null && amend) throw new WrongRepositoryStateException(JGitText.get().commitAmendOnInitialNotPossible); if (headId != null) if (amend) { RevCommit previousCommit = rw.parseCommit(headId); for (RevCommit p : previousCommit.getParents()) parents.add(p.getId()); if (author == null) author = previousCommit.getAuthorIdent(); } else { parents.add(0, headId); } if (!noVerify) { message = Hooks.commitMsg(repo, hookOutRedirect).setCommitMessage(message).call(); } // lock the index DirCache index = repo.lockDirCache(); try (ObjectInserter odi = repo.newObjectInserter()) { if (!only.isEmpty()) index = createTemporaryIndex(headId, index, rw); // Write the index as tree to the object database. This may // fail for example when the index contains unmerged paths // (unresolved conflicts) ObjectId indexTreeId = index.writeTree(odi); if (insertChangeId) insertChangeId(indexTreeId); // Create a Commit object, populate it and write it CommitBuilder commit = new CommitBuilder(); commit.setCommitter(committer); commit.setAuthor(author); commit.setMessage(message); commit.setParentIds(parents); commit.setTreeId(indexTreeId); ObjectId commitId = odi.insert(commit); odi.flush(); RevCommit revCommit = rw.parseCommit(commitId); RefUpdate ru = repo.updateRef(Constants.HEAD); ru.setNewObjectId(commitId); if (reflogComment != null) { ru.setRefLogMessage(reflogComment, false); } else { String prefix = amend ? "commit (amend): " //$NON-NLS-1$ : parents.size() == 0 ? "commit (initial): " //$NON-NLS-1$ : "commit: "; //$NON-NLS-1$ ru.setRefLogMessage(prefix + revCommit.getShortMessage(), false); } if (headId != null) ru.setExpectedOldObjectId(headId); else ru.setExpectedOldObjectId(ObjectId.zeroId()); Result rc = ru.forceUpdate(); switch (rc) { case NEW: case FORCED: case FAST_FORWARD: { setCallable(false); if (state == RepositoryState.MERGING_RESOLVED || isMergeDuringRebase(state)) { // Commit was successful. Now delete the files // used for merge commits repo.writeMergeCommitMsg(null); repo.writeMergeHeads(null); } else if (state == RepositoryState.CHERRY_PICKING_RESOLVED) { repo.writeMergeCommitMsg(null); repo.writeCherryPickHead(null); } else if (state == RepositoryState.REVERTING_RESOLVED) { repo.writeMergeCommitMsg(null); repo.writeRevertHead(null); } return revCommit; } case REJECTED: case LOCK_FAILURE: throw new ConcurrentRefUpdateException( JGitText.get().couldNotLockHEAD, ru.getRef(), rc); default: throw new JGitInternalException( MessageFormat.format( JGitText.get().updatingRefFailed, Constants.HEAD, commitId.toString(), rc)); } } finally { index.unlock(); } } catch (UnmergedPathException e) { throw new UnmergedPathsException(e); } catch (IOException e) { throw new JGitInternalException( JGitText.get().exceptionCaughtDuringExecutionOfCommitCommand, e); } }
/** * Update the submodules in one branch of one repository. * * @param subscriber the branch of the repository which should be changed. * @param updates submodule updates which should be updated to. * @throws SubmoduleException */ private void updateGitlinks( ReviewDb db, Branch.NameKey subscriber, Collection<SubmoduleSubscription> updates) throws SubmoduleException { PersonIdent author = null; Repository pdb = null; RevWalk recRw = null; StringBuilder msgbuf = new StringBuilder("Updated git submodules\n\n"); try { boolean sameAuthorForAll = true; pdb = repoManager.openRepository(subscriber.getParentKey()); if (pdb.getRef(subscriber.get()) == null) { throw new SubmoduleException( "The branch was probably deleted from the subscriber repository"); } DirCache dc = readTree(pdb, pdb.getRef(subscriber.get())); DirCacheEditor ed = dc.editor(); for (SubmoduleSubscription s : updates) { try (Repository subrepo = repoManager.openRepository(s.getSubmodule().getParentKey()); RevWalk rw = CodeReviewCommit.newRevWalk(subrepo)) { Ref ref = subrepo.getRefDatabase().exactRef(s.getSubmodule().get()); if (ref == null) { ed.add(new DeletePath(s.getPath())); continue; } final ObjectId updateTo = ref.getObjectId(); RevCommit newCommit = rw.parseCommit(updateTo); if (author == null) { author = newCommit.getAuthorIdent(); } else if (!author.equals(newCommit.getAuthorIdent())) { sameAuthorForAll = false; } DirCacheEntry dce = dc.getEntry(s.getPath()); ObjectId oldId = null; if (dce != null) { if (!dce.getFileMode().equals(FileMode.GITLINK)) { log.error( "Requested to update gitlink " + s.getPath() + " in " + s.getSubmodule().getParentKey().get() + " but entry " + "doesn't have gitlink file mode."); continue; } oldId = dce.getObjectId(); } else { // This submodule did not exist before. We do not want to add // the full submodule history to the commit message, so omit it. oldId = updateTo; } ed.add( new PathEdit(s.getPath()) { @Override public void apply(DirCacheEntry ent) { ent.setFileMode(FileMode.GITLINK); ent.setObjectId(updateTo); } }); if (verboseSuperProject) { msgbuf.append("Project: " + s.getSubmodule().getParentKey().get()); msgbuf.append(" " + s.getSubmodule().getShortName()); msgbuf.append(" " + updateTo.getName()); msgbuf.append("\n\n"); try { rw.markStart(newCommit); if (oldId != null) { rw.markUninteresting(rw.parseCommit(oldId)); } for (RevCommit c : rw) { msgbuf.append(c.getFullMessage() + "\n\n"); } } catch (IOException e) { logAndThrowSubmoduleException( "Could not perform a revwalk to " + "create superproject commit message", e); } } } } ed.finish(); if (!sameAuthorForAll || author == null) { author = myIdent; } ObjectInserter oi = pdb.newObjectInserter(); ObjectId tree = dc.writeTree(oi); ObjectId currentCommitId = pdb.getRef(subscriber.get()).getObjectId(); CommitBuilder commit = new CommitBuilder(); commit.setTreeId(tree); commit.setParentIds(new ObjectId[] {currentCommitId}); commit.setAuthor(author); commit.setCommitter(myIdent); commit.setMessage(msgbuf.toString()); oi.insert(commit); oi.flush(); ObjectId commitId = oi.idFor(Constants.OBJ_COMMIT, commit.build()); final RefUpdate rfu = pdb.updateRef(subscriber.get()); rfu.setForceUpdate(false); rfu.setNewObjectId(commitId); rfu.setExpectedOldObjectId(currentCommitId); rfu.setRefLogMessage("Submit to " + subscriber.getParentKey().get(), true); switch (rfu.update()) { case NEW: case FAST_FORWARD: gitRefUpdated.fire(subscriber.getParentKey(), rfu); changeHooks.doRefUpdatedHook(subscriber, rfu, account); // TODO since this is performed "in the background" no mail will be // sent to inform users about the updated branch break; default: throw new IOException(rfu.getResult().name()); } recRw = new RevWalk(pdb); // Recursive call: update subscribers of the subscriber updateSuperProjects(db, Sets.newHashSet(subscriber)); } catch (IOException e) { throw new SubmoduleException("Cannot update gitlinks for " + subscriber.get(), e); } finally { if (recRw != null) { recRw.close(); } if (pdb != null) { pdb.close(); } } }
@Override public List<CommitInfo> history( String objectId, String path, int limit, int pageOffset, boolean showRemoteRefs, int itemsPerPage) { try { if (itemsPerPage <= 1) { itemsPerPage = 50; } boolean pageResults = limit <= 0; Repository r = git.getRepository(); // TODO not sure if this is the right String we should use for the sub module stuff... String repositoryName = getConfigDirectory().getPath(); objectId = defaultObjectId(objectId); RevCommit commit = JGitUtils.getCommit(r, objectId); List<PathModel.PathChangeModel> paths = JGitUtils.getFilesInCommit(r, commit); Map<String, SubmoduleModel> submodules = new HashMap<String, SubmoduleModel>(); for (SubmoduleModel model : JGitUtils.getSubmodules(r, commit.getTree())) { submodules.put(model.path, model); } PathModel matchingPath = null; for (PathModel p : paths) { if (p.path.equals(path)) { matchingPath = p; break; } } if (matchingPath == null) { // path not in commit // manually locate path in tree TreeWalk tw = new TreeWalk(r); tw.reset(); tw.setRecursive(true); try { tw.addTree(commit.getTree()); tw.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path))); while (tw.next()) { if (tw.getPathString().equals(path)) { matchingPath = new PathModel.PathChangeModel( tw.getPathString(), tw.getPathString(), 0, tw.getRawMode(0), tw.getObjectId(0).getName(), commit.getId().getName(), ChangeType.MODIFY); } } } catch (Exception e) { } finally { tw.release(); } } final boolean isTree = matchingPath == null ? true : matchingPath.isTree(); final boolean isSubmodule = matchingPath == null ? true : matchingPath.isSubmodule(); // submodule SubmoduleModel submodule = null; if (matchingPath != null) { submodule = getSubmodule(submodules, repositoryName, matchingPath.path); } final String submodulePath; final boolean hasSubmodule; if (submodule != null) { submodulePath = submodule.gitblitPath; hasSubmodule = submodule.hasSubmodule; } else { submodulePath = ""; hasSubmodule = false; } final Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(r, showRemoteRefs); List<RevCommit> commits; if (pageResults) { // Paging result set commits = JGitUtils.getRevLog(r, objectId, path, pageOffset * itemsPerPage, itemsPerPage); } else { // Fixed size result set commits = JGitUtils.getRevLog(r, objectId, path, 0, limit); } // inaccurate way to determine if there are more commits. // works unless commits.size() represents the exact end. boolean hasMore = commits.size() >= itemsPerPage; List<CommitInfo> results = new ArrayList<CommitInfo>(); for (RevCommit entry : commits) { final Date date = JGitUtils.getCommitDate(entry); String author = entry.getAuthorIdent().getName(); boolean merge = entry.getParentCount() > 1; String shortMessage = entry.getShortMessage(); String trimmedMessage = shortMessage; if (allRefs.containsKey(entry.getId())) { trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG_REFS); } else { trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG); } String name = entry.getName(); String commitHashText = getShortCommitHash(name); String kind; if (isTree) { kind = "tree"; } else if (isSubmodule) { kind = "submodule"; } else kind = "file"; results.add( new CommitInfo( commitHashText, name, kind, author, date, merge, trimmedMessage, shortMessage)); } return results; } catch (Exception e) { throw new RuntimeIOException(e); } }
@Override public Document execute( Repository repository, Git git, CallSpecification spec, DocumentWriter writer, Values values) throws GitAPIException, IOException { if (spec.parameterCount() == 0) { // This is the top-level "/branches" node writer.setPrimaryType(GitLexicon.TREES); // Generate the child references to the branches and tags. Branches are likely used more // often, so list them first... addBranchesAsChildren(git, spec, writer); addTagsAsChildren(git, spec, writer); addCommitsAsChildren(git, spec, writer, pageSize); } else if (spec.parameterCount() == 1) { // This is a particular branch/tag/commit node ... String branchOrTagOrObjectId = spec.parameter(0); ObjectId objId = resolveBranchOrTagOrCommitId(repository, branchOrTagOrObjectId); RevWalk walker = new RevWalk(repository); walker.setRetainBody(true); // we need to parse the commit for the top-level try { RevCommit commit = walker.parseCommit(objId); // Add the properties for this node ... String committer = commit.getCommitterIdent().getName(); String author = commit.getAuthorIdent().getName(); DateTime committed = values.dateFrom(commit.getCommitTime()); writer.setPrimaryType(GitLexicon.FOLDER); writer.addProperty(JcrLexicon.CREATED, committed); writer.addProperty(JcrLexicon.CREATED_BY, committer); writer.addProperty(GitLexicon.OBJECT_ID, objId.name()); writer.addProperty(GitLexicon.AUTHOR, author); writer.addProperty(GitLexicon.COMMITTER, committer); writer.addProperty(GitLexicon.COMMITTED, committed); writer.addProperty(GitLexicon.TITLE, commit.getShortMessage()); writer.addProperty( GitLexicon.HISTORY, GitHistory.referenceToHistory(objId, branchOrTagOrObjectId, values)); writer.addProperty(GitLexicon.DETAIL, GitCommitDetails.referenceToCommit(objId, values)); // Add the top-level children of the directory ... addInformationForPath(repository, git, writer, commit, "", spec, values); } finally { walker.dispose(); } } else { // This is a folder or file within the directory structure ... String branchOrTagOrObjectId = spec.parameter(0); String path = spec.parametersAsPath(1); ObjectId objId = resolveBranchOrTagOrCommitId(repository, branchOrTagOrObjectId); RevWalk walker = new RevWalk(repository); walker.setRetainBody(false); // we don't need top-level commit information try { // Get the commit information ... RevCommit commit = walker.parseCommit(objId); // Add the top-level children of the directory ... addInformationForPath(repository, git, writer, commit, path, spec, values); } finally { walker.dispose(); } } return writer.document(); }