/******************************************************************************* * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com> * Copyright (C) 2007, Jing Xue <jingxue@digizenstudio.com> * Copyright (C) 2007, Robin Rosenberg <me@lathund.dewire.com> * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com> * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com> * Copyright (C) 2011, Jens Baumgart <jens.baumgart@sap.com> * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package org.eclipse.egit.ui.internal.commit; import java.io.IOException; import org.eclipse.egit.ui.Activator; import org.eclipse.egit.ui.internal.UIText; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryState; import org.eclipse.jgit.lib.UserConfig; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Text; /** * Helper class for preparing a commit in EGit UI * */ public class CommitHelper { private Repository repository; boolean canCommit; String cannotCommitMessage; private RevCommit previousCommit; String author; String committer; boolean isMergedResolved; boolean isCherryPickResolved; private String commitMessage; /** * @param repository */ public CommitHelper(Repository repository) { this.repository = repository; calculateCommitInfo(); } private void calculateCommitInfo() { Repository mergeRepository = null; isMergedResolved = false; isCherryPickResolved = false; RepositoryState state = repository.getRepositoryState(); canCommit = state.canCommit(); if (!canCommit) { cannotCommitMessage = NLS.bind(UIText.CommitAction_repositoryState, state.getDescription()); return; } if (state.equals(RepositoryState.MERGING_RESOLVED)) { isMergedResolved = true; mergeRepository = repository; } else if (state.equals(RepositoryState.CHERRY_PICKING_RESOLVED)) { isCherryPickResolved = true; mergeRepository = repository; } previousCommit = getHeadCommit(repository); final UserConfig config = repository.getConfig().get(UserConfig.KEY); author = config.getAuthorName(); final String authorEmail = config.getAuthorEmail(); author = author + " <" + authorEmail + ">"; //$NON-NLS-1$ //$NON-NLS-2$ committer = config.getCommitterName(); final String committerEmail = config.getCommitterEmail(); committer = committer + " <" + committerEmail + ">"; //$NON-NLS-1$ //$NON-NLS-2$ if (isMergedResolved || isCherryPickResolved) { commitMessage = getMergeResolveMessage(mergeRepository); } if (isCherryPickResolved) { author = getCherryPickOriginalAuthor(mergeRepository); } } private static RevCommit getHeadCommit(Repository repository) { if (repository == null) { return null; } RevCommit headCommit = null; try (RevWalk rw = new RevWalk(repository)) { ObjectId parentId = repository.resolve(Constants.HEAD); if (parentId != null) headCommit = rw.parseCommit(parentId); } catch (IOException e) { Activator.handleError(UIText.CommitAction_errorRetrievingCommit, e, true); } return headCommit; } private String getMergeResolveMessage(Repository mergeRepository) { try { String message = mergeRepository.readMergeCommitMsg(); if (message != null) return message; } catch (IOException e) { // Return "Could not find ..." below } return NLS.bind(UIText.CommitHelper_couldNotFindMergeMsg, Constants.MERGE_MSG); } private static String getCherryPickOriginalAuthor(Repository mergeRepository) { try (RevWalk rw = new RevWalk(mergeRepository)) { ObjectId cherryPickHead = mergeRepository.readCherryPickHead(); PersonIdent author = rw.parseCommit( cherryPickHead).getAuthorIdent(); return author.getName() + " <" + author.getEmailAddress() + ">"; //$NON-NLS-1$//$NON-NLS-2$ } catch (IOException e) { Activator.handleError(UIText.CommitAction_errorRetrievingCommit, e, true); throw new IllegalStateException(e); } } /** * @return true if committing is possible */ public boolean canCommit() { return canCommit; } /** * @return error message if committing is not possible */ public String getCannotCommitMessage() { return cannotCommitMessage; } /** * @return author */ public String getAuthor() { return author; } /** * @return committer */ public String getCommitter() { return committer; } /** * @return commit message */ public String getCommitMessage() { return commitMessage; } /** * @return isMergedResolved */ public boolean isMergedResolved() { return isMergedResolved; } /** * @return isCherryPickResolved */ public boolean isCherryPickResolved() { return isCherryPickResolved; } /** * @return previous commit */ public RevCommit getPreviousCommit() { return previousCommit; } /** * @return true if amending is allowed */ public boolean amendAllowed() { return previousCommit != null && repository.getRepositoryState().canAmend(); } /** * @param repository * to check * @return true if an empty commit without files is allowed in the * current state */ public static boolean isCommitWithoutFilesAllowed(Repository repository) { RepositoryState state = repository.getRepositoryState(); return state == RepositoryState.MERGING_RESOLVED; } /** * @param repository * @return info related to the HEAD commit */ public static CommitInfo getHeadCommitInfo(Repository repository) { RevCommit headCommit = getHeadCommit(repository); if (headCommit == null) return null; String commitMessage = headCommit.getFullMessage().replaceAll( "\n", Text.DELIMITER); //$NON-NLS-1$ PersonIdent authorIdent = headCommit.getAuthorIdent(); String author = authorIdent.getName() + " <" + authorIdent.getEmailAddress() + ">"; //$NON-NLS-1$ //$NON-NLS-2$ PersonIdent committerIdent = headCommit.getCommitterIdent(); String committer = committerIdent.getName() + " <" + committerIdent.getEmailAddress() + ">"; //$NON-NLS-1$ //$NON-NLS-2$ return new CommitInfo(headCommit, author, committer, commitMessage); } /** * Commit Info * */ public static class CommitInfo { private RevCommit commit; private String author; private String committer; private String commitMessage; /** * @param commit * @param author * @param committer * @param commitMessage */ public CommitInfo(RevCommit commit, String author, String committer, String commitMessage) { super(); this.commit = commit; this.author = author; this.committer = committer; this.commitMessage = commitMessage; } /** * @return commit */ public RevCommit getCommit() { return commit; } /** * @return author */ public String getAuthor() { return author; } /** * @return committer */ public String getCommitter() { return committer; } /** * @return commit message */ public String getCommitMessage() { return commitMessage; } } }