CommitMsgHook.java

  1. /*
  2.  * Copyright (C) 2015 Obeo. and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */
  10. package org.eclipse.jgit.hooks;

  11. import java.io.File;
  12. import java.io.IOException;
  13. import java.io.PrintStream;

  14. import org.eclipse.jgit.api.errors.AbortedByHookException;
  15. import org.eclipse.jgit.lib.Constants;
  16. import org.eclipse.jgit.lib.Repository;

  17. /**
  18.  * The <code>commit-msg</code> hook implementation. This hook is run before the
  19.  * commit and can reject the commit. It passes one argument to the hook script,
  20.  * which is the path to the COMMIT_MSG file, relative to the repository
  21.  * workTree.
  22.  *
  23.  * @since 4.0
  24.  */
  25. public class CommitMsgHook extends GitHook<String> {

  26.     /**
  27.      * Constant indicating the name of the commit-smg hook.
  28.      */
  29.     public static final String NAME = "commit-msg"; //$NON-NLS-1$

  30.     /**
  31.      * The commit message.
  32.      */
  33.     private String commitMessage;

  34.     /**
  35.      * Constructor for CommitMsgHook
  36.      * <p>
  37.      * This constructor will use the default error stream.
  38.      * </p>
  39.      *
  40.      * @param repo
  41.      *            The repository
  42.      * @param outputStream
  43.      *            The output stream the hook must use. {@code null} is allowed,
  44.      *            in which case the hook will use {@code System.out}.
  45.      */
  46.     protected CommitMsgHook(Repository repo, PrintStream outputStream) {
  47.         super(repo, outputStream);
  48.     }

  49.     /**
  50.      * Constructor for CommitMsgHook
  51.      *
  52.      * @param repo
  53.      *            The repository
  54.      * @param outputStream
  55.      *            The output stream the hook must use. {@code null} is allowed,
  56.      *            in which case the hook will use {@code System.out}.
  57.      * @param errorStream
  58.      *            The error stream the hook must use. {@code null} is allowed,
  59.      *            in which case the hook will use {@code System.err}.
  60.      * @since 5.6
  61.      */
  62.     protected CommitMsgHook(Repository repo, PrintStream outputStream,
  63.             PrintStream errorStream) {
  64.         super(repo, outputStream, errorStream);
  65.     }

  66.     /** {@inheritDoc} */
  67.     @Override
  68.     public String call() throws IOException, AbortedByHookException {
  69.         if (commitMessage == null) {
  70.             throw new IllegalStateException();
  71.         }
  72.         if (canRun()) {
  73.             getRepository().writeCommitEditMsg(commitMessage);
  74.             doRun();
  75.             commitMessage = getRepository().readCommitEditMsg();
  76.         }
  77.         return commitMessage;
  78.     }

  79.     /**
  80.      * @return {@code true} if and only if the path to the message commit file
  81.      *         is not null (which would happen in a bare repository) and the
  82.      *         commit message is also not null.
  83.      */
  84.     private boolean canRun() {
  85.         return getCommitEditMessageFilePath() != null && commitMessage != null;
  86.     }

  87.     /** {@inheritDoc} */
  88.     @Override
  89.     public String getHookName() {
  90.         return NAME;
  91.     }

  92.     /**
  93.      * {@inheritDoc}
  94.      *
  95.      * This hook receives one parameter, which is the path to the file holding
  96.      * the current commit-msg, relative to the repository's work tree.
  97.      */
  98.     @Override
  99.     protected String[] getParameters() {
  100.         return new String[] { getCommitEditMessageFilePath() };
  101.     }

  102.     /**
  103.      * @return The path to the commit edit message file relative to the
  104.      *         repository's work tree, or null if the repository is bare.
  105.      */
  106.     private String getCommitEditMessageFilePath() {
  107.         File gitDir = getRepository().getDirectory();
  108.         if (gitDir == null) {
  109.             return null;
  110.         }
  111.         return Repository.stripWorkDir(getRepository().getWorkTree(), new File(
  112.                 gitDir, Constants.COMMIT_EDITMSG));
  113.     }

  114.     /**
  115.      * It is mandatory to call this method with a non-null value before actually
  116.      * calling the hook.
  117.      *
  118.      * @param commitMessage
  119.      *            The commit message before the hook has run.
  120.      * @return {@code this} for convenience.
  121.      */
  122.     public CommitMsgHook setCommitMessage(String commitMessage) {
  123.         this.commitMessage = commitMessage;
  124.         return this;
  125.     }

  126. }