Merge branch 'stable-5.6'
* stable-5.6: Add ability to redirect stderr from git hooks Add possibility to get pure stderr output from AbortedByHookException Change-Id: Ifc02675542dad6ced25fdd8b9fae80b5736db688 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
commit
23c5ebff79
|
@ -106,6 +106,16 @@ public PrePushHook getPrePushHook(Repository repo,
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PrePushHook getPrePushHook(Repository repo, PrintStream outputStream,
|
||||
PrintStream errorStream) {
|
||||
if (isEnabled(repo)) {
|
||||
return new LfsPrePushHook(repo, outputStream, errorStream);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param db
|
||||
* the repository
|
||||
|
|
|
@ -107,6 +107,20 @@ public LfsPrePushHook(Repository repo, PrintStream outputStream) {
|
|||
super(repo, outputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param repo
|
||||
* the repository
|
||||
* @param outputStream
|
||||
* not used by this implementation
|
||||
* @param errorStream
|
||||
* not used by this implementation
|
||||
* @since 5.6
|
||||
*/
|
||||
public LfsPrePushHook(Repository repo, PrintStream outputStream,
|
||||
PrintStream errorStream) {
|
||||
super(repo, outputStream, errorStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRefs(Collection<RemoteRefUpdate> toRefs) {
|
||||
this.refs = toRefs;
|
||||
|
|
|
@ -172,6 +172,7 @@ Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
|
|||
org.bouncycastle.openpgp.operator;version="[1.61.0,2.0.0)",
|
||||
org.bouncycastle.openpgp.operator.jcajce;version="[1.61.0,2.0.0)",
|
||||
org.bouncycastle.util.encoders;version="[1.61.0,2.0.0)",
|
||||
org.bouncycastle.util.io;version="[1.61.0,2.0.0)",
|
||||
org.slf4j;version="[1.7.0,2.0.0)",
|
||||
org.xml.sax,
|
||||
org.xml.sax.helpers
|
||||
|
|
|
@ -143,6 +143,8 @@ public class CommitCommand extends GitCommand<RevCommit> {
|
|||
|
||||
private HashMap<String, PrintStream> hookOutRedirect = new HashMap<>(3);
|
||||
|
||||
private HashMap<String, PrintStream> hookErrRedirect = new HashMap<>(3);
|
||||
|
||||
private Boolean allowEmpty;
|
||||
|
||||
private Boolean signCommit;
|
||||
|
@ -188,7 +190,8 @@ public RevCommit call() throws GitAPIException, NoHeadException,
|
|||
state.name()));
|
||||
|
||||
if (!noVerify) {
|
||||
Hooks.preCommit(repo, hookOutRedirect.get(PreCommitHook.NAME))
|
||||
Hooks.preCommit(repo, hookOutRedirect.get(PreCommitHook.NAME),
|
||||
hookErrRedirect.get(PreCommitHook.NAME))
|
||||
.call();
|
||||
}
|
||||
|
||||
|
@ -230,7 +233,8 @@ public RevCommit call() throws GitAPIException, NoHeadException,
|
|||
if (!noVerify) {
|
||||
message = Hooks
|
||||
.commitMsg(repo,
|
||||
hookOutRedirect.get(CommitMsgHook.NAME))
|
||||
hookOutRedirect.get(CommitMsgHook.NAME),
|
||||
hookErrRedirect.get(CommitMsgHook.NAME))
|
||||
.setCommitMessage(message).call();
|
||||
}
|
||||
|
||||
|
@ -311,7 +315,8 @@ public RevCommit call() throws GitAPIException, NoHeadException,
|
|||
repo.writeRevertHead(null);
|
||||
}
|
||||
Hooks.postCommit(repo,
|
||||
hookOutRedirect.get(PostCommitHook.NAME)).call();
|
||||
hookOutRedirect.get(PostCommitHook.NAME),
|
||||
hookErrRedirect.get(PostCommitHook.NAME)).call();
|
||||
|
||||
return revCommit;
|
||||
}
|
||||
|
@ -890,6 +895,23 @@ public CommitCommand setHookOutputStream(PrintStream hookStdOut) {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the error stream for all hook scripts executed by this command
|
||||
* (pre-commit, commit-msg, post-commit). If not set it defaults to
|
||||
* {@code System.err}.
|
||||
*
|
||||
* @param hookStdErr
|
||||
* the error stream for hook scripts executed by this command
|
||||
* @return {@code this}
|
||||
* @since 5.6
|
||||
*/
|
||||
public CommitCommand setHookErrorStream(PrintStream hookStdErr) {
|
||||
setHookErrorStream(PreCommitHook.NAME, hookStdErr);
|
||||
setHookErrorStream(CommitMsgHook.NAME, hookStdErr);
|
||||
setHookErrorStream(PostCommitHook.NAME, hookStdErr);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the output stream for a selected hook script executed by this command
|
||||
* (pre-commit, commit-msg, post-commit). If not set it defaults to
|
||||
|
@ -915,6 +937,30 @@ public CommitCommand setHookOutputStream(String hookName,
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the error stream for a selected hook script executed by this command
|
||||
* (pre-commit, commit-msg, post-commit). If not set it defaults to
|
||||
* {@code System.err}.
|
||||
*
|
||||
* @param hookName
|
||||
* name of the hook to set the output stream for
|
||||
* @param hookStdErr
|
||||
* the output stream to use for the selected hook
|
||||
* @return {@code this}
|
||||
* @since 5.6
|
||||
*/
|
||||
public CommitCommand setHookErrorStream(String hookName,
|
||||
PrintStream hookStdErr) {
|
||||
if (!(PreCommitHook.NAME.equals(hookName)
|
||||
|| CommitMsgHook.NAME.equals(hookName)
|
||||
|| PostCommitHook.NAME.equals(hookName))) {
|
||||
throw new IllegalArgumentException(MessageFormat
|
||||
.format(JGitText.get().illegalHookName, hookName));
|
||||
}
|
||||
hookErrRedirect.put(hookName, hookStdErr);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the signing key
|
||||
* <p>
|
||||
|
|
|
@ -66,20 +66,27 @@ public class AbortedByHookException extends GitAPIException {
|
|||
*/
|
||||
private final int returnCode;
|
||||
|
||||
/**
|
||||
* The stderr output of the hook.
|
||||
*/
|
||||
private final String hookStdErr;
|
||||
|
||||
/**
|
||||
* Constructor for AbortedByHookException
|
||||
*
|
||||
* @param message
|
||||
* The error details.
|
||||
* @param hookStdErr
|
||||
* The error details from the stderr output of the hook
|
||||
* @param hookName
|
||||
* The name of the hook that interrupted the command, must not be
|
||||
* null.
|
||||
* @param returnCode
|
||||
* The return code of the hook process that has been run.
|
||||
*/
|
||||
public AbortedByHookException(String message, String hookName,
|
||||
public AbortedByHookException(String hookStdErr, String hookName,
|
||||
int returnCode) {
|
||||
super(message);
|
||||
super(MessageFormat.format(JGitText.get().commandRejectedByHook,
|
||||
hookName, hookStdErr));
|
||||
this.hookStdErr = hookStdErr;
|
||||
this.hookName = hookName;
|
||||
this.returnCode = returnCode;
|
||||
}
|
||||
|
@ -102,10 +109,13 @@ public int getReturnCode() {
|
|||
return returnCode;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return MessageFormat.format(JGitText.get().commandRejectedByHook,
|
||||
hookName, super.getMessage());
|
||||
/**
|
||||
* Get the stderr output of the hook.
|
||||
*
|
||||
* @return A string containing the complete stderr output of the hook.
|
||||
* @since 5.6
|
||||
*/
|
||||
public String getHookStdErr() {
|
||||
return hookStdErr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,6 +72,9 @@ public class CommitMsgHook extends GitHook<String> {
|
|||
|
||||
/**
|
||||
* Constructor for CommitMsgHook
|
||||
* <p>
|
||||
* This constructor will use the default error stream.
|
||||
* </p>
|
||||
*
|
||||
* @param repo
|
||||
* The repository
|
||||
|
@ -83,6 +86,24 @@ protected CommitMsgHook(Repository repo, PrintStream outputStream) {
|
|||
super(repo, outputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for CommitMsgHook
|
||||
*
|
||||
* @param repo
|
||||
* The repository
|
||||
* @param outputStream
|
||||
* The output stream the hook must use. {@code null} is allowed,
|
||||
* in which case the hook will use {@code System.out}.
|
||||
* @param errorStream
|
||||
* The error stream the hook must use. {@code null} is allowed,
|
||||
* in which case the hook will use {@code System.err}.
|
||||
* @since 5.6
|
||||
*/
|
||||
protected CommitMsgHook(Repository repo, PrintStream outputStream,
|
||||
PrintStream errorStream) {
|
||||
super(repo, outputStream, errorStream);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public String call() throws IOException, AbortedByHookException {
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.bouncycastle.util.io.TeeOutputStream;
|
||||
import org.eclipse.jgit.api.errors.AbortedByHookException;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
|
@ -79,7 +80,15 @@ abstract class GitHook<T> implements Callable<T> {
|
|||
protected final PrintStream outputStream;
|
||||
|
||||
/**
|
||||
* Constructor for GitHook
|
||||
* The error stream to be used by the hook.
|
||||
*/
|
||||
protected final PrintStream errorStream;
|
||||
|
||||
/**
|
||||
* Constructor for GitHook.
|
||||
* <p>
|
||||
* This constructor will use stderr for the error stream.
|
||||
* </p>
|
||||
*
|
||||
* @param repo
|
||||
* a {@link org.eclipse.jgit.lib.Repository} object.
|
||||
|
@ -88,8 +97,26 @@ abstract class GitHook<T> implements Callable<T> {
|
|||
* in which case the hook will use {@code System.out}.
|
||||
*/
|
||||
protected GitHook(Repository repo, PrintStream outputStream) {
|
||||
this(repo, outputStream, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for GitHook
|
||||
*
|
||||
* @param repo
|
||||
* a {@link org.eclipse.jgit.lib.Repository} object.
|
||||
* @param outputStream
|
||||
* The output stream the hook must use. {@code null} is allowed,
|
||||
* in which case the hook will use {@code System.out}.
|
||||
* @param errorStream
|
||||
* The error stream the hook must use. {@code null} is allowed,
|
||||
* in which case the hook will use {@code System.err}.
|
||||
*/
|
||||
protected GitHook(Repository repo, PrintStream outputStream,
|
||||
PrintStream errorStream) {
|
||||
this.repo = repo;
|
||||
this.outputStream = outputStream;
|
||||
this.errorStream = errorStream;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,6 +174,16 @@ protected PrintStream getOutputStream() {
|
|||
return outputStream == null ? System.out : outputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get error stream
|
||||
*
|
||||
* @return The error stream the hook must use. Never {@code null},
|
||||
* {@code System.err} is returned by default.
|
||||
*/
|
||||
protected PrintStream getErrorStream() {
|
||||
return errorStream == null ? System.err : errorStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the hook, without performing any validity checks.
|
||||
*
|
||||
|
@ -155,9 +192,11 @@ protected PrintStream getOutputStream() {
|
|||
*/
|
||||
protected void doRun() throws AbortedByHookException {
|
||||
final ByteArrayOutputStream errorByteArray = new ByteArrayOutputStream();
|
||||
final TeeOutputStream stderrStream = new TeeOutputStream(errorByteArray,
|
||||
getErrorStream());
|
||||
PrintStream hookErrRedirect = null;
|
||||
try {
|
||||
hookErrRedirect = new PrintStream(errorByteArray, false,
|
||||
hookErrRedirect = new PrintStream(stderrStream, false,
|
||||
UTF_8.name());
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// UTF-8 is guaranteed to be available
|
||||
|
|
|
@ -57,7 +57,8 @@
|
|||
public class Hooks {
|
||||
|
||||
/**
|
||||
* Create pre-commit hook for the given repository
|
||||
* Create pre-commit hook for the given repository with the default error
|
||||
* stream
|
||||
*
|
||||
* @param repo
|
||||
* a {@link org.eclipse.jgit.lib.Repository} object.
|
||||
|
@ -71,7 +72,25 @@ public static PreCommitHook preCommit(Repository repo,
|
|||
}
|
||||
|
||||
/**
|
||||
* Create post-commit hook for the given repository
|
||||
* Create pre-commit hook for the given repository
|
||||
*
|
||||
* @param repo
|
||||
* a {@link org.eclipse.jgit.lib.Repository} object.
|
||||
* @param outputStream
|
||||
* The output stream, or {@code null} to use {@code System.out}
|
||||
* @param errorStream
|
||||
* The error stream, or {@code null} to use {@code System.err}
|
||||
* @return The pre-commit hook for the given repository.
|
||||
* @since 5.6
|
||||
*/
|
||||
public static PreCommitHook preCommit(Repository repo,
|
||||
PrintStream outputStream, PrintStream errorStream) {
|
||||
return new PreCommitHook(repo, outputStream, errorStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create post-commit hook for the given repository with the default error
|
||||
* stream
|
||||
*
|
||||
* @param repo
|
||||
* a {@link org.eclipse.jgit.lib.Repository} object.
|
||||
|
@ -86,7 +105,25 @@ public static PostCommitHook postCommit(Repository repo,
|
|||
}
|
||||
|
||||
/**
|
||||
* Create commit-msg hook for the given repository
|
||||
* Create post-commit hook for the given repository
|
||||
*
|
||||
* @param repo
|
||||
* a {@link org.eclipse.jgit.lib.Repository} object.
|
||||
* @param outputStream
|
||||
* The output stream, or {@code null} to use {@code System.out}
|
||||
* @param errorStream
|
||||
* The error stream, or {@code null} to use {@code System.err}
|
||||
* @return The pre-commit hook for the given repository.
|
||||
* @since 5.6
|
||||
*/
|
||||
public static PostCommitHook postCommit(Repository repo,
|
||||
PrintStream outputStream, PrintStream errorStream) {
|
||||
return new PostCommitHook(repo, outputStream, errorStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create commit-msg hook for the given repository with the default error
|
||||
* stream
|
||||
*
|
||||
* @param repo
|
||||
* a {@link org.eclipse.jgit.lib.Repository} object.
|
||||
|
@ -100,7 +137,25 @@ public static CommitMsgHook commitMsg(Repository repo,
|
|||
}
|
||||
|
||||
/**
|
||||
* Create pre-push hook for the given repository
|
||||
* Create commit-msg hook for the given repository
|
||||
*
|
||||
* @param repo
|
||||
* a {@link org.eclipse.jgit.lib.Repository} object.
|
||||
* @param outputStream
|
||||
* The output stream, or {@code null} to use {@code System.out}
|
||||
* @param errorStream
|
||||
* The error stream, or {@code null} to use {@code System.err}
|
||||
* @return The pre-commit hook for the given repository.
|
||||
* @since 5.6
|
||||
*/
|
||||
public static CommitMsgHook commitMsg(Repository repo,
|
||||
PrintStream outputStream, PrintStream errorStream) {
|
||||
return new CommitMsgHook(repo, outputStream, errorStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create pre-push hook for the given repository with the default error
|
||||
* stream
|
||||
*
|
||||
* @param repo
|
||||
* a {@link org.eclipse.jgit.lib.Repository} object.
|
||||
|
@ -127,4 +182,36 @@ public static PrePushHook prePush(Repository repo, PrintStream outputStream) {
|
|||
}
|
||||
return new PrePushHook(repo, outputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create pre-push hook for the given repository
|
||||
*
|
||||
* @param repo
|
||||
* a {@link org.eclipse.jgit.lib.Repository} object.
|
||||
* @param outputStream
|
||||
* The output stream, or {@code null} to use {@code System.out}
|
||||
* @param errorStream
|
||||
* The error stream, or {@code null} to use {@code System.err}
|
||||
* @return The pre-push hook for the given repository.
|
||||
* @since 5.6
|
||||
*/
|
||||
public static PrePushHook prePush(Repository repo, PrintStream outputStream,
|
||||
PrintStream errorStream) {
|
||||
if (LfsFactory.getInstance().isAvailable()) {
|
||||
PrePushHook hook = LfsFactory.getInstance().getPrePushHook(repo,
|
||||
outputStream, errorStream);
|
||||
if (hook != null) {
|
||||
if (hook.isNativeHookPresent()) {
|
||||
PrintStream ps = outputStream;
|
||||
if (ps == null) {
|
||||
ps = System.out;
|
||||
}
|
||||
ps.println(MessageFormat
|
||||
.format(JGitText.get().lfsHookConflict, repo));
|
||||
}
|
||||
return hook;
|
||||
}
|
||||
}
|
||||
return new PrePushHook(repo, outputStream, errorStream);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,6 +61,9 @@ public class PostCommitHook extends GitHook<Void> {
|
|||
|
||||
/**
|
||||
* Constructor for PostCommitHook
|
||||
* <p>
|
||||
* This constructor will use the default error stream.
|
||||
* </p>
|
||||
*
|
||||
* @param repo
|
||||
* The repository
|
||||
|
@ -72,6 +75,24 @@ protected PostCommitHook(Repository repo, PrintStream outputStream) {
|
|||
super(repo, outputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for PostCommitHook
|
||||
*
|
||||
* @param repo
|
||||
* The repository
|
||||
* @param outputStream
|
||||
* The output stream the hook must use. {@code null} is allowed,
|
||||
* in which case the hook will use {@code System.out}.
|
||||
* @param errorStream
|
||||
* The error stream the hook must use. {@code null} is allowed,
|
||||
* in which case the hook will use {@code System.err}.
|
||||
* @since 5.6
|
||||
*/
|
||||
protected PostCommitHook(Repository repo, PrintStream outputStream,
|
||||
PrintStream errorStream) {
|
||||
super(repo, outputStream, errorStream);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public Void call() throws IOException, AbortedByHookException {
|
||||
|
|
|
@ -61,6 +61,9 @@ public class PreCommitHook extends GitHook<Void> {
|
|||
|
||||
/**
|
||||
* Constructor for PreCommitHook
|
||||
* <p>
|
||||
* This constructor will use the default error stream.
|
||||
* </p>
|
||||
*
|
||||
* @param repo
|
||||
* The repository
|
||||
|
@ -72,6 +75,24 @@ protected PreCommitHook(Repository repo, PrintStream outputStream) {
|
|||
super(repo, outputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for PreCommitHook
|
||||
*
|
||||
* @param repo
|
||||
* The repository
|
||||
* @param outputStream
|
||||
* The output stream the hook must use. {@code null} is allowed,
|
||||
* in which case the hook will use {@code System.out}.
|
||||
* @param errorStream
|
||||
* The error stream the hook must use. {@code null} is allowed,
|
||||
* in which case the hook will use {@code System.err}.
|
||||
* @since 5.6
|
||||
*/
|
||||
protected PreCommitHook(Repository repo, PrintStream outputStream,
|
||||
PrintStream errorStream) {
|
||||
super(repo, outputStream, errorStream);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public Void call() throws IOException, AbortedByHookException {
|
||||
|
|
|
@ -73,6 +73,9 @@ public class PrePushHook extends GitHook<String> {
|
|||
|
||||
/**
|
||||
* Constructor for PrePushHook
|
||||
* <p>
|
||||
* This constructor will use the default error stream.
|
||||
* </p>
|
||||
*
|
||||
* @param repo
|
||||
* The repository
|
||||
|
@ -84,6 +87,24 @@ protected PrePushHook(Repository repo, PrintStream outputStream) {
|
|||
super(repo, outputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for PrePushHook
|
||||
*
|
||||
* @param repo
|
||||
* The repository
|
||||
* @param outputStream
|
||||
* The output stream the hook must use. {@code null} is allowed,
|
||||
* in which case the hook will use {@code System.out}.
|
||||
* @param errorStream
|
||||
* The error stream the hook must use. {@code null} is allowed,
|
||||
* in which case the hook will use {@code System.err}.
|
||||
* @since 5.6
|
||||
*/
|
||||
protected PrePushHook(Repository repo, PrintStream outputStream,
|
||||
PrintStream errorStream) {
|
||||
super(repo, outputStream, errorStream);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected String getStdinArgs() {
|
||||
|
|
|
@ -145,7 +145,7 @@ public ObjectLoader applySmudgeFilter(Repository db,
|
|||
}
|
||||
|
||||
/**
|
||||
* Retrieve a pre-push hook to be applied.
|
||||
* Retrieve a pre-push hook to be applied using the default error stream.
|
||||
*
|
||||
* @param repo
|
||||
* the {@link Repository} the hook is applied to.
|
||||
|
@ -158,6 +158,22 @@ public PrePushHook getPrePushHook(Repository repo,
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a pre-push hook to be applied.
|
||||
*
|
||||
* @param repo
|
||||
* the {@link Repository} the hook is applied to.
|
||||
* @param outputStream
|
||||
* @param errorStream
|
||||
* @return a {@link PrePushHook} implementation or <code>null</code>
|
||||
* @since 5.6
|
||||
*/
|
||||
@Nullable
|
||||
public PrePushHook getPrePushHook(Repository repo, PrintStream outputStream,
|
||||
PrintStream errorStream) {
|
||||
return getPrePushHook(repo, outputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an {@link LfsInstallCommand} which can be used to enable LFS
|
||||
* support (if available) either per repository or for the user.
|
||||
|
|
Loading…
Reference in New Issue