aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.pgm/src/org/eclipse
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit.pgm/src/org/eclipse')
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleAuthenticator.java50
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java87
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AbstractFetchCommand.java82
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Add.java86
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AmazonS3Client.java95
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java56
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java259
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java307
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java159
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clean.java58
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java147
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Command.java51
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java115
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandRef.java95
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java101
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Config.java19
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ConvertRefStorage.java35
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java101
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java110
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Die.java65
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Diff.java126
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTool.java380
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTree.java132
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java175
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Gc.java75
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java54
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/IndexPack.java48
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java77
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java141
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsFiles.java77
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java85
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java91
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java328
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java285
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeBase.java81
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeTool.java485
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MultiPackIndex.java107
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ObjectSizeIndex.java87
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/PackRefs.java34
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java129
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java56
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reflog.java70
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Remote.java166
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java62
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java99
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevList.java47
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevParse.java93
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java107
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Rm.java66
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java195
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ShowRef.java77
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java141
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java210
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java327
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java64
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Version.java69
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java368
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java132
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java285
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/MakeCacheTree.java51
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadChangedPathFilter.java83
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadDirCache.java47
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadReftable.java64
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java97
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCacheTree.java51
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java64
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowDirCache.java69
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowPackDelta.java73
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java119
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/VerifyReftable.java179
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteDirCache.java43
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java271
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java157
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/SshDriver.java23
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/VerificationUtils.java56
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java83
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java232
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/GpgSignHandler.java80
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/InstantHandler.java58
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/ObjectIdHandler.java61
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/OptionWithValuesListHandler.java57
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java66
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RefSpecHandler.java55
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java89
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java80
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/SubcommandHandler.java70
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/UntrackedFilesHandler.java53
87 files changed, 6269 insertions, 3871 deletions
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleAuthenticator.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleAuthenticator.java
index bdaccb0657..201fa3d22d 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleAuthenticator.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleAuthenticator.java
@@ -1,45 +1,12 @@
/*
* Copyright (C) 2009, Google Inc.
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.console;
@@ -49,9 +16,8 @@ import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.text.MessageFormat;
-import org.eclipse.jgit.util.CachedAuthenticator;
-
import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.util.CachedAuthenticator;
/**
* Basic network prompt for username/password when using the console.
@@ -59,7 +25,9 @@ import org.eclipse.jgit.pgm.internal.CLIText;
* @since 4.0
*/
public class ConsoleAuthenticator extends CachedAuthenticator {
- /** Install this authenticator implementation into the JVM. */
+ /**
+ * Install this authenticator implementation into the JVM.
+ */
public static void install() {
final ConsoleAuthenticator c = new ConsoleAuthenticator();
if (c.cons == null)
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java
index e805add814..5bdfc7bb51 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java
@@ -1,46 +1,13 @@
/*
* Copyright (C) 2010, Google Inc.
* Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.console;
@@ -48,21 +15,22 @@ package org.eclipse.jgit.console;
import java.io.Console;
import org.eclipse.jgit.errors.UnsupportedCredentialItem;
+import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.transport.ChainingCredentialsProvider;
import org.eclipse.jgit.transport.CredentialItem;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.NetRCCredentialsProvider;
import org.eclipse.jgit.transport.URIish;
-import org.eclipse.jgit.pgm.internal.CLIText;
-
/**
* Interacts with the user during authentication by using the text console.
*
* @since 4.0
*/
public class ConsoleCredentialsProvider extends CredentialsProvider {
- /** Install this implementation as the default. */
+ /**
+ * Install this implementation as the default.
+ */
public static void install() {
final ConsoleCredentialsProvider c = new ConsoleCredentialsProvider();
if (c.cons == null)
@@ -132,18 +100,15 @@ public class ConsoleCredentialsProvider extends CredentialsProvider {
if (v != null) {
item.setValue(new String(v));
return true;
- } else {
- return false;
- }
- } else {
- String v = cons.readLine("%s: ", item.getPromptText()); //$NON-NLS-1$
- if (v != null) {
- item.setValue(v);
- return true;
- } else {
- return false;
}
+ return false;
+ }
+ String v = cons.readLine("%s: ", item.getPromptText()); //$NON-NLS-1$
+ if (v != null) {
+ item.setValue(v);
+ return true;
}
+ return false;
}
private boolean get(CredentialItem.CharArrayType item) {
@@ -152,18 +117,15 @@ public class ConsoleCredentialsProvider extends CredentialsProvider {
if (v != null) {
item.setValueNoCopy(v);
return true;
- } else {
- return false;
- }
- } else {
- String v = cons.readLine("%s: ", item.getPromptText()); //$NON-NLS-1$
- if (v != null) {
- item.setValueNoCopy(v.toCharArray());
- return true;
- } else {
- return false;
}
+ return false;
}
+ String v = cons.readLine("%s: ", item.getPromptText()); //$NON-NLS-1$
+ if (v != null) {
+ item.setValueNoCopy(v.toCharArray());
+ return true;
+ }
+ return false;
}
private boolean get(CredentialItem.InformationalMessage item) {
@@ -178,8 +140,7 @@ public class ConsoleCredentialsProvider extends CredentialsProvider {
if (r != null) {
item.setValue(CLIText.get().answerYes.equalsIgnoreCase(r));
return true;
- } else {
- return false;
}
+ return false;
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AbstractFetchCommand.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AbstractFetchCommand.java
index fde0a78bf6..4440e26f6d 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AbstractFetchCommand.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AbstractFetchCommand.java
@@ -3,52 +3,17 @@
* Copyright (C) 2008-2010, Google Inc.
* Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2010, Sasa Zivkov <sasa.zivkov@sap.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2010, Sasa Zivkov <sasa.zivkov@sap.com> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
-import static java.lang.Character.valueOf;
-
import java.io.IOException;
import java.text.MessageFormat;
@@ -66,10 +31,18 @@ abstract class AbstractFetchCommand extends TextBuiltin {
@Option(name = "--verbose", aliases = { "-v" }, usage = "usage_beMoreVerbose")
private boolean verbose;
- protected void showFetchResult(final FetchResult r) throws IOException {
+ /**
+ * Show fetch result.
+ *
+ * @param r
+ * a {@link org.eclipse.jgit.transport.FetchResult} object.
+ * @throws java.io.IOException
+ * if any.
+ */
+ protected void showFetchResult(FetchResult r) throws IOException {
try (ObjectReader reader = db.newObjectReader()) {
boolean shownURI = false;
- for (final TrackingRefUpdate u : r.getTrackingRefUpdates()) {
+ for (TrackingRefUpdate u : r.getTrackingRefUpdates()) {
if (!verbose && u.getResult() == RefUpdate.Result.NO_CHANGE)
continue;
@@ -84,12 +57,15 @@ abstract class AbstractFetchCommand extends TextBuiltin {
shownURI = true;
}
- outw.format(" %c %-17s %-10s -> %s", valueOf(type), longType, //$NON-NLS-1$
- src, dst);
+ outw.format(" %c %-17s %-10s -> %s", Character.valueOf(type), //$NON-NLS-1$
+ longType, src, dst);
outw.println();
}
}
showRemoteMessages(errw, r.getMessages());
+ for (FetchResult submoduleResult : r.submoduleResults().values()) {
+ showFetchResult(submoduleResult);
+ }
}
static void showRemoteMessages(ThrowingPrintWriter writer, String pkt) throws IOException {
@@ -129,20 +105,20 @@ abstract class AbstractFetchCommand extends TextBuiltin {
final TrackingRefUpdate u) {
final RefUpdate.Result r = u.getResult();
if (r == RefUpdate.Result.LOCK_FAILURE)
- return "[lock fail]";
+ return "[lock fail]"; //$NON-NLS-1$
if (r == RefUpdate.Result.IO_FAILURE)
- return "[i/o error]";
+ return "[i/o error]"; //$NON-NLS-1$
if (r == RefUpdate.Result.REJECTED)
- return "[rejected]";
+ return "[rejected]"; //$NON-NLS-1$
if (ObjectId.zeroId().equals(u.getNewObjectId()))
- return "[deleted]";
+ return "[deleted]"; //$NON-NLS-1$
if (r == RefUpdate.Result.NEW) {
if (u.getRemoteName().startsWith(Constants.R_HEADS))
- return "[new branch]";
+ return "[new branch]"; //$NON-NLS-1$
else if (u.getLocalName().startsWith(Constants.R_TAGS))
- return "[new tag]";
- return "[new]";
+ return "[new tag]"; //$NON-NLS-1$
+ return "[new]"; //$NON-NLS-1$
}
if (r == RefUpdate.Result.FORCED) {
@@ -158,7 +134,7 @@ abstract class AbstractFetchCommand extends TextBuiltin {
}
if (r == RefUpdate.Result.NO_CHANGE)
- return "[up to date]";
+ return "[up to date]"; //$NON-NLS-1$
return "[" + r.name() + "]"; //$NON-NLS-1$//$NON-NLS-2$
}
@@ -170,7 +146,7 @@ abstract class AbstractFetchCommand extends TextBuiltin {
}
}
- private static char shortTypeOf(final RefUpdate.Result r) {
+ private static char shortTypeOf(RefUpdate.Result r) {
if (r == RefUpdate.Result.LOCK_FAILURE)
return '!';
if (r == RefUpdate.Result.IO_FAILURE)
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Add.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Add.java
index 12aac77e9d..dc9d77df35 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Add.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Add.java
@@ -1,44 +1,11 @@
/*
- * Copyright (C) 2010, Sasa Zivkov <sasa.zivkov@sap.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2010, 2025 Sasa Zivkov <sasa.zivkov@sap.com> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
@@ -48,24 +15,53 @@ import java.util.List;
import org.eclipse.jgit.api.AddCommand;
import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.pgm.internal.CLIText;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@Command(common = true, usage = "usage_addFileContentsToTheIndex")
class Add extends TextBuiltin {
+ @Option(name = "--renormalize", usage = "usage_addRenormalize")
+ private boolean renormalize = false;
+
@Option(name = "--update", aliases = { "-u" }, usage = "usage_onlyMatchAgainstAlreadyTrackedFiles")
private boolean update = false;
- @Argument(required = true, metaVar = "metaVar_filepattern", usage = "usage_filesToAddContentFrom")
- private List<String> filepatterns = new ArrayList<String>();
+ @Option(name = "--all", aliases = { "-A",
+ "--no-ignore-removal" }, usage = "usage_addStageDeletions")
+ private Boolean all;
+
+ @Option(name = "--no-all", aliases = {
+ "--ignore-removal" }, usage = "usage_addDontStageDeletions")
+ private void noAll(@SuppressWarnings("unused") boolean ignored) {
+ all = Boolean.FALSE;
+ }
+
+ @Argument(metaVar = "metaVar_filepattern", usage = "usage_filesToAddContentFrom")
+ private List<String> filepatterns = new ArrayList<>();
@Override
protected void run() throws Exception {
- AddCommand addCmd = new Git(db).add();
- addCmd.setUpdate(update);
- for (String p : filepatterns)
- addCmd.addFilepattern(p);
- addCmd.call();
+ try (Git git = new Git(db)) {
+ if (renormalize) {
+ update = true;
+ }
+ if (update && all != null) {
+ throw die(CLIText.get().addIncompatibleOptions);
+ }
+ AddCommand addCmd = git.add();
+ addCmd.setUpdate(update).setRenormalize(renormalize);
+ if (all != null) {
+ addCmd.setAll(all.booleanValue());
+ }
+ for (String p : filepatterns) {
+ addCmd.addFilepattern(p);
+ }
+ addCmd.call();
+ } catch (GitAPIException e) {
+ throw die(e.getMessage(), e);
+ }
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AmazonS3Client.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AmazonS3Client.java
index e0a9244a8f..24a75a86e8 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AmazonS3Client.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/AmazonS3Client.java
@@ -1,51 +1,16 @@
/*
* Copyright (C) 2009, Google Inc.
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
-import static java.lang.Integer.valueOf;
-
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
@@ -84,11 +49,14 @@ class AmazonS3Client extends TextBuiltin {
protected void run() throws Exception {
final AmazonS3 s3 = new AmazonS3(properties());
- if ("get".equals(op)) { //$NON-NLS-1$
+ if (op == null) {
+ throw die(MessageFormat.format(CLIText.get().unsupportedOperation, op));
+ }
+ switch (op) {
+ case "get": //$NON-NLS-1$
final URLConnection c = s3.get(bucket, key);
int len = c.getContentLength();
- final InputStream in = c.getInputStream();
- try {
+ try (InputStream in = c.getInputStream()) {
outw.flush();
final byte[] tmp = new byte[2048];
while (len > 0) {
@@ -96,44 +64,41 @@ class AmazonS3Client extends TextBuiltin {
if (n < 0)
throw new EOFException(MessageFormat.format(
CLIText.get().expectedNumberOfbytes,
- valueOf(len)));
+ Integer.valueOf(len)));
outs.write(tmp, 0, n);
len -= n;
}
outs.flush();
- } finally {
- in.close();
}
-
- } else if ("ls".equals(op) || "list".equals(op)) { //$NON-NLS-1$//$NON-NLS-2$
- for (final String k : s3.list(bucket, key))
+ break;
+ case "ls": //$NON-NLS-1$
+ case "list": //$NON-NLS-1$
+ for (String k : s3.list(bucket, key))
outw.println(k);
-
- } else if ("rm".equals(op) || "delete".equals(op)) { //$NON-NLS-1$ //$NON-NLS-2$
+ break;
+ case "rm": //$NON-NLS-1$
+ case "delete": //$NON-NLS-1$
s3.delete(bucket, key);
-
- } else if ("put".equals(op)) { //$NON-NLS-1$
- final OutputStream os = s3.beginPut(bucket, key, null, null);
- final byte[] tmp = new byte[2048];
- int n;
- while ((n = ins.read(tmp)) > 0)
- os.write(tmp, 0, n);
- os.close();
-
- } else {
+ break;
+ case "put": //$NON-NLS-1$
+ try (OutputStream os = s3.beginPut(bucket, key, null, null)) {
+ final byte[] tmp = new byte[2048];
+ int n;
+ while ((n = ins.read(tmp)) > 0)
+ os.write(tmp, 0, n);
+ }
+ break;
+ default:
throw die(MessageFormat.format(CLIText.get().unsupportedOperation, op));
}
}
private Properties properties() {
try {
- final InputStream in = new FileInputStream(propertyFile);
- try {
+ try (InputStream in = new FileInputStream(propertyFile)) {
final Properties p = new Properties();
p.load(in);
return p;
- } finally {
- in.close();
}
} catch (FileNotFoundException e) {
throw die(MessageFormat.format(CLIText.get().noSuchFile, propertyFile), e);
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java
index 80bb9ec9df..f98f8cb728 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java
@@ -1,44 +1,11 @@
/*
- * Copyright (C) 2012 Google Inc.
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2012 Google Inc. and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
@@ -52,7 +19,6 @@ import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.archive.ArchiveFormats;
import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.pgm.TextBuiltin;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@@ -87,8 +53,8 @@ class Archive extends TextBuiltin {
else
stream = outs;
- try {
- ArchiveCommand cmd = new Git(db).archive()
+ try (Git git = new Git(db)) {
+ ArchiveCommand cmd = git.archive()
.setTree(tree)
.setFormat(format)
.setPrefix(prefix)
@@ -96,11 +62,11 @@ class Archive extends TextBuiltin {
if (output != null)
cmd.setFilename(output);
cmd.call();
- } catch (GitAPIException e) {
- throw die(e.getMessage());
- }
+ } catch (GitAPIException e) {
+ throw die(e.getMessage(), e);
+ }
} catch (FileNotFoundException e) {
- throw die(e.getMessage());
+ throw die(e.getMessage(), e);
} finally {
if (output != null && stream != null)
stream.close();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java
index 0f541715ab..285fe2a96a 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Blame.java
@@ -2,70 +2,37 @@
* Copyright (C) 2011, Google Inc.
* Copyright (C) 2009, Christian Halstrick <christian.halstrick@sap.com>
* Copyright (C) 2009, Johannes E. Schindelin
- * Copyright (C) 2009, Johannes Schindelin <johannes.schindelin@gmx.de>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2009, Johannes Schindelin <johannes.schindelin@gmx.de> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
-import static java.lang.Integer.valueOf;
-import static java.lang.Long.valueOf;
+import static org.eclipse.jgit.lib.Constants.OBJECT_ID_ABBREV_STRING_LENGTH;
import static org.eclipse.jgit.lib.Constants.OBJECT_ID_STRING_LENGTH;
-import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
-import java.text.SimpleDateFormat;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
+import org.eclipse.jgit.api.errors.NoHeadException;
import org.eclipse.jgit.blame.BlameGenerator;
import org.eclipse.jgit.blame.BlameResult;
import org.eclipse.jgit.diff.RawText;
import org.eclipse.jgit.diff.RawTextComparator;
-import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.pgm.internal.CLIText;
@@ -114,7 +81,7 @@ class Blame extends TextBuiltin {
private String rangeString;
@Option(name = "--reverse", metaVar = "metaVar_blameReverse", usage = "usage_blameReverse")
- private List<RevCommit> reverseRange = new ArrayList<RevCommit>(2);
+ private List<RevCommit> reverseRange = new ArrayList<>(2);
@Argument(index = 0, required = false, metaVar = "metaVar_revision")
private String revision;
@@ -122,11 +89,9 @@ class Blame extends TextBuiltin {
@Argument(index = 1, required = false, metaVar = "metaVar_file")
private String file;
- private ObjectReader reader;
+ private final Map<RevCommit, String> abbreviatedCommits = new HashMap<>();
- private final Map<RevCommit, String> abbreviatedCommits = new HashMap<RevCommit, String>();
-
- private SimpleDateFormat dateFmt;
+ private DateTimeFormatter dateFmt;
private int begin;
@@ -134,64 +99,74 @@ class Blame extends TextBuiltin {
private BlameResult blame;
+ /** Used to get a current time stamp for lines without commit. */
+ private final PersonIdent dummyDate = new PersonIdent("", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
@Override
- protected void run() throws Exception {
+ protected void run() {
if (file == null) {
- if (revision == null)
+ if (revision == null) {
throw die(CLIText.get().fileIsRequired);
+ }
file = revision;
revision = null;
}
boolean autoAbbrev = abbrev == 0;
- if (abbrev == 0)
- abbrev = db.getConfig().getInt("core", "abbrev", 7); //$NON-NLS-1$ //$NON-NLS-2$
- if (!showBlankBoundary)
+ if (abbrev == 0) {
+ abbrev = db.getConfig().getInt("core", "abbrev", //$NON-NLS-1$ //$NON-NLS-2$
+ OBJECT_ID_ABBREV_STRING_LENGTH);
+ }
+ if (!showBlankBoundary) {
root = db.getConfig().getBoolean("blame", "blankboundary", false); //$NON-NLS-1$ //$NON-NLS-2$
- if (!root)
+ }
+ if (!root) {
root = db.getConfig().getBoolean("blame", "showroot", false); //$NON-NLS-1$ //$NON-NLS-2$
+ }
- if (showRawTimestamp)
- dateFmt = new SimpleDateFormat("ZZZZ"); //$NON-NLS-1$
- else
- dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ZZZZ"); //$NON-NLS-1$
+ if (showRawTimestamp) {
+ dateFmt = DateTimeFormatter.ofPattern("ZZ"); //$NON-NLS-1$
+ } else {
+ dateFmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss ZZ"); //$NON-NLS-1$
+ }
- reader = db.newObjectReader();
- try (BlameGenerator generator = new BlameGenerator(db, file)) {
+ try (ObjectReader reader = db.newObjectReader();
+ BlameGenerator generator = new BlameGenerator(db, file)) {
RevFlag scanned = generator.newFlag("SCANNED"); //$NON-NLS-1$
generator.setTextComparator(comparator);
if (!reverseRange.isEmpty()) {
RevCommit rangeStart = null;
- List<RevCommit> rangeEnd = new ArrayList<RevCommit>(2);
+ List<RevCommit> rangeEnd = new ArrayList<>(2);
for (RevCommit c : reverseRange) {
- if (c.has(RevFlag.UNINTERESTING))
+ if (c.has(RevFlag.UNINTERESTING)) {
rangeStart = c;
- else
+ } else {
rangeEnd.add(c);
+ }
}
generator.reverse(rangeStart, rangeEnd);
} else if (revision != null) {
- generator.push(null, db.resolve(revision + "^{commit}")); //$NON-NLS-1$
- } else {
- generator.push(null, db.resolve(Constants.HEAD));
- if (!db.isBare()) {
- DirCache dc = db.readDirCache();
- int entry = dc.findEntry(file);
- if (0 <= entry)
- generator.push(null, dc.getEntry(entry).getObjectId());
-
- File inTree = new File(db.getWorkTree(), file);
- if (db.getFS().isFile(inTree))
- generator.push(null, new RawText(inTree));
+ ObjectId rev = db.resolve(revision + "^{commit}"); //$NON-NLS-1$
+ if (rev == null) {
+ throw die(MessageFormat.format(CLIText.get().noSuchRef,
+ revision));
}
+ generator.push(null, rev);
+ } else {
+ generator.prepareHead();
}
blame = BlameResult.create(generator);
+ if (blame == null) {
+ throw die(MessageFormat.format(CLIText.get().noSuchPathInRef,
+ file, revision != null ? revision : Constants.HEAD));
+ }
begin = 0;
end = blame.getResultContents().size();
- if (rangeString != null)
+ if (rangeString != null) {
parseLineRangeOption();
+ }
blame.computeRange(begin, end);
int authorWidth = 8;
@@ -202,28 +177,36 @@ class Blame extends TextBuiltin {
RevCommit c = blame.getSourceCommit(line);
if (c != null && !c.has(scanned)) {
c.add(scanned);
- if (autoAbbrev)
- abbrev = Math.max(abbrev, uniqueAbbrevLen(c));
+ if (autoAbbrev) {
+ abbrev = Math.max(abbrev, uniqueAbbrevLen(reader, c));
+ }
+ authorWidth = Math.max(authorWidth, author(line).length());
+ dateWidth = Math.max(dateWidth, date(line).length());
+ pathWidth = Math.max(pathWidth, path(line).length());
+ } else if (c == null) {
authorWidth = Math.max(authorWidth, author(line).length());
dateWidth = Math.max(dateWidth, date(line).length());
pathWidth = Math.max(pathWidth, path(line).length());
}
- while (line + 1 < end && blame.getSourceCommit(line + 1) == c)
+ while (line + 1 < end
+ && sameCommit(blame.getSourceCommit(line + 1), c)) {
line++;
+ }
maxSourceLine = Math.max(maxSourceLine, blame.getSourceLine(line));
}
- String pathFmt = MessageFormat.format(" %{0}s", valueOf(pathWidth)); //$NON-NLS-1$
+ String pathFmt = MessageFormat.format(" %{0}s", //$NON-NLS-1$
+ Integer.valueOf(pathWidth));
String numFmt = MessageFormat.format(" %{0}d", //$NON-NLS-1$
- valueOf(1 + (int) Math.log10(maxSourceLine + 1)));
+ Integer.valueOf(1 + (int) Math.log10(maxSourceLine + 1)));
String lineFmt = MessageFormat.format(" %{0}d) ", //$NON-NLS-1$
- valueOf(1 + (int) Math.log10(end + 1)));
+ Integer.valueOf(1 + (int) Math.log10(end + 1)));
String authorFmt = MessageFormat.format(" (%-{0}s %{1}s", //$NON-NLS-1$
- valueOf(authorWidth), valueOf(dateWidth));
+ Integer.valueOf(authorWidth), Integer.valueOf(dateWidth));
for (int line = begin; line < end;) {
RevCommit c = blame.getSourceCommit(line);
- String commit = abbreviate(c);
+ String commit = abbreviate(reader, c);
String author = null;
String date = null;
if (!noAuthor) {
@@ -232,25 +215,39 @@ class Blame extends TextBuiltin {
}
do {
outw.print(commit);
- if (showSourcePath)
+ if (showSourcePath) {
outw.format(pathFmt, path(line));
- if (showSourceLine)
- outw.format(numFmt, valueOf(blame.getSourceLine(line) + 1));
- if (!noAuthor)
+ }
+ if (showSourceLine) {
+ outw.format(numFmt,
+ Integer.valueOf(blame.getSourceLine(line) + 1));
+ }
+ if (!noAuthor) {
outw.format(authorFmt, author, date);
- outw.format(lineFmt, valueOf(line + 1));
+ }
+ outw.format(lineFmt, Integer.valueOf(line + 1));
outw.flush();
blame.getResultContents().writeLine(outs, line);
outs.flush();
outw.print('\n');
- } while (++line < end && blame.getSourceCommit(line) == c);
+ } while (++line < end
+ && sameCommit(blame.getSourceCommit(line), c));
}
- } finally {
- reader.close();
+ } catch (NoWorkTreeException | NoHeadException | IOException e) {
+ throw die(e.getMessage(), e);
}
}
- private int uniqueAbbrevLen(RevCommit commit) throws IOException {
+ @SuppressWarnings("ReferenceEquality")
+ private static boolean sameCommit(RevCommit a, RevCommit b) {
+ // Reference comparison is intentional; BlameGenerator uses a single
+ // RevWalk which caches the RevCommit objects, and if a given commit
+ // is cached the RevWalk returns the same instance.
+ return a == b;
+ }
+
+ private int uniqueAbbrevLen(ObjectReader reader, RevCommit commit)
+ throws IOException {
return reader.abbreviate(commit, abbrev).length();
}
@@ -280,14 +277,14 @@ class Blame extends TextBuiltin {
}
}
- if (beginStr.equals("")) //$NON-NLS-1$
+ if (beginStr.isEmpty())
begin = 0;
else if (beginStr.startsWith("/")) //$NON-NLS-1$
begin = findLine(0, beginStr);
else
begin = Math.max(0, Integer.parseInt(beginStr) - 1);
- if (endStr.equals("")) //$NON-NLS-1$
+ if (endStr.isEmpty())
end = blame.getResultContents().size();
else if (endStr.startsWith("/")) //$NON-NLS-1$
end = findLine(begin, endStr);
@@ -329,48 +326,62 @@ class Blame extends TextBuiltin {
}
private String date(int line) {
- if (blame.getSourceCommit(line) == null)
- return ""; //$NON-NLS-1$
-
- PersonIdent author = blame.getSourceAuthor(line);
+ PersonIdent author;
+ if (blame.getSourceCommit(line) == null) {
+ author = dummyDate;
+ } else {
+ author = blame.getSourceAuthor(line);
+ }
if (author == null)
return ""; //$NON-NLS-1$
- dateFmt.setTimeZone(author.getTimeZone());
- if (!showRawTimestamp)
- return dateFmt.format(author.getWhen());
+ if (!showRawTimestamp) {
+ return dateFmt.withZone(author.getZoneId())
+ .format(author.getWhenAsInstant());
+ }
return String.format("%d %s", //$NON-NLS-1$
- valueOf(author.getWhen().getTime() / 1000L),
- dateFmt.format(author.getWhen()));
+ Long.valueOf(author.getWhenAsInstant().getEpochSecond()),
+ dateFmt.withZone(author.getZoneId())
+ .format(author.getWhenAsInstant()));
}
- private String abbreviate(RevCommit commit) throws IOException {
+ private String abbreviate(ObjectReader reader, RevCommit commit)
+ throws IOException {
String r = abbreviatedCommits.get(commit);
if (r != null)
return r;
- if (showBlankBoundary && commit.getParentCount() == 0)
- commit = null;
-
if (commit == null) {
- int len = showLongRevision ? OBJECT_ID_STRING_LENGTH : (abbrev + 1);
- StringBuilder b = new StringBuilder(len);
- for (int i = 0; i < len; i++)
- b.append(' ');
- r = b.toString();
-
- } else if (!root && commit.getParentCount() == 0) {
- if (showLongRevision)
- r = "^" + commit.name().substring(0, OBJECT_ID_STRING_LENGTH - 1); //$NON-NLS-1$
- else
- r = "^" + reader.abbreviate(commit, abbrev).name(); //$NON-NLS-1$
+ if (showLongRevision) {
+ r = ObjectId.zeroId().name();
+ } else {
+ r = ObjectId.zeroId().abbreviate(abbrev + 1).name();
+ }
} else {
- if (showLongRevision)
- r = commit.name();
- else
- r = reader.abbreviate(commit, abbrev + 1).name();
+ if (showBlankBoundary && commit.getParentCount() == 0)
+ commit = null;
+
+ if (commit == null) {
+ int len = showLongRevision ? OBJECT_ID_STRING_LENGTH
+ : (abbrev + 1);
+ StringBuilder b = new StringBuilder(len);
+ for (int i = 0; i < len; i++)
+ b.append(' ');
+ r = b.toString();
+
+ } else if (!root && commit.getParentCount() == 0) {
+ if (showLongRevision)
+ r = "^" + commit.name().substring(0, //$NON-NLS-1$
+ OBJECT_ID_STRING_LENGTH - 1);
+ else
+ r = "^" + reader.abbreviate(commit, abbrev).name(); //$NON-NLS-1$
+ } else {
+ if (showLongRevision)
+ r = commit.name();
+ else
+ r = reader.abbreviate(commit, abbrev + 1).name();
+ }
}
-
abbreviatedCommits.put(commit, r);
return r;
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java
index 72e37158cd..e680394a79 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java
@@ -1,51 +1,17 @@
/*
- * Copyright (C) 2007-2008, Charles O'Farrell <charleso@charleso.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2007-2008, Charles O'Farrell <charleso@charleso.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
import java.io.IOException;
import java.text.MessageFormat;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
@@ -55,6 +21,7 @@ import java.util.Map.Entry;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ListBranchCommand;
import org.eclipse.jgit.api.ListBranchCommand.ListMode;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
@@ -65,15 +32,18 @@ import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.pgm.internal.CLIText;
-import org.eclipse.jgit.pgm.opt.CmdLineParser;
+import org.eclipse.jgit.pgm.opt.OptionWithValuesListHandler;
import org.eclipse.jgit.revwalk.RevWalk;
import org.kohsuke.args4j.Argument;
-import org.kohsuke.args4j.ExampleMode;
import org.kohsuke.args4j.Option;
@Command(common = true, usage = "usage_listCreateOrDeleteBranches")
class Branch extends TextBuiltin {
+ private String otherBranch;
+ private boolean createForce;
+ private boolean rename;
+
@Option(name = "--remote", aliases = { "-r" }, usage = "usage_actOnRemoteTrackingBranches")
private boolean remote = false;
@@ -83,25 +53,95 @@ class Branch extends TextBuiltin {
@Option(name = "--contains", metaVar = "metaVar_commitish", usage = "usage_printOnlyBranchesThatContainTheCommit")
private String containsCommitish;
- @Option(name = "--delete", aliases = { "-d" }, usage = "usage_deleteFullyMergedBranch")
- private boolean delete = false;
+ private List<String> delete;
+
+ /**
+ * Delete branches
+ *
+ * @param names
+ * a {@link java.util.List} of branch names.
+ */
+ @Option(name = "--delete", aliases = {
+ "-d" }, metaVar = "metaVar_branchNames", usage = "usage_deleteFullyMergedBranch", handler = OptionWithValuesListHandler.class)
+ public void delete(List<String> names) {
+ if (names.isEmpty()) {
+ throw die(CLIText.get().branchNameRequired);
+ }
+ delete = names;
+ }
+
+ private List<String> deleteForce;
- @Option(name = "--delete-force", aliases = { "-D" }, usage = "usage_deleteBranchEvenIfNotMerged")
- private boolean deleteForce = false;
+ /**
+ * Forcefully delete branches
+ *
+ * @param names
+ * a {@link java.util.List} of branch names.
+ */
+ @Option(name = "--delete-force", aliases = {
+ "-D" }, metaVar = "metaVar_branchNames", usage = "usage_deleteBranchEvenIfNotMerged", handler = OptionWithValuesListHandler.class)
+ public void deleteForce(List<String> names) {
+ if (names.isEmpty()) {
+ throw die(CLIText.get().branchNameRequired);
+ }
+ deleteForce = names;
+ }
- @Option(name = "--create-force", aliases = { "-f" }, usage = "usage_forceCreateBranchEvenExists")
- private boolean createForce = false;
+ /**
+ * Forcefully create a list of branches
+ *
+ * @param branchAndStartPoint
+ * a branch name and a start point
+ */
+ @Option(name = "--create-force", aliases = {
+ "-f" }, metaVar = "metaVar_branchAndStartPoint", usage = "usage_forceCreateBranchEvenExists", handler = OptionWithValuesListHandler.class)
+ public void createForce(List<String> branchAndStartPoint) {
+ createForce = true;
+ if (branchAndStartPoint.isEmpty()) {
+ throw die(CLIText.get().branchNameRequired);
+ }
+ if (branchAndStartPoint.size() > 2) {
+ throw die(CLIText.get().tooManyRefsGiven);
+ }
+ if (branchAndStartPoint.size() == 1) {
+ branch = branchAndStartPoint.get(0);
+ } else {
+ branch = branchAndStartPoint.get(0);
+ otherBranch = branchAndStartPoint.get(1);
+ }
+ }
- @Option(name = "-m", usage = "usage_moveRenameABranch")
- private boolean rename = false;
+ /**
+ * Move or rename a branch
+ *
+ * @param currentAndNew
+ * the current and the new branch name
+ */
+ @Option(name = "--move", aliases = {
+ "-m" }, metaVar = "metaVar_oldNewBranchNames", usage = "usage_moveRenameABranch", handler = OptionWithValuesListHandler.class)
+ public void moveRename(List<String> currentAndNew) {
+ rename = true;
+ if (currentAndNew.isEmpty()) {
+ throw die(CLIText.get().branchNameRequired);
+ }
+ if (currentAndNew.size() > 2) {
+ throw die(CLIText.get().tooManyRefsGiven);
+ }
+ if (currentAndNew.size() == 1) {
+ branch = currentAndNew.get(0);
+ } else {
+ branch = currentAndNew.get(0);
+ otherBranch = currentAndNew.get(1);
+ }
+ }
@Option(name = "--verbose", aliases = { "-v" }, usage = "usage_beVerbose")
private boolean verbose = false;
- @Argument
- private List<String> branches = new ArrayList<String>();
+ @Argument(metaVar = "metaVar_name")
+ private String branch;
- private final Map<String, Ref> printRefs = new LinkedHashMap<String, Ref>();
+ private final Map<String, Ref> printRefs = new LinkedHashMap<>();
/** Only set for verbose branch listing at-the-moment */
private RevWalk rw;
@@ -109,126 +149,150 @@ class Branch extends TextBuiltin {
private int maxNameLength;
@Override
- protected void run() throws Exception {
- if (delete || deleteForce)
- delete(deleteForce);
- else {
- if (branches.size() > 2)
- throw die(CLIText.get().tooManyRefsGiven + new CmdLineParser(this).printExample(ExampleMode.ALL));
-
+ protected void run() {
+ try {
+ if (delete != null || deleteForce != null) {
+ if (delete != null) {
+ delete(delete, false);
+ }
+ if (deleteForce != null) {
+ delete(deleteForce, true);
+ }
+ return;
+ }
if (rename) {
String src, dst;
- if (branches.size() == 1) {
- final Ref head = db.getRef(Constants.HEAD);
- if (head != null && head.isSymbolic())
+ if (otherBranch == null) {
+ final Ref head = db.exactRef(Constants.HEAD);
+ if (head != null && head.isSymbolic()) {
src = head.getLeaf().getName();
- else
+ } else {
throw die(CLIText.get().cannotRenameDetachedHEAD);
- dst = branches.get(0);
+ }
+ dst = branch;
} else {
- src = branches.get(0);
- final Ref old = db.getRef(src);
- if (old == null)
+ src = branch;
+ final Ref old = db.findRef(src);
+ if (old == null) {
throw die(MessageFormat.format(CLIText.get().doesNotExist, src));
- if (!old.getName().startsWith(Constants.R_HEADS))
+ }
+ if (!old.getName().startsWith(Constants.R_HEADS)) {
throw die(MessageFormat.format(CLIText.get().notABranch, src));
+ }
src = old.getName();
- dst = branches.get(1);
+ dst = otherBranch;
}
- if (!dst.startsWith(Constants.R_HEADS))
+ if (!dst.startsWith(Constants.R_HEADS)) {
dst = Constants.R_HEADS + dst;
- if (!Repository.isValidRefName(dst))
+ }
+ if (!Repository.isValidRefName(dst)) {
throw die(MessageFormat.format(CLIText.get().notAValidRefName, dst));
+ }
RefRename r = db.renameRef(src, dst);
- if (r.rename() != Result.RENAMED)
+ if (r.rename() != Result.RENAMED) {
throw die(MessageFormat.format(CLIText.get().cannotBeRenamed, src));
+ }
- } else if (branches.size() > 0) {
- String newHead = branches.get(0);
+ } else if (createForce || branch != null) {
+ String newHead = branch;
String startBranch;
- if (branches.size() == 2)
- startBranch = branches.get(1);
- else
+ if (createForce) {
+ startBranch = otherBranch;
+ } else {
startBranch = Constants.HEAD;
- Ref startRef = db.getRef(startBranch);
+ }
+ Ref startRef = db.findRef(startBranch);
ObjectId startAt = db.resolve(startBranch + "^0"); //$NON-NLS-1$
- if (startRef != null)
+ if (startRef != null) {
startBranch = startRef.getName();
- else
+ } else if (startAt != null) {
startBranch = startAt.name();
+ } else {
+ throw die(MessageFormat.format(
+ CLIText.get().notAValidCommitName, startBranch));
+ }
startBranch = Repository.shortenRefName(startBranch);
String newRefName = newHead;
- if (!newRefName.startsWith(Constants.R_HEADS))
+ if (!newRefName.startsWith(Constants.R_HEADS)) {
newRefName = Constants.R_HEADS + newRefName;
- if (!Repository.isValidRefName(newRefName))
+ }
+ if (!Repository.isValidRefName(newRefName)) {
throw die(MessageFormat.format(CLIText.get().notAValidRefName, newRefName));
- if (!createForce && db.resolve(newRefName) != null)
+ }
+ if (!createForce && db.resolve(newRefName) != null) {
throw die(MessageFormat.format(CLIText.get().branchAlreadyExists, newHead));
+ }
RefUpdate updateRef = db.updateRef(newRefName);
updateRef.setNewObjectId(startAt);
updateRef.setForceUpdate(createForce);
updateRef.setRefLogMessage(MessageFormat.format(CLIText.get().branchCreatedFrom, startBranch), false);
Result update = updateRef.update();
- if (update == Result.REJECTED)
+ if (update == Result.REJECTED) {
throw die(MessageFormat.format(CLIText.get().couldNotCreateBranch, newHead, update.toString()));
+ }
} else {
- if (verbose)
+ if (verbose) {
rw = new RevWalk(db);
+ }
list();
}
+ } catch (IOException | GitAPIException e) {
+ throw die(e.getMessage(), e);
}
}
- private void list() throws Exception {
- Ref head = db.getRef(Constants.HEAD);
+ private void list() throws IOException, GitAPIException {
+ Ref head = db.exactRef(Constants.HEAD);
// This can happen if HEAD is stillborn
if (head != null) {
String current = head.getLeaf().getName();
- ListBranchCommand command = new Git(db).branchList();
- if (all)
- command.setListMode(ListMode.ALL);
- else if (remote)
- command.setListMode(ListMode.REMOTE);
-
- if (containsCommitish != null)
- command.setContains(containsCommitish);
-
- List<Ref> refs = command.call();
- for (Ref ref : refs) {
- if (ref.getName().equals(Constants.HEAD))
- addRef("(no branch)", head); //$NON-NLS-1$
- }
+ try (Git git = new Git(db)) {
+ ListBranchCommand command = git.branchList();
+ if (all)
+ command.setListMode(ListMode.ALL);
+ else if (remote)
+ command.setListMode(ListMode.REMOTE);
+
+ if (containsCommitish != null)
+ command.setContains(containsCommitish);
+
+ List<Ref> refs = command.call();
+ for (Ref ref : refs) {
+ if (ref.getName().equals(Constants.HEAD))
+ addRef("(no branch)", head); //$NON-NLS-1$
+ }
- addRefs(refs, Constants.R_HEADS);
- addRefs(refs, Constants.R_REMOTES);
+ addRefs(refs, Constants.R_HEADS);
+ addRefs(refs, Constants.R_REMOTES);
- try (ObjectReader reader = db.newObjectReader()) {
- for (final Entry<String, Ref> e : printRefs.entrySet()) {
- final Ref ref = e.getValue();
- printHead(reader, e.getKey(),
- current.equals(ref.getName()), ref);
+ try (ObjectReader reader = db.newObjectReader()) {
+ for (Entry<String, Ref> e : printRefs.entrySet()) {
+ final Ref ref = e.getValue();
+ printHead(reader, e.getKey(),
+ current.equals(ref.getName()), ref);
+ }
}
}
}
}
- private void addRefs(final Collection<Ref> refs, final String prefix) {
- for (final Ref ref : RefComparator.sort(refs)) {
+ private void addRefs(Collection<Ref> refs, String prefix) {
+ for (Ref ref : RefComparator.sort(refs)) {
final String name = ref.getName();
if (name.startsWith(prefix))
addRef(name.substring(name.indexOf('/', 5) + 1), ref);
}
}
- private void addRef(final String name, final Ref ref) {
+ private void addRef(String name, Ref ref) {
printRefs.put(name, ref);
maxNameLength = Math.max(maxNameLength, name.length());
}
private void printHead(final ObjectReader reader, final String ref,
- final boolean isCurrent, final Ref refObj) throws Exception {
+ final boolean isCurrent, final Ref refObj) throws IOException {
outw.print(isCurrent ? '*' : ' ');
outw.print(' ');
outw.print(ref);
@@ -243,27 +307,28 @@ class Branch extends TextBuiltin {
outw.println();
}
- private void delete(boolean force) throws IOException {
+ private void delete(List<String> branches, boolean force)
+ throws IOException {
String current = db.getBranch();
ObjectId head = db.resolve(Constants.HEAD);
- for (String branch : branches) {
- if (current.equals(branch)) {
- throw die(MessageFormat.format(CLIText.get().cannotDeleteTheBranchWhichYouAreCurrentlyOn, branch));
+ for (String b : branches) {
+ if (b.equals(current)) {
+ throw die(MessageFormat.format(CLIText.get().cannotDeleteTheBranchWhichYouAreCurrentlyOn, b));
}
RefUpdate update = db.updateRef((remote ? Constants.R_REMOTES
: Constants.R_HEADS)
- + branch);
+ + b);
update.setNewObjectId(head);
update.setForceUpdate(force || remote);
Result result = update.delete();
if (result == Result.REJECTED) {
- throw die(MessageFormat.format(CLIText.get().branchIsNotAnAncestorOfYourCurrentHEAD, branch));
+ throw die(MessageFormat.format(CLIText.get().branchIsNotAnAncestorOfYourCurrentHEAD, b));
} else if (result == Result.NEW)
- throw die(MessageFormat.format(CLIText.get().branchNotFound, branch));
+ throw die(MessageFormat.format(CLIText.get().branchNotFound, b));
if (remote)
- outw.println(MessageFormat.format(CLIText.get().deletedRemoteBranch, branch));
+ outw.println(MessageFormat.format(CLIText.get().deletedRemoteBranch, b));
else if (verbose)
- outw.println(MessageFormat.format(CLIText.get().deletedBranch, branch));
+ outw.println(MessageFormat.format(CLIText.get().deletedBranch, b));
}
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java
index 56d4fcff02..7a218ec926 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java
@@ -1,45 +1,12 @@
/*
* Copyright (C) 2010, 2012 Chris Aniszczyk <caniszczyk@gmail.com>
- * Copyright (C) 2013, Obeo
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2013, Obeo and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
@@ -51,16 +18,18 @@ import java.util.List;
import org.eclipse.jgit.api.CheckoutCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.CheckoutConflictException;
+import org.eclipse.jgit.api.errors.InvalidRefNameException;
import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
import org.eclipse.jgit.api.errors.RefNotFoundException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.TextProgressMonitor;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
-import org.kohsuke.args4j.spi.StopOptionHandler;
+import org.kohsuke.args4j.spi.RestOfArgumentsHandler;
@Command(common = true, usage = "usage_checkout")
class Checkout extends TextBuiltin {
@@ -68,18 +37,20 @@ class Checkout extends TextBuiltin {
@Option(name = "-b", usage = "usage_createBranchAndCheckout")
private boolean createBranch = false;
+ @Option(name = "-B", usage = "usage_forcedSwitchBranch")
+ private boolean forceSwitchBranch = false;
+
@Option(name = "--force", aliases = { "-f" }, usage = "usage_forceCheckout")
- private boolean force = false;
+ private boolean forced = false;
@Option(name = "--orphan", usage = "usage_orphan")
private boolean orphan = false;
- @Argument(required = true, index = 0, metaVar = "metaVar_name", usage = "usage_checkout")
+ @Argument(required = false, index = 0, metaVar = "metaVar_name", usage = "usage_checkout")
private String name;
- @Argument(index = 1)
- @Option(name = "--", metaVar = "metaVar_paths", multiValued = true, handler = StopOptionHandler.class)
- private List<String> paths = new ArrayList<String>();
+ @Option(name = "--", metaVar = "metaVar_paths", handler = RestOfArgumentsHandler.class)
+ private List<String> paths = new ArrayList<>();
@Override
protected void run() throws Exception {
@@ -89,47 +60,67 @@ class Checkout extends TextBuiltin {
throw die(CLIText.get().onBranchToBeBorn);
}
- CheckoutCommand command = new Git(db).checkout();
- if (paths.size() > 0) {
- command.setStartPoint(name);
- for (String path : paths)
- command.addPath(path);
- } else {
- command.setCreateBranch(createBranch);
- command.setName(name);
- command.setForce(force);
- command.setOrphan(orphan);
- }
- try {
- String oldBranch = db.getBranch();
- Ref ref = command.call();
- if (ref == null)
- return;
- if (Repository.shortenRefName(ref.getName()).equals(oldBranch)) {
- outw.println(MessageFormat.format(
- CLIText.get().alreadyOnBranch,
- name));
- return;
+ try (Git git = new Git(db)) {
+ CheckoutCommand command = git.checkout()
+ .setProgressMonitor(new TextProgressMonitor(errw));
+ if (!paths.isEmpty()) {
+ command.setStartPoint(name);
+ if (paths.size() == 1 && paths.get(0).equals(".")) { //$NON-NLS-1$
+ command.setAllPaths(true);
+ } else {
+ command.addPaths(paths);
+ }
+ } else {
+ command.setCreateBranch(createBranch);
+ command.setName(name);
+ command.setForceRefUpdate(forceSwitchBranch);
+ command.setForced(forced);
+ command.setOrphan(orphan);
+ }
+ try {
+ String oldBranch = db.getBranch();
+ Ref ref = command.call();
+ if (ref == null)
+ return;
+ if (Repository.shortenRefName(ref.getName()).equals(oldBranch)) {
+ outw.println(MessageFormat.format(
+ CLIText.get().alreadyOnBranch,
+ name));
+ return;
+ }
+ if (createBranch || orphan)
+ outw.println(MessageFormat.format(
+ CLIText.get().switchedToNewBranch, name));
+ else
+ outw.println(MessageFormat.format(
+ CLIText.get().switchedToBranch,
+ Repository.shortenRefName(ref.getName())));
+ } catch (InvalidRefNameException e){
+ if (name == null){
+ throw die(MessageFormat
+ .format("a valid ref is expected",e));
+ } else {
+ throw die(MessageFormat
+ .format(CLIText.get().notAValidRefName, name, e));
+ }
+ }
+ catch (RefNotFoundException e) {
+ throw die(MessageFormat
+ .format(CLIText.get().pathspecDidNotMatch, name), e);
+ } catch (RefAlreadyExistsException e) {
+ throw die(MessageFormat
+ .format(CLIText.get().branchAlreadyExists, name), e);
+ } catch (CheckoutConflictException e) {
+ StringBuilder builder = new StringBuilder();
+ builder.append(CLIText.get().checkoutConflict);
+ builder.append(System.lineSeparator());
+ for (String path : e.getConflictingPaths()) {
+ builder.append(MessageFormat.format(
+ CLIText.get().checkoutConflictPathLine, path));
+ builder.append(System.lineSeparator());
+ }
+ throw die(builder.toString(), e);
}
- if (createBranch || orphan)
- outw.println(MessageFormat.format(
- CLIText.get().switchedToNewBranch, name));
- else
- outw.println(MessageFormat.format(
- CLIText.get().switchedToBranch,
- Repository.shortenRefName(ref.getName())));
- } catch (RefNotFoundException e) {
- outw.println(MessageFormat.format(
- CLIText.get().pathspecDidNotMatch,
- name));
- } catch (RefAlreadyExistsException e) {
- throw die(MessageFormat.format(CLIText.get().branchAlreadyExists,
- name));
- } catch (CheckoutConflictException e) {
- outw.println(CLIText.get().checkoutConflict);
- for (String path : e.getConflictingPaths())
- outw.println(MessageFormat.format(
- CLIText.get().checkoutConflictPathLine, path));
}
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clean.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clean.java
new file mode 100644
index 0000000000..348f2e7dbb
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clean.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016, Ned Twigg <ned.twigg@diffplug.com> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.pgm;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.Set;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.errors.NoWorkTreeException;
+import org.eclipse.jgit.pgm.internal.CLIText;
+import org.kohsuke.args4j.Option;
+
+@Command(common = true, usage = "usage_Clean")
+class Clean extends TextBuiltin {
+ @Option(name = "-d", usage = "usage_removeUntrackedDirectories")
+ private boolean dirs = false;
+
+ @Option(name = "--force", aliases = {
+ "-f" }, usage = "usage_forceClean")
+ private boolean force = false;
+
+ @Option(name = "--dryRun", aliases = { "-n" })
+ private boolean dryRun = false;
+
+ @Override
+ protected void run() {
+ try (Git git = new Git(db)) {
+ boolean requireForce = git.getRepository().getConfig()
+ .getBoolean("clean", "requireForce", true); //$NON-NLS-1$ //$NON-NLS-2$
+ if (requireForce && !(force || dryRun)) {
+ throw die(CLIText.fatalError(CLIText.get().cleanRequireForce));
+ }
+ // Note that CleanCommand's setForce(true) will delete
+ // .git folders. In the cgit cli, this behavior
+ // requires setting "-f" twice, not sure how to do
+ // this with args4j, so this feature is unimplemented
+ // for now.
+ Set<String> removedFiles = git.clean().setCleanDirectories(dirs)
+ .setDryRun(dryRun).call();
+ for (String removedFile : removedFiles) {
+ outw.println(MessageFormat.format(CLIText.get().removing,
+ removedFile));
+ }
+ } catch (NoWorkTreeException | GitAPIException | IOException e) {
+ throw die(e.getMessage(), e);
+ }
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java
index cd6953cb05..1efba55f05 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java
@@ -1,55 +1,30 @@
/*
- * Copyright (C) 2008-2010, Google Inc.
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008-2010, Google Inc. and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
import java.io.File;
+import java.io.IOException;
import java.text.MessageFormat;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
+import org.eclipse.jgit.api.errors.TransportException;
+import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.TextProgressMonitor;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.util.SystemReader;
@@ -57,7 +32,7 @@ import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@Command(common = true, usage = "usage_cloneRepositoryIntoNewDir")
-class Clone extends AbstractFetchCommand {
+class Clone extends AbstractFetchCommand implements CloneCommand.Callback {
@Option(name = "--origin", aliases = { "-o" }, metaVar = "metaVar_remoteName", usage = "usage_useNameInsteadOfOriginToTrackUpstream")
private String remoteName = Constants.DEFAULT_REMOTE_NAME;
@@ -70,6 +45,27 @@ class Clone extends AbstractFetchCommand {
@Option(name = "--bare", usage = "usage_bareClone")
private boolean isBare;
+ @Option(name = "--mirror", usage = "usage_mirrorClone")
+ private boolean isMirror;
+
+ @Option(name = "--quiet", usage = "usage_quiet")
+ private Boolean quiet;
+
+ @Option(name = "--depth", metaVar = "metaVar_depth", usage = "usage_depth")
+ private Integer depth = null;
+
+ @Option(name = "--shallow-since", metaVar = "metaVar_shallowSince", usage = "usage_shallowSince")
+ private Instant shallowSince = null;
+
+ @Option(name = "--shallow-exclude", metaVar = "metaVar_shallowExclude", usage = "usage_shallowExclude")
+ private List<String> shallowExcludes = new ArrayList<>();
+
+ @Option(name = "--recurse-submodules", usage = "usage_recurseSubmodules")
+ private boolean cloneSubmodules;
+
+ @Option(name = "--timeout", metaVar = "metaVar_seconds", usage = "usage_abortConnectionIfNoActivity")
+ int timeout = -1;
+
@Argument(index = 0, required = true, metaVar = "metaVar_uriish")
private String sourceUri;
@@ -91,11 +87,14 @@ class Clone extends AbstractFetchCommand {
if (localName == null) {
try {
localName = uri.getHumanishName();
+ if (isBare || isMirror) {
+ localName = localName + Constants.DOT_GIT_EXT;
+ }
localNameF = new File(SystemReader.getInstance().getProperty(
Constants.OS_USER_DIR), localName);
} catch (IllegalArgumentException e) {
throw die(MessageFormat.format(
- CLIText.get().cannotGuessLocalNameFrom, sourceUri));
+ CLIText.get().cannotGuessLocalNameFrom, sourceUri), e);
}
} else
localNameF = new File(localName);
@@ -105,24 +104,80 @@ class Clone extends AbstractFetchCommand {
CloneCommand command = Git.cloneRepository();
command.setURI(sourceUri).setRemote(remoteName).setBare(isBare)
- .setNoCheckout(noCheckout).setBranch(branch);
+ .setMirror(isMirror).setNoCheckout(noCheckout).setBranch(branch)
+ .setCloneSubmodules(cloneSubmodules).setTimeout(timeout);
+
+ if (depth != null) {
+ command.setDepth(depth.intValue());
+ }
+ if (shallowSince != null) {
+ command.setShallowSince(shallowSince);
+ }
+ for (String shallowExclude : shallowExcludes) {
+ command.addShallowExclude(shallowExclude);
+ }
command.setGitDir(gitdir == null ? null : new File(gitdir));
command.setDirectory(localNameF);
- outw.println(MessageFormat.format(CLIText.get().cloningInto, localName));
+ boolean msgs = quiet == null || !quiet.booleanValue();
+ if (msgs) {
+ command.setProgressMonitor(new TextProgressMonitor(errw))
+ .setCallback(this);
+ outw.println(MessageFormat.format(
+ CLIText.get().cloningInto, localName));
+ outw.flush();
+ }
try {
db = command.call().getRepository();
- if (db.resolve(Constants.HEAD) == null)
+ if (msgs && db.resolve(Constants.HEAD) == null)
outw.println(CLIText.get().clonedEmptyRepository);
+ } catch (TransportException e) {
+ throw die(e.getMessage(), e);
} catch (InvalidRemoteException e) {
throw die(MessageFormat.format(CLIText.get().doesNotExist,
- sourceUri));
+ sourceUri), e);
} finally {
if (db != null)
db.close();
}
+ if (msgs) {
+ outw.println();
+ outw.flush();
+ }
+ }
+
+ @Override
+ public void initializedSubmodules(Collection<String> submodules) {
+ try {
+ for (String submodule : submodules) {
+ outw.println(MessageFormat
+ .format(CLIText.get().submoduleRegistered, submodule));
+ }
+ outw.flush();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
- outw.println();
- outw.flush();
+ @Override
+ public void cloningSubmodule(String path) {
+ try {
+ outw.println(MessageFormat.format(
+ CLIText.get().cloningInto, path));
+ outw.flush();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+
+ @Override
+ public void checkingOut(AnyObjectId commit, String path) {
+ try {
+ outw.println(MessageFormat.format(CLIText.get().checkingOut,
+ path, commit.getName()));
+ outw.flush();
+ } catch (IOException e) {
+ // ignore
+ }
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Command.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Command.java
index 0562416a85..52d5782bdd 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Command.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Command.java
@@ -1,44 +1,11 @@
/*
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
@@ -50,7 +17,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
- * Annotation to document a {@link TextBuiltin}.
+ * Annotation to document a {@link org.eclipse.jgit.pgm.TextBuiltin}.
* <p>
* This is an optional annotation for TextBuiltin subclasses and it carries
* documentation forward into the runtime system describing what the command is
@@ -60,6 +27,8 @@ import java.lang.annotation.Target;
@Target( { TYPE })
public @interface Command {
/**
+ * Get the command name
+ *
* @return name the command is invoked as from the command line. If the
* (default) empty string is supplied the name will be generated
* from the class name.
@@ -67,11 +36,15 @@ public @interface Command {
public String name() default "";
/**
+ * Get command description
+ *
* @return one line description of the command's feature set.
*/
public String usage() default "";
/**
+ * If this command is considered to be commonly used
+ *
* @return true if this command is considered to be commonly used.
*/
public boolean common() default false;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java
index 2673cc887d..2a9f7acdb9 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandCatalog.java
@@ -1,68 +1,36 @@
/*
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
import java.io.BufferedReader;
import java.io.IOException;
-import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Comparator;
+import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
-import java.util.Vector;
/**
* List of all commands known by jgit's command line tools.
* <p>
- * Commands are implementations of {@link TextBuiltin}, with an optional
- * {@link Command} class annotation to insert additional documentation or
- * override the default command name (which is guessed from the class name).
+ * Commands are implementations of {@link org.eclipse.jgit.pgm.TextBuiltin},
+ * with an optional {@link org.eclipse.jgit.pgm.Command} class annotation to
+ * insert additional documentation or override the default command name (which
+ * is guessed from the class name).
* <p>
* Commands may be registered by adding them to a services file in the same JAR
* (or classes directory) as the command implementation. The service file name
@@ -85,11 +53,13 @@ public class CommandCatalog {
* was derived from the DashLowerCaseForm class name.
* @return the command instance; null if no command exists by that name.
*/
- public static CommandRef get(final String name) {
+ public static CommandRef get(String name) {
return INSTANCE.commands.get(name);
}
/**
+ * Get all commands sorted by their name
+ *
* @return all known commands, sorted by command name.
*/
public static CommandRef[] all() {
@@ -97,23 +67,22 @@ public class CommandCatalog {
}
/**
+ * Get all common commands sorted by their name
+ *
* @return all common commands, sorted by command name.
*/
public static CommandRef[] common() {
- final ArrayList<CommandRef> common = new ArrayList<CommandRef>();
- for (final CommandRef c : INSTANCE.commands.values())
+ final ArrayList<CommandRef> common = new ArrayList<>();
+ for (CommandRef c : INSTANCE.commands.values())
if (c.isCommon())
common.add(c);
return toSortedArray(common);
}
- private static CommandRef[] toSortedArray(final Collection<CommandRef> c) {
- final CommandRef[] r = c.toArray(new CommandRef[c.size()]);
- Arrays.sort(r, new Comparator<CommandRef>() {
- public int compare(final CommandRef o1, final CommandRef o2) {
- return o1.getName().compareTo(o2.getName());
- }
- });
+ private static CommandRef[] toSortedArray(Collection<CommandRef> c) {
+ final CommandRef[] r = c.toArray(new CommandRef[0]);
+ Arrays.sort(r, (CommandRef o1, CommandRef o2) -> o1.getName()
+ .compareTo(o2.getName()));
return r;
}
@@ -123,7 +92,7 @@ public class CommandCatalog {
private CommandCatalog() {
ldr = Thread.currentThread().getContextClassLoader();
- commands = new HashMap<String, CommandRef>();
+ commands = new HashMap<>();
final Enumeration<URL> catalogs = catalogs();
while (catalogs.hasMoreElements())
@@ -135,50 +104,30 @@ public class CommandCatalog {
final String pfx = "META-INF/services/"; //$NON-NLS-1$
return ldr.getResources(pfx + TextBuiltin.class.getName());
} catch (IOException err) {
- return new Vector<URL>().elements();
+ return Collections.emptyEnumeration();
}
}
- private void scan(final URL cUrl) {
- final BufferedReader cIn;
- try {
- final InputStream in = cUrl.openStream();
- cIn = new BufferedReader(new InputStreamReader(in, "UTF-8")); //$NON-NLS-1$
- } catch (IOException err) {
- // If we cannot read from the service list, go to the next.
- //
- return;
- }
-
- try {
+ private void scan(URL cUrl) {
+ try (BufferedReader cIn = new BufferedReader(
+ new InputStreamReader(cUrl.openStream(), UTF_8))) {
String line;
while ((line = cIn.readLine()) != null) {
if (line.length() > 0 && !line.startsWith("#")) //$NON-NLS-1$
load(line);
}
- } catch (IOException err) {
- // If we failed during a read, ignore the error.
- //
- } finally {
- try {
- cIn.close();
- } catch (IOException e) {
- // Ignore the close error; we are only reading.
- }
+ } catch (IOException e) {
+ // Ignore errors
}
}
- private void load(final String cn) {
+ private void load(String cn) {
final Class<? extends TextBuiltin> clazz;
try {
clazz = Class.forName(cn, false, ldr).asSubclass(TextBuiltin.class);
- } catch (ClassNotFoundException notBuiltin) {
+ } catch (ClassNotFoundException | ClassCastException notBuiltin) {
// Doesn't exist, even though the service entry is present.
- //
- return;
- } catch (ClassCastException notBuiltin) {
// Isn't really a builtin, even though its listed as such.
- //
return;
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandRef.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandRef.java
index 52225150a5..fb5a8fffc1 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandRef.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CommandRef.java
@@ -1,44 +1,11 @@
/*
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
@@ -50,7 +17,8 @@ import java.text.MessageFormat;
import org.eclipse.jgit.pgm.internal.CLIText;
/**
- * Description of a command (a {@link TextBuiltin} subclass.
+ * Description of a command (a {@link org.eclipse.jgit.pgm.TextBuiltin}
+ * subclass).
* <p>
* These descriptions are lightweight compared to creating a command instance
* and are therefore suitable for catalogs of "known" commands without linking
@@ -65,29 +33,29 @@ public class CommandRef {
boolean common;
- CommandRef(final Class<? extends TextBuiltin> clazz) {
+ CommandRef(Class<? extends TextBuiltin> clazz) {
this(clazz, guessName(clazz));
}
- CommandRef(final Class<? extends TextBuiltin> clazz, final Command cmd) {
+ CommandRef(Class<? extends TextBuiltin> clazz, Command cmd) {
this(clazz, cmd.name().length() > 0 ? cmd.name() : guessName(clazz));
usage = cmd.usage();
common = cmd.common();
}
- private CommandRef(final Class<? extends TextBuiltin> clazz, final String cn) {
+ private CommandRef(Class<? extends TextBuiltin> clazz, String cn) {
impl = clazz;
name = cn;
usage = ""; //$NON-NLS-1$
}
- private static String guessName(final Class<? extends TextBuiltin> clazz) {
+ private static String guessName(Class<? extends TextBuiltin> clazz) {
final StringBuilder s = new StringBuilder();
if (clazz.getName().startsWith("org.eclipse.jgit.pgm.debug.")) //$NON-NLS-1$
s.append("debug-"); //$NON-NLS-1$
boolean lastWasDash = true;
- for (final char c : clazz.getSimpleName().toCharArray()) {
+ for (char c : clazz.getSimpleName().toCharArray()) {
if (Character.isUpperCase(c)) {
if (!lastWasDash)
s.append('-');
@@ -102,6 +70,8 @@ public class CommandRef {
}
/**
+ * Get the <code>name</code>.
+ *
* @return name the command is invoked as from the command line.
*/
public String getName() {
@@ -109,6 +79,8 @@ public class CommandRef {
}
/**
+ * Get <code>usage</code>.
+ *
* @return one line description of the command's feature set.
*/
public String getUsage() {
@@ -116,6 +88,8 @@ public class CommandRef {
}
/**
+ * Is this command commonly used
+ *
* @return true if this command is considered to be commonly used.
*/
public boolean isCommon() {
@@ -123,6 +97,8 @@ public class CommandRef {
}
/**
+ * Get implementation class name
+ *
* @return name of the Java class which implements this command.
*/
public String getImplementationClassName() {
@@ -130,6 +106,8 @@ public class CommandRef {
}
/**
+ * Get implementation class loader
+ *
* @return loader for {@link #getImplementationClassName()}.
*/
public ClassLoader getImplementationClassLoader() {
@@ -137,32 +115,37 @@ public class CommandRef {
}
/**
+ * Create an instance of the command implementation
+ *
* @return a new instance of the command implementation.
*/
public TextBuiltin create() {
final Constructor<? extends TextBuiltin> c;
try {
c = impl.getDeclaredConstructor();
- } catch (SecurityException e) {
- throw new RuntimeException(MessageFormat.format(CLIText.get().cannotCreateCommand, getName(), e));
- } catch (NoSuchMethodException e) {
- throw new RuntimeException(MessageFormat.format(CLIText.get().cannotCreateCommand, getName(), e));
+ } catch (SecurityException | NoSuchMethodException e) {
+ throw new RuntimeException(MessageFormat
+ .format(CLIText.get().cannotCreateCommand, getName(), e));
}
c.setAccessible(true);
final TextBuiltin r;
try {
r = c.newInstance();
- } catch (InstantiationException e) {
- throw new RuntimeException(MessageFormat.format(CLIText.get().cannotCreateCommand, getName(), e));
- } catch (IllegalAccessException e) {
- throw new RuntimeException(MessageFormat.format(CLIText.get().cannotCreateCommand, getName(), e));
- } catch (IllegalArgumentException e) {
- throw new RuntimeException(MessageFormat.format(CLIText.get().cannotCreateCommand, getName(), e));
- } catch (InvocationTargetException e) {
- throw new RuntimeException(MessageFormat.format(CLIText.get().cannotCreateCommand, getName(), e));
+ } catch (InstantiationException | IllegalAccessException
+ | IllegalArgumentException | InvocationTargetException e) {
+ throw new RuntimeException(MessageFormat
+ .format(CLIText.get().cannotCreateCommand, getName(), e));
}
r.setCommandName(getName());
return r;
}
+
+ @SuppressWarnings("nls")
+ @Override
+ public String toString() {
+ return "CommandRef [impl=" + impl + ", name=" + name + ", usage="
+ + CLIText.get().resourceBundle().getString(usage) + ", common="
+ + common + "]";
+ }
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java
index 14c449a6b3..8df028d2e2 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java
@@ -37,18 +37,18 @@
*/
package org.eclipse.jgit.pgm;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.api.errors.NoHeadException;
-import org.eclipse.jgit.api.errors.NoMessageException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.pgm.opt.GpgSignHandler;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.util.RawParseUtils;
import org.kohsuke.args4j.Argument;
@@ -74,43 +74,72 @@ class Commit extends TextBuiltin {
@Option(name = "--amend", usage = "usage_CommitAmend")
private boolean amend;
+ @Option(name = "--gpg-sign", aliases = { "-S" }, forbids = {
+ "--no-gpg-sign" }, handler = GpgSignHandler.class)
+ private String gpgSigningKey;
+
+ @Option(name = "--no-gpg-sign", forbids = { "--gpg-sign" })
+ private boolean noGpgSign;
+
@Argument(metaVar = "metaVar_commitPaths", usage = "usage_CommitPaths")
- private List<String> paths = new ArrayList<String>();
+ private List<String> paths = new ArrayList<>();
@Override
- protected void run() throws NoHeadException, NoMessageException,
- ConcurrentRefUpdateException, JGitInternalException, Exception {
- CommitCommand commitCmd = new Git(db).commit();
- if (author != null)
- commitCmd.setAuthor(RawParseUtils.parsePersonIdent(author));
- if (message != null)
- commitCmd.setMessage(message);
- if (only && paths.isEmpty())
- throw die(CLIText.get().pathsRequired);
- if (only && all)
- throw die(CLIText.get().onlyOneOfIncludeOnlyAllInteractiveCanBeUsed);
- if (!paths.isEmpty())
- for (String p : paths)
- commitCmd.setOnly(p);
- commitCmd.setAmend(amend);
- commitCmd.setAll(all);
- Ref head = db.getRef(Constants.HEAD);
- RevCommit commit;
- try {
- commit = commitCmd.call();
- } catch (JGitInternalException e) {
- throw die(e.getMessage());
- }
+ protected void run() {
+ try (Git git = new Git(db)) {
+ CommitCommand commitCmd = git.commit();
+ if (author != null) {
+ commitCmd.setAuthor(RawParseUtils.parsePersonIdent(author));
+ }
+ if (message != null) {
+ commitCmd.setMessage(message);
+ }
+ if (noGpgSign) {
+ commitCmd.setSign(Boolean.FALSE);
+ } else if (gpgSigningKey != null) {
+ commitCmd.setSign(Boolean.TRUE);
+ if (!gpgSigningKey.equals(GpgSignHandler.DEFAULT)) {
+ commitCmd.setSigningKey(gpgSigningKey);
+ }
+ }
+ if (only && paths.isEmpty()) {
+ throw die(CLIText.get().pathsRequired);
+ }
+ if (only && all) {
+ throw die(CLIText.get().onlyOneCommitOptionAllowed);
+ }
+ if (!paths.isEmpty()) {
+ for (String p : paths) {
+ commitCmd.setOnly(p);
+ }
+ }
+ commitCmd.setAmend(amend);
+ commitCmd.setAll(all);
+ Ref head = db.exactRef(Constants.HEAD);
+ if (head == null) {
+ throw die(CLIText.get().onBranchToBeBorn);
+ }
+ RevCommit commit;
+ try {
+ commit = commitCmd.call();
+ } catch (JGitInternalException | GitAPIException e) {
+ throw die(e.getMessage(), e);
+ }
- String branchName;
- if (!head.isSymbolic())
- branchName = CLIText.get().branchDetachedHEAD;
- else {
- branchName = head.getTarget().getName();
- if (branchName.startsWith(Constants.R_HEADS))
- branchName = branchName.substring(Constants.R_HEADS.length());
+ String branchName;
+ if (!head.isSymbolic()) {
+ branchName = CLIText.get().branchDetachedHEAD;
+ } else {
+ branchName = head.getTarget().getName();
+ if (branchName.startsWith(Constants.R_HEADS)) {
+ branchName = branchName
+ .substring(Constants.R_HEADS.length());
+ }
+ }
+ outw.println('[' + branchName + ' ' + commit.name() + "] " //$NON-NLS-1$
+ + commit.getShortMessage());
+ } catch (IOException e) {
+ throw die(e.getMessage(), e);
}
- outw.println("[" + branchName + " " + commit.name() + "] " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- + commit.getShortMessage());
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Config.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Config.java
index 8569e9278e..f5de7045d0 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Config.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Config.java
@@ -42,9 +42,9 @@ import java.io.IOException;
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;
-import org.eclipse.jgit.errors.NotSupportedException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.StringUtils;
@@ -69,12 +69,15 @@ class Config extends TextBuiltin {
private File configFile;
@Override
- protected void run() throws Exception {
- if (list)
+ protected void run() {
+ if (!list) {
+ throw die(CLIText.get().configOnlyListOptionSupported);
+ }
+ try {
list();
- else
- throw new NotSupportedException(
- "only --list option is currently supported");
+ } catch (IOException | ConfigInvalidException e) {
+ throw die(e.getMessage(), e);
+ }
}
private void list() throws IOException, ConfigInvalidException {
@@ -91,7 +94,7 @@ class Config extends TextBuiltin {
if (global || isListAll())
list(SystemReader.getInstance().openUserConfig(null, fs));
if (local || isListAll())
- list(new FileBasedConfig(fs.resolve(getRepository().getDirectory(),
+ list(new FileBasedConfig(fs.resolve(getRepository().getCommonDirectory(),
Constants.CONFIG), fs));
}
@@ -122,4 +125,4 @@ class Config extends TextBuiltin {
}
}
}
-} \ No newline at end of file
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ConvertRefStorage.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ConvertRefStorage.java
new file mode 100644
index 0000000000..06e37da841
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ConvertRefStorage.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019, Google LLC and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.pgm;
+
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.kohsuke.args4j.Option;
+import org.kohsuke.args4j.spi.ExplicitBooleanOptionHandler;
+
+@Command(common = true, usage = "usage_convertRefStorage")
+class ConvertRefStorage extends TextBuiltin {
+
+ @Option(name = "--format", usage = "usage_convertRefStorageFormat")
+ private String format = "reftable"; //$NON-NLS-1$
+
+ @Option(name = "--backup", handler = ExplicitBooleanOptionHandler.class, aliases = {
+ "-b" }, usage = "usage_convertRefStorageBackup")
+ private boolean backup = true;
+
+ @Option(name = "--reflogs", handler = ExplicitBooleanOptionHandler.class, aliases = {
+ "-r" }, usage = "usage_convertRefStorageRefLogs")
+ private boolean writeLogs = true;
+
+ @Override
+ protected void run() throws Exception {
+ ((FileRepository) db).convertRefStorage(format, writeLogs, backup);
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java
index 04182d6dbe..ec201a55ef 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java
@@ -1,55 +1,25 @@
/*
- * Copyright (C) 2008-2009, Google Inc.
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008-2009, Google Inc. and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
import java.io.File;
+import java.io.IOException;
import java.net.InetSocketAddress;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.storage.file.WindowCacheConfig;
@@ -58,6 +28,7 @@ import org.eclipse.jgit.transport.DaemonClient;
import org.eclipse.jgit.transport.DaemonService;
import org.eclipse.jgit.transport.resolver.FileResolver;
import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.SystemReader;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@@ -75,23 +46,23 @@ class Daemon extends TextBuiltin {
@Option(name = "--timeout", metaVar = "metaVar_seconds", usage = "usage_abortConnectionIfNoActivity")
int timeout = -1;
- @Option(name = "--enable", metaVar = "metaVar_service", usage = "usage_enableTheServiceInAllRepositories", multiValued = true)
- final List<String> enable = new ArrayList<String>();
+ @Option(name = "--enable", metaVar = "metaVar_service", usage = "usage_enableTheServiceInAllRepositories")
+ List<String> enable = new ArrayList<>();
- @Option(name = "--disable", metaVar = "metaVar_service", usage = "usage_disableTheServiceInAllRepositories", multiValued = true)
- final List<String> disable = new ArrayList<String>();
+ @Option(name = "--disable", metaVar = "metaVar_service", usage = "usage_disableTheServiceInAllRepositories")
+ List<String> disable = new ArrayList<>();
- @Option(name = "--allow-override", metaVar = "metaVar_service", usage = "usage_configureTheServiceInDaemonServicename", multiValued = true)
- final List<String> canOverride = new ArrayList<String>();
+ @Option(name = "--allow-override", metaVar = "metaVar_service", usage = "usage_configureTheServiceInDaemonServicename")
+ List<String> canOverride = new ArrayList<>();
- @Option(name = "--forbid-override", metaVar = "metaVar_service", usage = "usage_configureTheServiceInDaemonServicename", multiValued = true)
- final List<String> forbidOverride = new ArrayList<String>();
+ @Option(name = "--forbid-override", metaVar = "metaVar_service", usage = "usage_configureTheServiceInDaemonServicename")
+ List<String> forbidOverride = new ArrayList<>();
@Option(name = "--export-all", usage = "usage_exportWithoutGitDaemonExportOk")
boolean exportAll;
@Argument(required = true, metaVar = "metaVar_directory", usage = "usage_directoriesToExport")
- final List<File> directory = new ArrayList<File>();
+ List<File> directory = new ArrayList<>();
@Override
protected boolean requiresRepository() {
@@ -101,19 +72,20 @@ class Daemon extends TextBuiltin {
@Override
protected void run() throws Exception {
PackConfig packConfig = new PackConfig();
-
- if (configFile != null) {
+ StoredConfig cfg;
+ if (configFile == null) {
+ cfg = getUserConfig();
+ } else {
if (!configFile.exists()) {
throw die(MessageFormat.format(
CLIText.get().configFileNotFound, //
configFile.getAbsolutePath()));
}
-
- FileBasedConfig cfg = new FileBasedConfig(configFile, FS.DETECTED);
+ cfg = new FileBasedConfig(configFile, FS.DETECTED);
+ }
cfg.load();
new WindowCacheConfig().fromConfig(cfg).install();
packConfig.fromConfig(cfg);
- }
int threads = packConfig.getThreads();
if (threads <= 0)
@@ -121,8 +93,8 @@ class Daemon extends TextBuiltin {
if (1 < threads)
packConfig.setExecutor(Executors.newFixedThreadPool(threads));
- final FileResolver<DaemonClient> resolver = new FileResolver<DaemonClient>();
- for (final File f : directory) {
+ final FileResolver<DaemonClient> resolver = new FileResolver<>();
+ for (File f : directory) {
outw.println(MessageFormat.format(CLIText.get().exporting, f.getAbsolutePath()));
resolver.exportDirectory(f);
}
@@ -137,20 +109,29 @@ class Daemon extends TextBuiltin {
if (0 <= timeout)
d.setTimeout(timeout);
- for (final String n : enable)
+ for (String n : enable)
service(d, n).setEnabled(true);
- for (final String n : disable)
+ for (String n : disable)
service(d, n).setEnabled(false);
- for (final String n : canOverride)
+ for (String n : canOverride)
service(d, n).setOverridable(true);
- for (final String n : forbidOverride)
+ for (String n : forbidOverride)
service(d, n).setOverridable(false);
-
d.start();
outw.println(MessageFormat.format(CLIText.get().listeningOn, d.getAddress()));
}
+ private StoredConfig getUserConfig() throws IOException {
+ StoredConfig userConfig = null;
+ try {
+ userConfig = SystemReader.getInstance().getUserConfig();
+ } catch (ConfigInvalidException e) {
+ throw die(e.getMessage());
+ }
+ return userConfig;
+ }
+
private static DaemonService service(
final org.eclipse.jgit.transport.Daemon d,
final String n) {
@@ -159,4 +140,4 @@ class Daemon extends TextBuiltin {
throw die(MessageFormat.format(CLIText.get().serviceNotSupported, n));
return svc;
}
-} \ No newline at end of file
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java
index 901e5604ae..2633336e12 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Describe.java
@@ -1,50 +1,23 @@
/*
- * Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
import org.eclipse.jgit.api.DescribeCommand;
import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.RefNotFoundException;
+import org.eclipse.jgit.errors.InvalidPatternException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.kohsuke.args4j.Argument;
@@ -59,22 +32,53 @@ class Describe extends TextBuiltin {
@Option(name = "--long", usage = "usage_LongFormat")
private boolean longDesc;
+ @Option(name = "--all", usage = "usage_UseTags")
+ private boolean useAll;
+
+ @Option(name = "--tags", usage = "usage_UseTags")
+ private boolean useTags;
+
+ @Option(name = "--always", usage = "usage_AlwaysFallback")
+ private boolean always;
+
+ @Option(name = "--match", usage = "usage_Match", metaVar = "metaVar_pattern")
+ private List<String> patterns = new ArrayList<>();
+
+ @Option(name = "--exclude", usage = "usage_Exclude", metaVar = "metaVar_pattern")
+ private List<String> excludes = new ArrayList<>();
+
+ @Option(name = "--abbrev", usage = "usage_Abbrev")
+ private Integer abbrev;
+
@Override
- protected void run() throws Exception {
- DescribeCommand cmd = new Git(db).describe();
- if (tree != null)
- cmd.setTarget(tree);
- cmd.setLong(longDesc);
- String result = null;
- try {
- result = cmd.call();
- } catch (RefNotFoundException e) {
- throw die(CLIText.get().noNamesFound, e);
- }
- if (result == null)
- throw die(CLIText.get().noNamesFound);
+ protected void run() {
+ try (Git git = new Git(db)) {
+ DescribeCommand cmd = git.describe();
+ if (tree != null) {
+ cmd.setTarget(tree);
+ }
+ cmd.setLong(longDesc);
+ cmd.setAll(useAll);
+ cmd.setTags(useTags);
+ cmd.setAlways(always);
+ cmd.setMatch(patterns.toArray(new String[0]));
+ cmd.setExclude(excludes.toArray(new String[0]));
+ if (abbrev != null) {
+ cmd.setAbbrev(abbrev.intValue());
+ }
+ String result = null;
+ try {
+ result = cmd.call();
+ } catch (RefNotFoundException e) {
+ throw die(CLIText.get().noNamesFound, e);
+ }
+ if (result == null) {
+ throw die(CLIText.get().noNamesFound);
+ }
- outw.println(result);
+ outw.println(result);
+ } catch (IOException | InvalidPatternException | GitAPIException e) {
+ throw die(e.getMessage(), e);
+ }
}
-
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Die.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Die.java
index f07df1a4b5..365cf6f158 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Die.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Die.java
@@ -1,51 +1,19 @@
/*
* Copyright (C) 2009, Google Inc.
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
/**
- * Indicates a {@link TextBuiltin} implementation has failed during execution.
+ * Indicates a {@link org.eclipse.jgit.pgm.TextBuiltin} implementation has
+ * failed during execution.
* <p>
* Typically the stack trace for a Die exception is not shown to the user as it
* may indicate a simple error condition that the end-user can fix on their own,
@@ -62,7 +30,7 @@ public class Die extends RuntimeException {
* @param why
* the message to show to the end-user.
*/
- public Die(final String why) {
+ public Die(String why) {
super(why);
}
@@ -74,7 +42,7 @@ public class Die extends RuntimeException {
* @param cause
* why the command has failed.
*/
- public Die(final String why, final Throwable cause) {
+ public Die(String why, Throwable cause) {
super(why, cause);
}
@@ -86,6 +54,21 @@ public class Die extends RuntimeException {
* @since 3.4
*/
public Die(boolean aborted) {
+ this(aborted, null);
+ }
+
+ /**
+ * Construct a new exception reflecting the fact that the command execution
+ * has been aborted before running.
+ *
+ * @param aborted
+ * boolean indicating the fact the execution has been aborted
+ * @param cause
+ * can be null
+ * @since 4.2
+ */
+ public Die(boolean aborted, Throwable cause) {
+ super(cause != null ? cause.getMessage() : null, cause);
this.aborted = aborted;
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Diff.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Diff.java
index 61a385df83..52665a1c71 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Diff.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Diff.java
@@ -1,51 +1,17 @@
/*
* Copyright (C) 2009, Christian Halstrick <christian.halstrick@sap.com>
* Copyright (C) 2009, Johannes E. Schindelin
- * Copyright (C) 2009, Johannes Schindelin <johannes.schindelin@gmx.de>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2009, Johannes Schindelin <johannes.schindelin@gmx.de> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
-import static java.lang.Integer.valueOf;
import static org.eclipse.jgit.lib.Constants.HEAD;
import static org.eclipse.jgit.lib.Constants.OBJECT_ID_STRING_LENGTH;
@@ -62,6 +28,7 @@ import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.RawTextComparator;
import org.eclipse.jgit.diff.RenameDetector;
import org.eclipse.jgit.dircache.DirCacheIterator;
+import org.eclipse.jgit.errors.RevisionSyntaxException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
@@ -80,16 +47,20 @@ import org.kohsuke.args4j.Option;
class Diff extends TextBuiltin {
private DiffFormatter diffFmt;
+ private boolean showNameOnly = false;
+
+ private boolean showNameAndStatusOnly = false;
+
@Argument(index = 0, metaVar = "metaVar_treeish")
private AbstractTreeIterator oldTree;
@Argument(index = 1, metaVar = "metaVar_treeish")
private AbstractTreeIterator newTree;
- @Option(name = "--cached", usage = "usage_cached")
+ @Option(name = "--cached", aliases = { "--staged" }, usage = "usage_cached")
private boolean cached;
- @Option(name = "--", metaVar = "metaVar_paths", multiValued = true, handler = PathTreeFilterHandler.class)
+ @Option(name = "--", metaVar = "metaVar_paths", handler = PathTreeFilterHandler.class)
private TreeFilter pathFilter = TreeFilter.ALL;
// BEGIN -- Options shared with Log
@@ -113,7 +84,22 @@ class Diff extends TextBuiltin {
private Integer renameLimit;
@Option(name = "--name-status", usage = "usage_nameStatus")
- private boolean showNameAndStatusOnly;
+ void nameAndStatusOnly(boolean on) {
+ if (showNameOnly) {
+ throw new IllegalArgumentException(
+ CLIText.get().cannotUseNameStatusOnlyAndNameOnly);
+ }
+ showNameAndStatusOnly = on;
+ }
+
+ @Option(name = "--name-only", usage = "usage_nameOnly")
+ void nameOnly(boolean on) {
+ if (showNameAndStatusOnly) {
+ throw new IllegalArgumentException(
+ CLIText.get().cannotUseNameStatusOnlyAndNameOnly);
+ }
+ showNameOnly = on;
+ }
@Option(name = "--ignore-space-at-eol")
void ignoreSpaceAtEol(@SuppressWarnings("unused") boolean on) {
@@ -150,12 +136,12 @@ class Diff extends TextBuiltin {
diffFmt.setAbbreviationLength(OBJECT_ID_STRING_LENGTH);
}
- @Option(name = "--src-prefix", usage = "usage_srcPrefix")
+ @Option(name = "--src-prefix", metaVar = "metaVar_prefix", usage = "usage_srcPrefix")
void sourcePrefix(String path) {
diffFmt.setOldPrefix(path);
}
- @Option(name = "--dst-prefix", usage = "usage_dstPrefix")
+ @Option(name = "--dst-prefix", metaVar = "metaVar_prefix", usage = "usage_dstPrefix")
void dstPrefix(String path) {
diffFmt.setNewPrefix(path);
}
@@ -169,20 +155,21 @@ class Diff extends TextBuiltin {
// END -- Options shared with Log
@Override
- protected void init(final Repository repository, final String gitDir) {
+ protected void init(Repository repository, String gitDir) {
super.init(repository, gitDir);
diffFmt = new DiffFormatter(new BufferedOutputStream(outs));
}
@Override
- protected void run() throws Exception {
+ protected void run() {
diffFmt.setRepository(db);
try {
if (cached) {
if (oldTree == null) {
ObjectId head = db.resolve(HEAD + "^{tree}"); //$NON-NLS-1$
- if (head == null)
+ if (head == null) {
die(MessageFormat.format(CLIText.get().notATree, HEAD));
+ }
CanonicalTreeParser p = new CanonicalTreeParser();
try (ObjectReader reader = db.newObjectReader()) {
p.reset(reader, head);
@@ -193,15 +180,17 @@ class Diff extends TextBuiltin {
} else if (oldTree == null) {
oldTree = new DirCacheIterator(db.readDirCache());
newTree = new FileTreeIterator(db);
- } else if (newTree == null)
+ } else if (newTree == null) {
newTree = new FileTreeIterator(db);
+ }
TextProgressMonitor pm = new TextProgressMonitor(errw);
pm.setDelayStart(2, TimeUnit.SECONDS);
diffFmt.setProgressMonitor(pm);
diffFmt.setPathFilter(pathFilter);
- if (detectRenames != null)
+ if (detectRenames != null) {
diffFmt.setDetectRenames(detectRenames.booleanValue());
+ }
if (renameLimit != null && diffFmt.isDetectRenames()) {
RenameDetector rd = diffFmt.getRenameDetector();
rd.setRenameLimit(renameLimit.intValue());
@@ -210,11 +199,15 @@ class Diff extends TextBuiltin {
if (showNameAndStatusOnly) {
nameStatus(outw, diffFmt.scan(oldTree, newTree));
outw.flush();
-
+ } else if(showNameOnly) {
+ nameOnly(outw, diffFmt.scan(oldTree, newTree));
+ outw.flush();
} else {
diffFmt.format(oldTree, newTree);
diffFmt.flush();
}
+ } catch (RevisionSyntaxException | IOException e) {
+ throw die(e.getMessage(), e);
} finally {
diffFmt.close();
}
@@ -234,16 +227,41 @@ class Diff extends TextBuiltin {
out.println("M\t" + ent.getNewPath()); //$NON-NLS-1$
break;
case COPY:
- out.format("C%1$03d\t%2$s\t%3$s", valueOf(ent.getScore()), // //$NON-NLS-1$
- ent.getOldPath(), ent.getNewPath());
+ out.format("C%1$03d\t%2$s\t%3$s", //$NON-NLS-1$
+ Integer.valueOf(ent.getScore()), ent.getOldPath(),
+ ent.getNewPath());
out.println();
break;
case RENAME:
- out.format("R%1$03d\t%2$s\t%3$s", valueOf(ent.getScore()), // //$NON-NLS-1$
- ent.getOldPath(), ent.getNewPath());
+ out.format("R%1$03d\t%2$s\t%3$s", //$NON-NLS-1$
+ Integer.valueOf(ent.getScore()), ent.getOldPath(),
+ ent.getNewPath());
out.println();
break;
}
}
}
+
+ static void nameOnly(ThrowingPrintWriter out, List<DiffEntry> files)
+ throws IOException {
+ for (DiffEntry ent : files) {
+ switch (ent.getChangeType()) {
+ case ADD:
+ out.println(ent.getNewPath());
+ break;
+ case DELETE:
+ out.println(ent.getOldPath());
+ break;
+ case MODIFY:
+ out.println(ent.getNewPath());
+ break;
+ case COPY:
+ out.println(ent.getNewPath());
+ break;
+ case RENAME:
+ out.println(ent.getNewPath());
+ break;
+ }
+ }
+ }
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTool.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTool.java
new file mode 100644
index 0000000000..87c71795ec
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTool.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2018-2022, Andre Bossert <andre.bossert@siemens.com>
+ * Copyright (C) 2019, Tim Neumann <tim.neumann@advantest.com>
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.pgm;
+
+import static org.eclipse.jgit.lib.Constants.HEAD;
+import static org.eclipse.jgit.treewalk.TreeWalk.OperationType.CHECKOUT_OP;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jgit.diff.ContentSource;
+import org.eclipse.jgit.diff.ContentSource.Pair;
+import org.eclipse.jgit.diff.DiffEntry;
+import org.eclipse.jgit.diff.DiffEntry.Side;
+import org.eclipse.jgit.diff.DiffFormatter;
+import org.eclipse.jgit.dircache.DirCacheCheckout;
+import org.eclipse.jgit.dircache.DirCacheCheckout.CheckoutMetadata;
+import org.eclipse.jgit.dircache.DirCacheIterator;
+import org.eclipse.jgit.errors.AmbiguousObjectException;
+import org.eclipse.jgit.errors.CorruptObjectException;
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.NoWorkTreeException;
+import org.eclipse.jgit.errors.RevisionSyntaxException;
+import org.eclipse.jgit.internal.diffmergetool.DiffTools;
+import org.eclipse.jgit.internal.diffmergetool.ExternalDiffTool;
+import org.eclipse.jgit.internal.diffmergetool.FileElement;
+import org.eclipse.jgit.internal.diffmergetool.PromptContinueHandler;
+import org.eclipse.jgit.internal.diffmergetool.ToolException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.CoreConfig.EolStreamType;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.TextProgressMonitor;
+import org.eclipse.jgit.lib.internal.BooleanTriState;
+import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.pgm.opt.PathTreeFilterHandler;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.AbstractTreeIterator;
+import org.eclipse.jgit.treewalk.CanonicalTreeParser;
+import org.eclipse.jgit.treewalk.FileTreeIterator;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.WorkingTreeIterator;
+import org.eclipse.jgit.treewalk.WorkingTreeOptions;
+import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
+import org.eclipse.jgit.util.FS.ExecutionResult;
+import org.eclipse.jgit.util.SystemReader;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+
+@Command(name = "difftool", common = true, usage = "usage_DiffTool")
+class DiffTool extends TextBuiltin {
+ private DiffFormatter diffFmt;
+
+ private DiffTools diffTools;
+
+ @Argument(index = 0, metaVar = "metaVar_treeish")
+ private AbstractTreeIterator oldTree;
+
+ @Argument(index = 1, metaVar = "metaVar_treeish")
+ private AbstractTreeIterator newTree;
+
+ private Optional<String> toolName = Optional.empty();
+
+ @Option(name = "--tool", aliases = {
+ "-t" }, metaVar = "metaVar_tool", usage = "usage_ToolForDiff")
+ void setToolName(String name) {
+ toolName = Optional.of(name);
+ }
+
+ @Option(name = "--cached", aliases = { "--staged" }, usage = "usage_cached")
+ private boolean cached;
+
+ private BooleanTriState prompt = BooleanTriState.UNSET;
+
+ @Option(name = "--prompt", usage = "usage_prompt")
+ void setPrompt(@SuppressWarnings("unused") boolean on) {
+ prompt = BooleanTriState.TRUE;
+ }
+
+ @Option(name = "--no-prompt", aliases = { "-y" }, usage = "usage_noPrompt")
+ void noPrompt(@SuppressWarnings("unused") boolean on) {
+ prompt = BooleanTriState.FALSE;
+ }
+
+ @Option(name = "--tool-help", usage = "usage_toolHelp")
+ private boolean toolHelp;
+
+ private boolean gui = false;
+
+ @Option(name = "--gui", aliases = { "-g" }, usage = "usage_DiffGuiTool")
+ void setGui(@SuppressWarnings("unused") boolean on) {
+ gui = true;
+ }
+
+ @Option(name = "--no-gui", usage = "usage_noGui")
+ void noGui(@SuppressWarnings("unused") boolean on) {
+ gui = false;
+ }
+
+ private BooleanTriState trustExitCode = BooleanTriState.UNSET;
+
+ @Option(name = "--trust-exit-code", usage = "usage_trustExitCode")
+ void setTrustExitCode(@SuppressWarnings("unused") boolean on) {
+ trustExitCode = BooleanTriState.TRUE;
+ }
+
+ @Option(name = "--no-trust-exit-code", usage = "usage_noTrustExitCode")
+ void noTrustExitCode(@SuppressWarnings("unused") boolean on) {
+ trustExitCode = BooleanTriState.FALSE;
+ }
+
+ @Option(name = "--", metaVar = "metaVar_paths", handler = PathTreeFilterHandler.class)
+ private TreeFilter pathFilter = TreeFilter.ALL;
+
+ private BufferedReader inputReader;
+
+ @Override
+ protected void init(Repository repository, String gitDir) {
+ super.init(repository, gitDir);
+ diffFmt = new DiffFormatter(new BufferedOutputStream(outs));
+ diffTools = new DiffTools(repository);
+ inputReader = new BufferedReader(new InputStreamReader(ins,
+ SystemReader.getInstance().getDefaultCharset()));
+ }
+
+ @Override
+ protected void run() {
+ try {
+ if (toolHelp) {
+ showToolHelp();
+ } else {
+ // get the changed files
+ List<DiffEntry> files = getFiles();
+ if (files.size() > 0) {
+ compare(files);
+ }
+ }
+ } catch (RevisionSyntaxException | IOException e) {
+ throw die(e.getMessage(), e);
+ } finally {
+ diffFmt.close();
+ }
+ }
+
+ private void informUserNoTool(List<String> tools) {
+ try {
+ StringBuilder toolNames = new StringBuilder();
+ for (String name : tools) {
+ toolNames.append(name + " "); //$NON-NLS-1$
+ }
+ outw.println(MessageFormat.format(
+ CLIText.get().diffToolPromptToolName, toolNames));
+ outw.flush();
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot output text", e); //$NON-NLS-1$
+ }
+ }
+
+ private class CountingPromptContinueHandler
+ implements PromptContinueHandler {
+ private final int fileIndex;
+
+ private final int fileCount;
+
+ private final String fileName;
+
+ public CountingPromptContinueHandler(int fileIndex, int fileCount,
+ String fileName) {
+ this.fileIndex = fileIndex;
+ this.fileCount = fileCount;
+ this.fileName = fileName;
+ }
+
+ @SuppressWarnings("boxing")
+ @Override
+ public boolean prompt(String toolToLaunchName) {
+ try {
+ boolean launchCompare = true;
+ outw.println(MessageFormat.format(CLIText.get().diffToolLaunch,
+ fileIndex, fileCount, fileName, toolToLaunchName)
+ + " "); //$NON-NLS-1$
+ outw.flush();
+ BufferedReader br = inputReader;
+ String line = null;
+ if ((line = br.readLine()) != null) {
+ if (!line.equalsIgnoreCase("Y")) { //$NON-NLS-1$
+ launchCompare = false;
+ }
+ }
+ return launchCompare;
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot output text", e); //$NON-NLS-1$
+ }
+ }
+ }
+
+ private void compare(List<DiffEntry> files) throws IOException {
+ ContentSource.Pair sourcePair = new ContentSource.Pair(source(oldTree),
+ source(newTree));
+ try {
+ for (int fileIndex = 0; fileIndex < files.size(); fileIndex++) {
+ DiffEntry ent = files.get(fileIndex);
+
+ String filePath = ent.getNewPath();
+ if (filePath.equals(DiffEntry.DEV_NULL)) {
+ filePath = ent.getOldPath();
+ }
+
+ try {
+ FileElement local = createFileElement(
+ FileElement.Type.LOCAL, sourcePair, Side.OLD, ent);
+ FileElement remote = createFileElement(
+ FileElement.Type.REMOTE, sourcePair, Side.NEW, ent);
+
+ PromptContinueHandler promptContinueHandler = new CountingPromptContinueHandler(
+ fileIndex + 1, files.size(), filePath);
+
+ Optional<ExecutionResult> optionalResult = diffTools
+ .compare(local, remote, toolName, prompt, gui,
+ trustExitCode, promptContinueHandler,
+ this::informUserNoTool);
+
+ if (optionalResult.isPresent()) {
+ ExecutionResult result = optionalResult.get();
+ // TODO: check how to return the exit-code of the tool
+ // to jgit / java runtime ?
+ // int rc =...
+ Charset defaultCharset = SystemReader.getInstance()
+ .getDefaultCharset();
+ outw.println(
+ new String(result.getStdout().toByteArray(),
+ defaultCharset));
+ outw.flush();
+ errw.println(
+ new String(result.getStderr().toByteArray(),
+ defaultCharset));
+ errw.flush();
+ }
+ } catch (ToolException e) {
+ outw.println(e.getResultStdout());
+ outw.flush();
+ errw.println(e.getMessage());
+ errw.flush();
+ throw die(MessageFormat.format(
+ CLIText.get().diffToolDied, filePath, e), e);
+ }
+ }
+ } finally {
+ sourcePair.close();
+ }
+ }
+
+ private void showToolHelp() throws IOException {
+ Map<String, ExternalDiffTool> predefTools = diffTools
+ .getPredefinedTools(true);
+ StringBuilder availableToolNames = new StringBuilder();
+ StringBuilder notAvailableToolNames = new StringBuilder();
+ for (String name : predefTools.keySet()) {
+ if (predefTools.get(name).isAvailable()) {
+ availableToolNames.append(MessageFormat.format("\t\t{0}\n", name)); //$NON-NLS-1$
+ } else {
+ notAvailableToolNames.append(MessageFormat.format("\t\t{0}\n", name)); //$NON-NLS-1$
+ }
+ }
+ StringBuilder userToolNames = new StringBuilder();
+ Map<String, ExternalDiffTool> userTools = diffTools
+ .getUserDefinedTools();
+ for (String name : userTools.keySet()) {
+ userToolNames.append(MessageFormat.format("\t\t{0}.cmd {1}\n", //$NON-NLS-1$
+ name, userTools.get(name).getCommand()));
+ }
+ outw.println(MessageFormat.format(
+ CLIText.get().diffToolHelpSetToFollowing, availableToolNames,
+ userToolNames, notAvailableToolNames));
+ }
+
+ private List<DiffEntry> getFiles()
+ throws RevisionSyntaxException, AmbiguousObjectException,
+ IncorrectObjectTypeException, IOException {
+ diffFmt.setRepository(db);
+ if (cached) {
+ if (oldTree == null) {
+ ObjectId head = db.resolve(HEAD + "^{tree}"); //$NON-NLS-1$
+ if (head == null) {
+ die(MessageFormat.format(CLIText.get().notATree, HEAD));
+ }
+ CanonicalTreeParser p = new CanonicalTreeParser();
+ try (ObjectReader reader = db.newObjectReader()) {
+ p.reset(reader, head);
+ }
+ oldTree = p;
+ }
+ newTree = new DirCacheIterator(db.readDirCache());
+ } else if (oldTree == null) {
+ oldTree = new DirCacheIterator(db.readDirCache());
+ newTree = new FileTreeIterator(db);
+ } else if (newTree == null) {
+ newTree = new FileTreeIterator(db);
+ }
+
+ TextProgressMonitor pm = new TextProgressMonitor(errw);
+ pm.setDelayStart(2, TimeUnit.SECONDS);
+ diffFmt.setProgressMonitor(pm);
+ diffFmt.setPathFilter(pathFilter);
+
+ List<DiffEntry> files = diffFmt.scan(oldTree, newTree);
+ return files;
+ }
+
+ private FileElement createFileElement(FileElement.Type elementType,
+ Pair pair, Side side, DiffEntry entry) throws NoWorkTreeException,
+ CorruptObjectException, IOException, ToolException {
+ String entryPath = side == Side.NEW ? entry.getNewPath()
+ : entry.getOldPath();
+ FileElement fileElement = new FileElement(entryPath, elementType,
+ db.getWorkTree());
+ if (!pair.isWorkingTreeSource(side) && !fileElement.isNullPath()) {
+ try (RevWalk revWalk = new RevWalk(db);
+ TreeWalk treeWalk = new TreeWalk(db,
+ revWalk.getObjectReader())) {
+ treeWalk.setFilter(
+ PathFilterGroup.createFromStrings(entryPath));
+ if (side == Side.NEW) {
+ newTree.reset();
+ treeWalk.addTree(newTree);
+ } else {
+ oldTree.reset();
+ treeWalk.addTree(oldTree);
+ }
+ if (treeWalk.next()) {
+ final EolStreamType eolStreamType = treeWalk
+ .getEolStreamType(CHECKOUT_OP);
+ final String filterCommand = treeWalk.getFilterCommand(
+ Constants.ATTR_FILTER_TYPE_SMUDGE);
+ WorkingTreeOptions opt = db.getConfig()
+ .get(WorkingTreeOptions.KEY);
+ CheckoutMetadata checkoutMetadata = new CheckoutMetadata(
+ eolStreamType, filterCommand);
+ DirCacheCheckout.getContent(db, entryPath,
+ checkoutMetadata, pair.open(side, entry), opt,
+ new FileOutputStream(
+ fileElement.createTempFile(null)));
+ } else {
+ throw new ToolException("Cannot find path '" + entryPath //$NON-NLS-1$
+ + "' in staging area!", //$NON-NLS-1$
+ null);
+ }
+ }
+ }
+ return fileElement;
+ }
+
+ private ContentSource source(AbstractTreeIterator iterator) {
+ if (iterator instanceof WorkingTreeIterator) {
+ return ContentSource.create((WorkingTreeIterator) iterator);
+ }
+ return ContentSource.create(db.newObjectReader());
+ }
+
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTree.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTree.java
index d89053c4cb..352ffde26c 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTree.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTree.java
@@ -1,60 +1,28 @@
/*
* Copyright (C) 2008, Jonas Fonseca <fonseca@diku.dk>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import org.kohsuke.args4j.Argument;
-import org.kohsuke.args4j.Option;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.pgm.opt.PathTreeFilterHandler;
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
@Command(usage = "usage_ShowDiffTree")
class DiffTree extends TextBuiltin {
@@ -67,53 +35,59 @@ class DiffTree extends TextBuiltin {
}
@Argument(index = 1, metaVar = "metaVar_treeish", required = true)
- private final List<AbstractTreeIterator> trees = new ArrayList<AbstractTreeIterator>();
+ private List<AbstractTreeIterator> trees = new ArrayList<>();
- @Option(name = "--", metaVar = "metaVar_path", multiValued = true, handler = PathTreeFilterHandler.class)
+ @Option(name = "--", metaVar = "metaVar_path", handler = PathTreeFilterHandler.class)
private TreeFilter pathFilter = TreeFilter.ALL;
@Override
- protected void run() throws Exception {
- final TreeWalk walk = new TreeWalk(db);
- walk.setRecursive(recursive);
- for (final AbstractTreeIterator i : trees)
- walk.addTree(i);
- walk.setFilter(AndTreeFilter.create(TreeFilter.ANY_DIFF, pathFilter));
+ protected void run() {
+ try (TreeWalk walk = new TreeWalk(db)) {
+ walk.setRecursive(recursive);
+ for (AbstractTreeIterator i : trees)
+ walk.addTree(i);
+ walk.setFilter(AndTreeFilter.create(TreeFilter.ANY_DIFF, pathFilter));
- final int nTree = walk.getTreeCount();
- while (walk.next()) {
- for (int i = 1; i < nTree; i++)
- outw.print(':');
- for (int i = 0; i < nTree; i++) {
- final FileMode m = walk.getFileMode(i);
- final String s = m.toString();
- for (int pad = 6 - s.length(); pad > 0; pad--)
- outw.print('0');
- outw.print(s);
- outw.print(' ');
- }
+ final int nTree = walk.getTreeCount();
+ while (walk.next()) {
+ for (int i = 1; i < nTree; i++) {
+ outw.print(':');
+ }
+ for (int i = 0; i < nTree; i++) {
+ final FileMode m = walk.getFileMode(i);
+ final String s = m.toString();
+ for (int pad = 6 - s.length(); pad > 0; pad--) {
+ outw.print('0');
+ }
+ outw.print(s);
+ outw.print(' ');
+ }
- for (int i = 0; i < nTree; i++) {
- outw.print(walk.getObjectId(i).name());
- outw.print(' ');
- }
+ for (int i = 0; i < nTree; i++) {
+ outw.print(walk.getObjectId(i).name());
+ outw.print(' ');
+ }
- char chg = 'M';
- if (nTree == 2) {
- final int m0 = walk.getRawMode(0);
- final int m1 = walk.getRawMode(1);
- if (m0 == 0 && m1 != 0)
- chg = 'A';
- else if (m0 != 0 && m1 == 0)
- chg = 'D';
- else if (m0 != m1 && walk.idEqual(0, 1))
- chg = 'T';
- }
- outw.print(chg);
+ char chg = 'M';
+ if (nTree == 2) {
+ final int m0 = walk.getRawMode(0);
+ final int m1 = walk.getRawMode(1);
+ if (m0 == 0 && m1 != 0) {
+ chg = 'A';
+ } else if (m0 != 0 && m1 == 0) {
+ chg = 'D';
+ } else if (m0 != m1 && walk.idEqual(0, 1)) {
+ chg = 'T';
+ }
+ }
+ outw.print(chg);
- outw.print('\t');
- outw.print(walk.getPathString());
- outw.println();
+ outw.print('\t');
+ outw.print(walk.getPathString());
+ outw.println();
+ }
+ } catch (IOException e) {
+ throw die(e.getMessage(), e);
}
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java
index 186fdd8a22..7a007e3b58 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Fetch.java
@@ -1,56 +1,30 @@
/*
* Copyright (C) 2008-2009, Google Inc.
* Copyright (C) 2009, Mykola Nikishov <mn@mn.com.ua>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.time.Instant;
+import java.util.ArrayList;
import java.util.List;
import org.eclipse.jgit.api.FetchCommand;
import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.SubmoduleConfig.FetchRecurseSubmodulesMode;
import org.eclipse.jgit.lib.TextProgressMonitor;
+import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.transport.FetchResult;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.TagOpt;
@@ -58,7 +32,7 @@ import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@Command(common = true, usage = "usage_updateRemoteRefsFromAnotherRepository")
-class Fetch extends AbstractFetchCommand {
+class Fetch extends AbstractFetchCommand implements FetchCommand.Callback {
@Option(name = "--timeout", metaVar = "metaVar_seconds", usage = "usage_abortConnectionIfNoActivity")
int timeout = -1;
@@ -90,12 +64,49 @@ class Fetch extends AbstractFetchCommand {
@Option(name = "--tags", usage="usage_tags", aliases = { "-t" })
private Boolean tags;
+ @Option(name = "--depth", metaVar = "metaVar_depth", usage = "usage_depth")
+ private Integer depth = null;
+
+ @Option(name = "--shallow-since", metaVar = "metaVar_shallowSince", usage = "usage_shallowSince")
+ private Instant shallowSince = null;
+
+ @Option(name = "--shallow-exclude", metaVar = "metaVar_shallowExclude", usage = "usage_shallowExclude")
+ private List<String> shallowExcludes = new ArrayList<>();
+
@Option(name = "--no-tags", usage = "usage_notags", aliases = { "-n" })
void notags(@SuppressWarnings("unused")
final boolean ignored) {
tags = Boolean.FALSE;
}
+ @Option(name = "--force", usage = "usage_forcedFetch", aliases = { "-f" })
+ private Boolean force;
+
+ private FetchRecurseSubmodulesMode recurseSubmodules;
+
+ @Option(name = "--recurse-submodules", usage = "usage_recurseSubmodules")
+ void recurseSubmodules(String mode) {
+ if (mode == null || mode.isEmpty()) {
+ recurseSubmodules = FetchRecurseSubmodulesMode.YES;
+ } else {
+ for (FetchRecurseSubmodulesMode m : FetchRecurseSubmodulesMode
+ .values()) {
+ if (m.matchConfigValue(mode)) {
+ recurseSubmodules = m;
+ return;
+ }
+ }
+ throw die(MessageFormat
+ .format(CLIText.get().invalidRecurseSubmodulesMode, mode));
+ }
+ }
+
+ @Option(name = "--no-recurse-submodules", usage = "usage_noRecurseSubmodules")
+ void noRecurseSubmodules(@SuppressWarnings("unused")
+ final boolean ignored) {
+ recurseSubmodules = FetchRecurseSubmodulesMode.NO;
+ }
+
@Argument(index = 0, metaVar = "metaVar_uriish")
private String remote = Constants.DEFAULT_REMOTE_NAME;
@@ -103,32 +114,66 @@ class Fetch extends AbstractFetchCommand {
private List<RefSpec> toget;
@Override
- protected void run() throws Exception {
- Git git = new Git(db);
- FetchCommand fetch = git.fetch();
- if (fsck != null)
- fetch.setCheckFetchedObjects(fsck.booleanValue());
- if (prune != null)
- fetch.setRemoveDeletedRefs(prune.booleanValue());
- if (toget != null)
- fetch.setRefSpecs(toget);
- if (tags != null) {
- fetch.setTagOpt(tags.booleanValue() ? TagOpt.FETCH_TAGS
- : TagOpt.NO_TAGS);
+ protected void run() {
+ try (Git git = new Git(db)) {
+ FetchCommand fetch = git.fetch();
+ if (fsck != null) {
+ fetch.setCheckFetchedObjects(fsck.booleanValue());
+ }
+ if (prune != null) {
+ fetch.setRemoveDeletedRefs(prune.booleanValue());
+ }
+ if (toget != null) {
+ fetch.setRefSpecs(toget);
+ }
+ if (tags != null) {
+ fetch.setTagOpt(tags.booleanValue() ? TagOpt.FETCH_TAGS
+ : TagOpt.NO_TAGS);
+ }
+ if (depth != null) {
+ fetch.setDepth(depth.intValue());
+ }
+ if (shallowSince != null) {
+ fetch.setShallowSince(shallowSince);
+ }
+ for (String shallowExclude : shallowExcludes) {
+ fetch.addShallowExclude(shallowExclude);
+ }
+ if (0 <= timeout) {
+ fetch.setTimeout(timeout);
+ }
+ fetch.setDryRun(dryRun);
+ fetch.setRemote(remote);
+ if (thin != null) {
+ fetch.setThin(thin.booleanValue());
+ }
+ if (quiet == null || !quiet.booleanValue()) {
+ fetch.setProgressMonitor(new TextProgressMonitor(errw));
+ }
+ fetch.setRecurseSubmodules(recurseSubmodules).setCallback(this);
+ if (force != null) {
+ fetch.setForceUpdate(force.booleanValue());
+ }
+
+ FetchResult result = fetch.call();
+ if (result.getTrackingRefUpdates().isEmpty()
+ && result.submoduleResults().isEmpty()) {
+ return;
+ }
+ showFetchResult(result);
+ } catch (GitAPIException | IOException e) {
+ throw die(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public void fetchingSubmodule(String name) {
+ try {
+ outw.println(MessageFormat.format(CLIText.get().fetchingSubmodule,
+ name));
+ outw.flush();
+ } catch (IOException e) {
+ // ignore
}
- if (0 <= timeout)
- fetch.setTimeout(timeout);
- fetch.setDryRun(dryRun);
- fetch.setRemote(remote);
- if (thin != null)
- fetch.setThin(thin.booleanValue());
- if (quiet == null || !quiet.booleanValue())
- fetch.setProgressMonitor(new TextProgressMonitor(errw));
-
- FetchResult result = fetch.call();
- if (result.getTrackingRefUpdates().isEmpty())
- return;
-
- showFetchResult(result);
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Gc.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Gc.java
index bf454760af..35ac7a162a 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Gc.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Gc.java
@@ -1,49 +1,18 @@
/*
- * Copyright (C) 2012, Christian Halstrick <christian.halstrick@sap.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2012, Christian Halstrick <christian.halstrick@sap.com> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
+import org.eclipse.jgit.api.GarbageCollectCommand;
import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.TextProgressMonitor;
import org.kohsuke.args4j.Option;
@@ -52,10 +21,34 @@ class Gc extends TextBuiltin {
@Option(name = "--aggressive", usage = "usage_Aggressive")
private boolean aggressive;
+ @Option(name = "--preserve-oldpacks", usage = "usage_PreserveOldPacks")
+ private Boolean preserveOldPacks;
+
+ @Option(name = "--prune-preserved", usage = "usage_PrunePreserved")
+ private Boolean prunePreserved;
+
+ @Option(name = "--pack-kept-objects", usage = "usage_PackKeptObjects")
+ private Boolean packKeptObjects;
+
+ /** {@inheritDoc} */
@Override
- protected void run() throws Exception {
+ protected void run() {
Git git = Git.wrap(db);
- git.gc().setAggressive(aggressive)
- .setProgressMonitor(new TextProgressMonitor(errw)).call();
+ try {
+ GarbageCollectCommand command = git.gc().setAggressive(aggressive)
+ .setProgressMonitor(new TextProgressMonitor(errw));
+ if (preserveOldPacks != null) {
+ command.setPreserveOldPacks(preserveOldPacks.booleanValue());
+ }
+ if (prunePreserved != null) {
+ command.setPrunePreserved(prunePreserved.booleanValue());
+ }
+ if (packKeptObjects != null) {
+ command.setPackKeptObjects(packKeptObjects.booleanValue());
+ }
+ command.call();
+ } catch (GitAPIException e) {
+ throw die(e.getMessage(), e);
+ }
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java
index f07c3ca8b5..ce687c4639 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Glog.java
@@ -1,45 +1,12 @@
/*
* Copyright (C) 2010, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
@@ -47,7 +14,6 @@ package org.eclipse.jgit.pgm;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
@@ -75,7 +41,7 @@ class Glog extends RevWalkTextBuiltin {
frame = new JFrame();
frame.addWindowListener(new WindowAdapter() {
@Override
- public void windowClosing(final WindowEvent e) {
+ public void windowClosing(WindowEvent e) {
frame.dispose();
}
});
@@ -87,10 +53,8 @@ class Glog extends RevWalkTextBuiltin {
final JPanel buttons = new JPanel(new FlowLayout());
final JButton repaint = new JButton();
repaint.setText(CLIText.get().repaint);
- repaint.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- graphPane.repaint();
- }
+ repaint.addActionListener((ActionEvent e) -> {
+ graphPane.repaint();
});
buttons.add(repaint);
@@ -113,7 +77,7 @@ class Glog extends RevWalkTextBuiltin {
}
@Override
- protected void show(final RevCommit c) throws Exception {
+ protected void show(RevCommit c) throws Exception {
throw new UnsupportedOperationException();
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/IndexPack.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/IndexPack.java
index 22f3be9afd..b3808d6fda 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/IndexPack.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/IndexPack.java
@@ -1,50 +1,18 @@
/*
* Copyright (C) 2009, Google Inc.
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
import java.io.BufferedInputStream;
+import java.io.IOException;
import org.eclipse.jgit.internal.storage.file.ObjectDirectoryPackParser;
import org.eclipse.jgit.lib.ObjectInserter;
@@ -61,7 +29,7 @@ class IndexPack extends TextBuiltin {
private int indexVersion = -1;
@Override
- protected void run() throws Exception {
+ protected void run() {
BufferedInputStream in = new BufferedInputStream(ins);
try (ObjectInserter inserter = db.newObjectInserter()) {
PackParser p = inserter.newPackParser(in);
@@ -72,6 +40,8 @@ class IndexPack extends TextBuiltin {
}
p.parse(new TextProgressMonitor(errw));
inserter.flush();
+ } catch (IOException e) {
+ throw die(e.getMessage(), e);
}
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java
index b3e73b5d99..9c4af813a4 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java
@@ -4,56 +4,28 @@
* Copyright (C) 2010, Robin Rosenberg <robin.rosenberg@dewire.com>
* Copyright (C) 2010, Sasa Zivkov <sasa.zivkov@sap.com>
* Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2016, Rüdiger Herrmann <ruediger.herrmann@gmx.de> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
import java.io.File;
+import java.io.IOException;
import java.text.MessageFormat;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.InitCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.util.StringUtils;
+import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@Command(common = true, usage = "usage_CreateAnEmptyGitRepository")
@@ -61,20 +33,39 @@ class Init extends TextBuiltin {
@Option(name = "--bare", usage = "usage_CreateABareRepository")
private boolean bare;
+ @Option(name = "--initial-branch", aliases = { "-b" },
+ metaVar = "metaVar_branchName", usage = "usage_initialBranch")
+ private String branch;
+
+ @Argument(index = 0, metaVar = "metaVar_directory")
+ private String directory;
+
@Override
protected final boolean requiresRepository() {
return false;
}
@Override
- protected void run() throws Exception {
+ protected void run() {
InitCommand command = Git.init();
command.setBare(bare);
- if (gitdir != null)
+ if (gitdir != null) {
command.setDirectory(new File(gitdir));
- Repository repository = command.call().getRepository();
- outw.println(MessageFormat.format(
- CLIText.get().initializedEmptyGitRepositoryIn, repository
- .getDirectory().getAbsolutePath()));
+ }
+ if (directory != null) {
+ command.setDirectory(new File(directory));
+ }
+ Repository repository;
+ try {
+ if (!StringUtils.isEmptyOrNull(branch)) {
+ command.setInitialBranch(branch);
+ }
+ repository = command.call().getRepository();
+ outw.println(MessageFormat.format(
+ CLIText.get().initializedEmptyGitRepositoryIn,
+ repository.getDirectory().getAbsolutePath()));
+ } catch (GitAPIException | IOException e) {
+ throw die(e.getMessage(), e);
+ }
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java
index d43424c7ce..958e566986 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java
@@ -1,46 +1,13 @@
/*
* Copyright (C) 2010, Google Inc.
- * Copyright (C) 2006-2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2006, 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, 2021, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
@@ -53,6 +20,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Set;
@@ -63,12 +31,16 @@ import org.eclipse.jgit.diff.RenameDetector;
import org.eclipse.jgit.errors.LargeObjectException;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.GpgConfig;
+import org.eclipse.jgit.lib.SignatureVerifier.SignatureVerification;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.SignatureVerifiers;
import org.eclipse.jgit.notes.NoteMap;
import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.pgm.internal.VerificationUtils;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.util.GitDateFormatter;
@@ -87,23 +59,30 @@ class Log extends RevWalkTextBuiltin {
private Map<String, NoteMap> noteMaps;
+ private boolean showNameOnly = false;
+
+ private boolean showNameAndStatusOnly = false;
+
@Option(name="--decorate", usage="usage_showRefNamesMatchingCommits")
private boolean decorate;
@Option(name = "--no-standard-notes", usage = "usage_noShowStandardNotes")
private boolean noStandardNotes;
- private List<String> additionalNoteRefs = new ArrayList<String>();
+ private List<String> additionalNoteRefs = new ArrayList<>();
@Option(name = "--show-notes", usage = "usage_showNotes", metaVar = "metaVar_ref")
void addAdditionalNoteRef(String notesRef) {
additionalNoteRefs.add(notesRef);
}
+ @Option(name = "--show-signature", usage = "usage_showSignature")
+ private boolean showSignature;
+
@Option(name = "--date", usage = "usage_date")
void dateFormat(String date) {
- if (date.toLowerCase().equals(date))
- date = date.toUpperCase();
+ if (date.toLowerCase(Locale.ROOT).equals(date))
+ date = date.toUpperCase(Locale.ROOT);
dateFormatter = new GitDateFormatter(Format.valueOf(date));
}
@@ -123,7 +102,22 @@ class Log extends RevWalkTextBuiltin {
private Integer renameLimit;
@Option(name = "--name-status", usage = "usage_nameStatus")
- private boolean showNameAndStatusOnly;
+ void nameAndStatusOnly(boolean on) {
+ if (showNameOnly) {
+ throw new IllegalArgumentException(
+ CLIText.get().cannotUseNameStatusOnlyAndNameOnly);
+ }
+ showNameAndStatusOnly = on;
+ }
+
+ @Option(name = "--name-only", usage = "usage_nameOnly")
+ void nameOnly(boolean on) {
+ if (showNameAndStatusOnly) {
+ throw new IllegalArgumentException(
+ CLIText.get().cannotUseNameStatusOnlyAndNameOnly);
+ }
+ showNameOnly = on;
+ }
@Option(name = "--ignore-space-at-eol")
void ignoreSpaceAtEol(@SuppressWarnings("unused") boolean on) {
@@ -179,23 +173,27 @@ class Log extends RevWalkTextBuiltin {
// END -- Options shared with Diff
+ private GpgConfig config;
+
Log() {
dateFormatter = new GitDateFormatter(Format.DEFAULT);
}
@Override
- protected void init(final Repository repository, final String gitDir) {
+ protected void init(Repository repository, String gitDir) {
super.init(repository, gitDir);
diffFmt = new DiffFormatter(new BufferedOutputStream(outs));
}
@Override
- protected void run() throws Exception {
+ protected void run() {
+ config = new GpgConfig(db.getConfig());
diffFmt.setRepository(db);
try {
diffFmt.setPathFilter(pathFilter);
- if (detectRenames != null)
+ if (detectRenames != null) {
diffFmt.setDetectRenames(detectRenames.booleanValue());
+ }
if (renameLimit != null && diffFmt.isDetectRenames()) {
RenameDetector rd = diffFmt.getRenameDetector();
rd.setRenameLimit(renameLimit.intValue());
@@ -203,7 +201,7 @@ class Log extends RevWalkTextBuiltin {
if (!noStandardNotes || !additionalNoteRefs.isEmpty()) {
createWalk();
- noteMaps = new LinkedHashMap<String, NoteMap>();
+ noteMaps = new LinkedHashMap<>();
if (!noStandardNotes) {
addNoteMap(Constants.R_NOTES_COMMITS);
}
@@ -217,18 +215,20 @@ class Log extends RevWalkTextBuiltin {
}
}
- if (decorate)
+ if (decorate) {
allRefsByPeeledObjectId = getRepository()
.getAllRefsByPeeledObjectId();
-
+ }
super.run();
+ } catch (Exception e) {
+ throw die(e.getMessage(), e);
} finally {
diffFmt.close();
}
}
private void addNoteMap(String notesRef) throws IOException {
- Ref notes = db.getRef(notesRef);
+ Ref notes = db.exactRef(notesRef);
if (notes == null)
return;
RevCommit notesCommit = argWalk.parseCommit(notes.getObjectId());
@@ -237,7 +237,7 @@ class Log extends RevWalkTextBuiltin {
}
@Override
- protected void show(final RevCommit c) throws Exception {
+ protected void show(RevCommit c) throws Exception {
outw.print(CLIText.get().commitLabel);
outw.print(" "); //$NON-NLS-1$
c.getId().copyTo(outbuffer, outw);
@@ -255,6 +255,9 @@ class Log extends RevWalkTextBuiltin {
}
outw.println();
+ if (showSignature) {
+ showSignature(c);
+ }
final PersonIdent author = c.getAuthorIdent();
outw.println(MessageFormat.format(CLIText.get().authorInfo, author.getName(), author.getEmailAddress()));
outw.println(MessageFormat.format(CLIText.get().dateInfo,
@@ -262,7 +265,7 @@ class Log extends RevWalkTextBuiltin {
outw.println();
final String[] lines = c.getFullMessage().split("\n"); //$NON-NLS-1$
- for (final String s : lines) {
+ for (String s : lines) {
outw.print(" "); //$NON-NLS-1$
outw.print(s);
outw.println();
@@ -273,16 +276,35 @@ class Log extends RevWalkTextBuiltin {
if (showNotes(c))
outw.println();
- if (c.getParentCount() <= 1 && (showNameAndStatusOnly || showPatch))
+ if (c.getParentCount() <= 1 && (showNameAndStatusOnly || showPatch
+ || showNameOnly)) {
showDiff(c);
+ }
outw.flush();
}
+ private void showSignature(RevCommit c) throws IOException {
+ if (c.getRawGpgSignature() == null) {
+ return;
+ }
+ SignatureVerification verification = SignatureVerifiers.verify(db,
+ config, c);
+ if (verification == null) {
+ return;
+ }
+ VerificationUtils.writeVerification(outw, verification,
+ verification.verifierName(), c.getCommitterIdent());
+ }
+
/**
+ * Show notes for given commit
+ *
* @param c
+ * given commit
* @return <code>true</code> if at least one note was printed,
* <code>false</code> otherwise
* @throws IOException
+ * if an IO error occurred
*/
private boolean showNotes(RevCommit c) throws IOException {
if (noteMaps == null)
@@ -309,12 +331,17 @@ class Log extends RevWalkTextBuiltin {
/**
* @param c
+ * given commit
* @param map
+ * note map
* @param label
+ * label
* @param emptyLine
+ * whether to start with an empty line
* @return <code>true</code> if note was printed, <code>false</code>
* otherwise
* @throws IOException
+ * if an IO error occurred
*/
private boolean showNotes(RevCommit c, NoteMap map, String label,
boolean emptyLine)
@@ -324,7 +351,7 @@ class Log extends RevWalkTextBuiltin {
return false;
if (emptyLine)
outw.println();
- outw.print("Notes");
+ outw.print("Notes"); //$NON-NLS-1$
if (label != null) {
outw.print(" ("); //$NON-NLS-1$
outw.print(label);
@@ -350,9 +377,11 @@ class Log extends RevWalkTextBuiltin {
: null;
final RevTree b = c.getTree();
- if (showNameAndStatusOnly)
+ if (showNameAndStatusOnly) {
Diff.nameStatus(outw, diffFmt.scan(a, b));
- else {
+ } else if (showNameOnly) {
+ Diff.nameOnly(outw, diffFmt.scan(a, b));
+ } else {
outw.flush();
diffFmt.format(a, b);
diffFmt.flush();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsFiles.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsFiles.java
new file mode 100644
index 0000000000..741e02a881
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsFiles.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017, Matthias Sohn <matthias.sohn@sap.com> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.pgm;
+
+import static java.util.function.Predicate.isEqual;
+import static org.eclipse.jgit.lib.FileMode.EXECUTABLE_FILE;
+import static org.eclipse.jgit.lib.FileMode.GITLINK;
+import static org.eclipse.jgit.lib.FileMode.REGULAR_FILE;
+import static org.eclipse.jgit.lib.FileMode.SYMLINK;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jgit.dircache.DirCacheIterator;
+import org.eclipse.jgit.errors.RevisionSyntaxException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.CanonicalTreeParser;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
+import org.eclipse.jgit.util.QuotedString;
+import org.kohsuke.args4j.Option;
+import org.kohsuke.args4j.spi.StopOptionHandler;
+
+@Command(common = true, usage = "usage_LsFiles")
+class LsFiles extends TextBuiltin {
+
+ @Option(name = "--", metaVar = "metaVar_paths", handler = StopOptionHandler.class)
+ private List<String> paths = new ArrayList<>();
+
+ @Override
+ protected void run() {
+ try (RevWalk rw = new RevWalk(db);
+ TreeWalk tw = new TreeWalk(db)) {
+ final ObjectId head = db.resolve(Constants.HEAD);
+ if (head == null) {
+ return;
+ }
+ RevCommit c = rw.parseCommit(head);
+ CanonicalTreeParser p = new CanonicalTreeParser();
+ p.reset(rw.getObjectReader(), c.getTree());
+ tw.reset(); // drop the first empty tree, which we do not need here
+ if (!paths.isEmpty()) {
+ tw.setFilter(PathFilterGroup.createFromStrings(paths));
+ }
+ tw.addTree(p);
+ tw.addTree(new DirCacheIterator(db.readDirCache()));
+ tw.setRecursive(true);
+ while (tw.next()) {
+ if (filterFileMode(tw, EXECUTABLE_FILE, GITLINK, REGULAR_FILE,
+ SYMLINK)) {
+ outw.println(
+ QuotedString.GIT_PATH.quote(tw.getPathString()));
+ }
+ }
+ } catch (RevisionSyntaxException | IOException e) {
+ throw die(e.getMessage(), e);
+ }
+ }
+
+ private boolean filterFileMode(TreeWalk tw, FileMode... modes) {
+ return Arrays.stream(modes).anyMatch(isEqual(tw.getFileMode(0))
+ .or(isEqual(tw.getFileMode(1))));
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java
index 6262ad2469..89ceed256d 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsRemote.java
@@ -1,56 +1,23 @@
/*
* Copyright (C) 2009, Google Inc.
* Copyright (C) 2008, Jonas Fonseca <fonseca@diku.dk>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
import java.io.IOException;
-import java.util.Comparator;
import java.util.TreeSet;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.LsRemoteCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Ref;
import org.kohsuke.args4j.Argument;
@@ -67,24 +34,31 @@ class LsRemote extends TextBuiltin {
@Option(name = "--timeout", metaVar = "metaVar_service", usage = "usage_abortConnectionIfNoActivity")
int timeout = -1;
+ @Option(name = "--symref", usage = "usage_lsRemoteSymref")
+ private boolean symref;
+
@Argument(index = 0, metaVar = "metaVar_uriish", required = true)
private String remote;
@Override
- protected void run() throws Exception {
+ protected void run() {
LsRemoteCommand command = Git.lsRemoteRepository().setRemote(remote)
.setTimeout(timeout).setHeads(heads).setTags(tags);
- TreeSet<Ref> refs = new TreeSet<Ref>(new Comparator<Ref>() {
-
- public int compare(Ref r1, Ref r2) {
- return r1.getName().compareTo(r2.getName());
+ TreeSet<Ref> refs = new TreeSet<>(
+ (Ref r1, Ref r2) -> r1.getName().compareTo(r2.getName()));
+ try {
+ refs.addAll(command.call());
+ for (Ref r : refs) {
+ if (symref && r.isSymbolic()) {
+ show(r.getTarget(), r.getName());
+ }
+ show(r.getObjectId(), r.getName());
+ if (r.getPeeledObjectId() != null) {
+ show(r.getPeeledObjectId(), r.getName() + "^{}"); //$NON-NLS-1$
+ }
}
- });
- refs.addAll(command.call());
- for (final Ref r : refs) {
- show(r.getObjectId(), r.getName());
- if (r.getPeeledObjectId() != null)
- show(r.getPeeledObjectId(), r.getName() + "^{}"); //$NON-NLS-1$
+ } catch (GitAPIException | IOException e) {
+ throw die(e.getMessage(), e);
}
}
@@ -93,11 +67,20 @@ class LsRemote extends TextBuiltin {
return false;
}
- private void show(final AnyObjectId id, final String name)
+ private void show(AnyObjectId id, String name)
throws IOException {
outw.print(id.name());
outw.print('\t');
outw.print(name);
outw.println();
}
+
+ private void show(Ref ref, String name)
+ throws IOException {
+ outw.print("ref: "); //$NON-NLS-1$
+ outw.print(ref.getName());
+ outw.print('\t');
+ outw.print(name);
+ outw.println();
+ }
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java
index 4b16ed8800..34b48c1b1a 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/LsTree.java
@@ -1,50 +1,18 @@
/*
* Copyright (C) 2008, Jonas Fonseca <fonseca@diku.dk>
* Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -67,32 +35,37 @@ class LsTree extends TextBuiltin {
private AbstractTreeIterator tree;
@Argument(index = 1)
- @Option(name = "--", metaVar = "metaVar_paths", multiValued = true, handler = StopOptionHandler.class)
- private List<String> paths = new ArrayList<String>();
+ @Option(name = "--", metaVar = "metaVar_paths", handler = StopOptionHandler.class)
+ private List<String> paths = new ArrayList<>();
@Override
- protected void run() throws Exception {
- final TreeWalk walk = new TreeWalk(db);
- walk.reset(); // drop the first empty tree, which we do not need here
- if (paths.size() > 0)
- walk.setFilter(PathFilterGroup.createFromStrings(paths));
- walk.setRecursive(recursive);
- walk.addTree(tree);
+ protected void run() {
+ try (TreeWalk walk = new TreeWalk(db)) {
+ walk.reset(); // drop the first empty tree, which we do not need here
+ if (!paths.isEmpty()) {
+ walk.setFilter(PathFilterGroup.createFromStrings(paths));
+ }
+ walk.setRecursive(recursive);
+ walk.addTree(tree);
- while (walk.next()) {
- final FileMode mode = walk.getFileMode(0);
- if (mode == FileMode.TREE)
- outw.print('0');
- outw.print(mode);
- outw.print(' ');
- outw.print(Constants.typeString(mode.getObjectType()));
+ while (walk.next()) {
+ final FileMode mode = walk.getFileMode(0);
+ if (mode == FileMode.TREE) {
+ outw.print('0');
+ }
+ outw.print(mode);
+ outw.print(' ');
+ outw.print(Constants.typeString(mode.getObjectType()));
- outw.print(' ');
- outw.print(walk.getObjectId(0).name());
+ outw.print(' ');
+ outw.print(walk.getObjectId(0).name());
- outw.print('\t');
- outw.print(QuotedString.GIT_PATH.quote(walk.getPathString()));
- outw.println();
+ outw.print('\t');
+ outw.print(QuotedString.GIT_PATH.quote(walk.getPathString()));
+ outw.println();
+ }
+ } catch (IOException e) {
+ throw die(e.getMessage(), e);
}
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java
index 7151de794d..8df9bad740 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Main.java
@@ -1,51 +1,21 @@
/*
* Copyright (C) 2006, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
import java.io.File;
import java.io.IOException;
+import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
@@ -53,22 +23,32 @@ import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.awtui.AwtAuthenticator;
import org.eclipse.jgit.awtui.AwtCredentialsProvider;
import org.eclipse.jgit.errors.TransportException;
+import org.eclipse.jgit.lfs.BuiltinLFS;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryBuilder;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.pgm.opt.CmdLineParser;
import org.eclipse.jgit.pgm.opt.SubcommandHandler;
+import org.eclipse.jgit.transport.HttpTransport;
+import org.eclipse.jgit.transport.http.apache.HttpClientConnectionFactory;
import org.eclipse.jgit.util.CachedAuthenticator;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.ExampleMode;
import org.kohsuke.args4j.Option;
+import org.kohsuke.args4j.OptionHandlerFilter;
-/** Command line entry point. */
+/**
+ * Command line entry point.
+ */
public class Main {
@Option(name = "--help", usage = "usage_displayThisHelpText", aliases = { "-h" })
private boolean help;
@@ -86,15 +66,43 @@ public class Main {
private TextBuiltin subcommand;
@Argument(index = 1, metaVar = "metaVar_arg")
- private List<String> arguments = new ArrayList<String>();
+ private List<String> arguments = new ArrayList<>();
+
+ PrintWriter writer;
+
+ private ExecutorService gcExecutor;
+
+ /**
+ * <p>Constructor for Main.</p>
+ */
+ public Main() {
+ HttpTransport.setConnectionFactory(new HttpClientConnectionFactory());
+ BuiltinLFS.register();
+ gcExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() {
+ private final ThreadFactory baseFactory = Executors
+ .defaultThreadFactory();
+
+ @Override
+ public Thread newThread(Runnable taskBody) {
+ Thread thr = baseFactory.newThread(taskBody);
+ thr.setName("JGit-autoGc"); //$NON-NLS-1$
+ return thr;
+ }
+ });
+ }
/**
* Execute the command line.
*
* @param argv
* arguments.
+ * @throws java.lang.Exception
+ * if an error occurred
*/
- public static void main(final String[] argv) {
+ public static void main(String[] argv) throws Exception {
+ // make sure built-in filters are registered
+ BuiltinLFS.register();
+
new Main().run(argv);
}
@@ -113,8 +121,11 @@ public class Main {
*
* @param argv
* arguments.
+ * @throws java.lang.Exception
+ * if an error occurred
*/
- protected void run(final String[] argv) {
+ protected void run(String[] argv) throws Exception {
+ writer = createErrorWriter();
try {
if (!installConsole()) {
AwtAuthenticator.install();
@@ -123,12 +134,14 @@ public class Main {
configureHttpProxy();
execute(argv);
} catch (Die err) {
- if (err.isAborted())
- System.exit(1);
- System.err.println(MessageFormat.format(CLIText.get().fatalError, err.getMessage()));
- if (showStackTrace)
- err.printStackTrace();
- System.exit(128);
+ if (err.isAborted()) {
+ exit(1, err);
+ }
+ writer.println(CLIText.fatalError(err.getMessage()));
+ if (showStackTrace) {
+ err.printStackTrace(writer);
+ }
+ exit(128, err);
} catch (Exception err) {
// Try to detect errno == EPIPE and exit normally if that happens
// There may be issues with operating system versions and locale,
@@ -136,52 +149,63 @@ public class Main {
// under other circumstances.
if (err.getClass() == IOException.class) {
// Linux, OS X
- if (err.getMessage().equals("Broken pipe")) //$NON-NLS-1$
- System.exit(0);
+ if (err.getMessage().equals("Broken pipe")) { //$NON-NLS-1$
+ exit(0, err);
+ }
// Windows
- if (err.getMessage().equals("The pipe is being closed")) //$NON-NLS-1$
- System.exit(0);
+ if (err.getMessage().equals("The pipe is being closed")) { //$NON-NLS-1$
+ exit(0, err);
+ }
}
if (!showStackTrace && err.getCause() != null
- && err instanceof TransportException)
- System.err.println(MessageFormat.format(CLIText.get().fatalError, err.getCause().getMessage()));
+ && err instanceof TransportException) {
+ writer.println(CLIText.fatalError(err.getCause().getMessage()));
+ }
if (err.getClass().getName().startsWith("org.eclipse.jgit.errors.")) { //$NON-NLS-1$
- System.err.println(MessageFormat.format(CLIText.get().fatalError, err.getMessage()));
- if (showStackTrace)
+ writer.println(CLIText.fatalError(err.getMessage()));
+ if (showStackTrace) {
err.printStackTrace();
- System.exit(128);
+ }
+ exit(128, err);
}
err.printStackTrace();
- System.exit(1);
+ exit(1, err);
}
if (System.out.checkError()) {
- System.err.println(CLIText.get().unknownIoErrorStdout);
- System.exit(1);
+ writer.println(CLIText.get().unknownIoErrorStdout);
+ exit(1, null);
}
- if (System.err.checkError()) {
+ if (writer.checkError()) {
// No idea how to present an error here, most likely disk full or
// broken pipe
- System.exit(1);
+ exit(1, null);
}
+ gcExecutor.shutdown();
+ gcExecutor.awaitTermination(10, TimeUnit.MINUTES);
+ }
+
+ PrintWriter createErrorWriter() {
+ return new PrintWriter(new OutputStreamWriter(System.err, UTF_8));
}
- private void execute(final String[] argv) throws Exception {
- final CmdLineParser clp = new CmdLineParser(this);
- PrintWriter writer = new PrintWriter(System.err);
+ private void execute(String[] argv) throws Exception {
+ final CmdLineParser clp = new SubcommandLineParser(this);
+
try {
clp.parseArgument(argv);
} catch (CmdLineException err) {
if (argv.length > 0 && !help && !version) {
- writer.println(MessageFormat.format(CLIText.get().fatalError, err.getMessage()));
+ writer.println(CLIText.fatalError(err.getMessage()));
writer.flush();
- System.exit(1);
+ exit(1, err);
}
}
if (argv.length == 0 || help) {
- final String ex = clp.printExample(ExampleMode.ALL, CLIText.get().resourceBundle());
- writer.println("jgit" + ex + " command [ARG ...]"); //$NON-NLS-1$
+ final String ex = clp.printExample(OptionHandlerFilter.ALL,
+ CLIText.get().resourceBundle());
+ writer.println("jgit" + ex + " command [ARG ...]"); //$NON-NLS-1$ //$NON-NLS-2$
if (help) {
writer.println();
clp.printUsage(writer, CLIText.get().resourceBundle());
@@ -191,44 +215,67 @@ public class Main {
writer.println(CLIText.get().mostCommonlyUsedCommandsAre);
final CommandRef[] common = CommandCatalog.common();
int width = 0;
- for (final CommandRef c : common)
+ for (CommandRef c : common) {
width = Math.max(width, c.getName().length());
+ }
width += 2;
- for (final CommandRef c : common) {
+ for (CommandRef c : common) {
writer.print(' ');
writer.print(c.getName());
- for (int i = c.getName().length(); i < width; i++)
+ for (int i = c.getName().length(); i < width; i++) {
writer.print(' ');
+ }
writer.print(CLIText.get().resourceBundle().getString(c.getUsage()));
writer.println();
}
writer.println();
}
writer.flush();
- System.exit(1);
+ exit(1, null);
}
if (version) {
- String cmdId = Version.class.getSimpleName().toLowerCase();
+ String cmdId = Version.class.getSimpleName()
+ .toLowerCase(Locale.ROOT);
subcommand = CommandCatalog.get(cmdId).create();
}
final TextBuiltin cmd = subcommand;
- if (cmd.requiresRepository())
- cmd.init(openGitDir(gitdir), null);
- else
- cmd.init(null, gitdir);
+ init(cmd);
try {
- cmd.execute(arguments.toArray(new String[arguments.size()]));
+ cmd.execute(arguments.toArray(new String[0]));
} finally {
- if (cmd.outw != null)
+ if (cmd.outw != null) {
cmd.outw.flush();
- if (cmd.errw != null)
+ }
+ if (cmd.errw != null) {
cmd.errw.flush();
+ }
}
}
+ void init(TextBuiltin cmd) throws IOException {
+ if (cmd.requiresRepository()) {
+ cmd.init(openGitDir(gitdir), null);
+ } else {
+ cmd.init(null, gitdir);
+ }
+ }
+
+ /**
+ * @param status
+ * exit status code, nonzero value indicates an error
+ * @param t
+ * can be {@code null}
+ * @throws Exception
+ * if an IO error occurred
+ */
+ void exit(int status, Exception t) throws Exception {
+ writer.flush();
+ System.exit(status);
+ }
+
/**
* Evaluate the {@code --git-dir} option and open the repository.
*
@@ -236,7 +283,7 @@ public class Main {
* the {@code --git-dir} option given on the command line. May be
* null if it was not supplied.
* @return the repository to operate on.
- * @throws IOException
+ * @throws java.io.IOException
* the repository cannot be opened.
*/
protected Repository openGitDir(String aGitdir) throws IOException {
@@ -254,31 +301,21 @@ public class Main {
install("org.eclipse.jgit.console.ConsoleAuthenticator"); //$NON-NLS-1$
install("org.eclipse.jgit.console.ConsoleCredentialsProvider"); //$NON-NLS-1$
return true;
- } catch (ClassNotFoundException e) {
- return false;
- } catch (NoClassDefFoundError e) {
+ } catch (ClassNotFoundException | NoClassDefFoundError
+ | UnsupportedClassVersionError e) {
return false;
- } catch (UnsupportedClassVersionError e) {
- return false;
-
- } catch (IllegalArgumentException e) {
- throw new RuntimeException(CLIText.get().cannotSetupConsole, e);
- } catch (SecurityException e) {
- throw new RuntimeException(CLIText.get().cannotSetupConsole, e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(CLIText.get().cannotSetupConsole, e);
- } catch (InvocationTargetException e) {
- throw new RuntimeException(CLIText.get().cannotSetupConsole, e);
- } catch (NoSuchMethodException e) {
+ } catch (IllegalArgumentException | SecurityException
+ | IllegalAccessException | InvocationTargetException
+ | NoSuchMethodException e) {
throw new RuntimeException(CLIText.get().cannotSetupConsole, e);
}
}
- private static void install(final String name)
+ private static void install(String name)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException, ClassNotFoundException {
try {
- Class.forName(name).getMethod("install").invoke(null); //$NON-NLS-1$
+ Class.forName(name).getMethod("install").invoke(null); //$NON-NLS-1$
} catch (InvocationTargetException e) {
if (e.getCause() instanceof RuntimeException)
throw (RuntimeException) e.getCause();
@@ -291,39 +328,70 @@ public class Main {
/**
* Configure the JRE's standard HTTP based on <code>http_proxy</code>.
* <p>
- * The popular libcurl library honors the <code>http_proxy</code>
- * environment variable as a means of specifying an HTTP proxy for requests
- * made behind a firewall. This is not natively recognized by the JRE, so
- * this method can be used by command line utilities to configure the JRE
- * before the first request is sent.
+ * The popular libcurl library honors the <code>http_proxy</code>,
+ * <code>https_proxy</code> environment variables as a means of specifying
+ * an HTTP/S proxy for requests made behind a firewall. This is not natively
+ * recognized by the JRE, so this method can be used by command line
+ * utilities to configure the JRE before the first request is sent. The
+ * information found in the environment variables is copied to the
+ * associated system properties. This is not done when the system properties
+ * are already set. The default way of telling java programs about proxies
+ * (the system properties) takes precedence over environment variables.
*
* @throws MalformedURLException
- * the value in <code>http_proxy</code> is unsupportable.
+ * the value in <code>http_proxy</code> or
+ * <code>https_proxy</code> is unsupportable.
*/
- private static void configureHttpProxy() throws MalformedURLException {
- final String s = System.getenv("http_proxy"); //$NON-NLS-1$
- if (s == null || s.equals("")) //$NON-NLS-1$
- return;
-
- final URL u = new URL((s.indexOf("://") == -1) ? "http://" + s : s); //$NON-NLS-1$ //$NON-NLS-2$
- if (!"http".equals(u.getProtocol())) //$NON-NLS-1$
- throw new MalformedURLException(MessageFormat.format(CLIText.get().invalidHttpProxyOnlyHttpSupported, s));
-
- final String proxyHost = u.getHost();
- final int proxyPort = u.getPort();
-
- System.setProperty("http.proxyHost", proxyHost); //$NON-NLS-1$
- if (proxyPort > 0)
- System.setProperty("http.proxyPort", String.valueOf(proxyPort)); //$NON-NLS-1$
-
- final String userpass = u.getUserInfo();
- if (userpass != null && userpass.contains(":")) { //$NON-NLS-1$
- final int c = userpass.indexOf(':');
- final String user = userpass.substring(0, c);
- final String pass = userpass.substring(c + 1);
- CachedAuthenticator
- .add(new CachedAuthenticator.CachedAuthentication(
- proxyHost, proxyPort, user, pass));
+ static void configureHttpProxy() throws MalformedURLException {
+ for (String protocol : new String[] { "http", "https" }) { //$NON-NLS-1$ //$NON-NLS-2$
+ if (System.getProperty(protocol + ".proxyHost") != null) { //$NON-NLS-1$
+ continue;
+ }
+ String s = System.getenv(protocol + "_proxy"); //$NON-NLS-1$
+ if (s == null && protocol.equals("https")) { //$NON-NLS-1$
+ s = System.getenv("HTTPS_PROXY"); //$NON-NLS-1$
+ }
+ if (s == null || s.isEmpty()) {
+ continue;
+ }
+
+ URL u = new URL(!s.contains("://") ? protocol + "://" + s : s); //$NON-NLS-1$ //$NON-NLS-2$
+ if (!u.getProtocol().startsWith("http")) //$NON-NLS-1$
+ throw new MalformedURLException(MessageFormat.format(
+ CLIText.get().invalidHttpProxyOnlyHttpSupported, s));
+
+ final String proxyHost = u.getHost();
+ final int proxyPort = u.getPort();
+
+ System.setProperty(protocol + ".proxyHost", proxyHost); //$NON-NLS-1$
+ if (proxyPort > 0)
+ System.setProperty(protocol + ".proxyPort", //$NON-NLS-1$
+ String.valueOf(proxyPort));
+
+ final String userpass = u.getUserInfo();
+ if (userpass != null && userpass.contains(":")) { //$NON-NLS-1$
+ final int c = userpass.indexOf(':');
+ final String user = userpass.substring(0, c);
+ final String pass = userpass.substring(c + 1);
+ CachedAuthenticator.add(
+ new CachedAuthenticator.CachedAuthentication(proxyHost,
+ proxyPort, user, pass));
+ }
+ }
+ }
+
+ /**
+ * Parser for subcommands which doesn't stop parsing on help options and so
+ * proceeds all specified options
+ */
+ static class SubcommandLineParser extends CmdLineParser {
+ public SubcommandLineParser(Object bean) {
+ super(bean);
+ }
+
+ @Override
+ protected boolean containsHelp(String... args) {
+ return false;
}
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java
index 93c4388dbc..b78998dd74 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java
@@ -1,61 +1,32 @@
/*
- * Copyright (C) 2011, 2014 Christian Halstrick <christian.halstrick@sap.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2011, 2014 Christian Halstrick <christian.halstrick@sap.com> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
+import static org.eclipse.jgit.lib.Constants.OBJECT_ID_ABBREV_STRING_LENGTH;
+
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Map;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.MergeCommand;
-import org.eclipse.jgit.api.MergeResult;
import org.eclipse.jgit.api.MergeCommand.FastForwardMode;
+import org.eclipse.jgit.api.MergeResult;
import org.eclipse.jgit.api.errors.CheckoutConflictException;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.merge.ContentMergeStrategy;
import org.eclipse.jgit.merge.MergeStrategy;
import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason;
import org.eclipse.jgit.pgm.internal.CLIText;
@@ -101,117 +72,163 @@ class Merge extends TextBuiltin {
@Option(name = "-m", usage = "usage_message")
private String message;
+ private ContentMergeStrategy contentStrategy = null;
+
+ @Option(name = "--strategy-option", aliases = { "-X" },
+ metaVar = "metaVar_extraArgument", usage = "usage_extraArgument")
+ void extraArg(String name) {
+ if (ContentMergeStrategy.OURS.name().equalsIgnoreCase(name)) {
+ contentStrategy = ContentMergeStrategy.OURS;
+ } else if (ContentMergeStrategy.THEIRS.name().equalsIgnoreCase(name)) {
+ contentStrategy = ContentMergeStrategy.THEIRS;
+ } else {
+ throw die(MessageFormat.format(CLIText.get().unknownExtraArgument, name));
+ }
+ }
+
@Override
- protected void run() throws Exception {
- if (squash && ff == FastForwardMode.NO_FF)
+ protected void run() {
+ if (squash && ff == FastForwardMode.NO_FF) {
throw die(CLIText.get().cannotCombineSquashWithNoff);
+ }
// determine the merge strategy
if (strategyName != null) {
mergeStrategy = MergeStrategy.get(strategyName);
- if (mergeStrategy == null)
+ if (mergeStrategy == null) {
throw die(MessageFormat.format(
CLIText.get().unknownMergeStrategy, strategyName));
+ }
}
- // determine the other revision we want to merge with HEAD
- final Ref srcRef = db.getRef(ref);
- final ObjectId src = db.resolve(ref + "^{commit}"); //$NON-NLS-1$
- if (src == null)
- throw die(MessageFormat.format(
- CLIText.get().refDoesNotExistOrNoCommit, ref));
-
- Ref oldHead = db.getRef(Constants.HEAD);
- Git git = new Git(db);
- MergeCommand mergeCmd = git.merge().setStrategy(mergeStrategy)
- .setSquash(squash).setFastForward(ff).setCommit(!noCommit);
- if (srcRef != null)
- mergeCmd.include(srcRef);
- else
- mergeCmd.include(src);
-
- if (message != null)
- mergeCmd.setMessage(message);
-
- MergeResult result;
try {
- result = mergeCmd.call();
- } catch (CheckoutConflictException e) {
- result = new MergeResult(e.getConflictingPaths()); // CHECKOUT_CONFLICT
- }
+ // determine the other revision we want to merge with HEAD
+ final Ref srcRef = db.findRef(ref);
+ final ObjectId src = db.resolve(ref + "^{commit}"); //$NON-NLS-1$
+ if (src == null) {
+ throw die(MessageFormat
+ .format(CLIText.get().refDoesNotExistOrNoCommit, ref));
+ }
+
+ Ref oldHead = getOldHead();
+ MergeResult result;
+ try (Git git = new Git(db)) {
+ MergeCommand mergeCmd = git.merge()
+ .setStrategy(mergeStrategy)
+ .setContentMergeStrategy(contentStrategy)
+ .setSquash(squash)
+ .setFastForward(ff)
+ .setCommit(!noCommit);
+ if (srcRef != null) {
+ mergeCmd.include(srcRef);
+ } else {
+ mergeCmd.include(src);
+ }
+
+ if (message != null) {
+ mergeCmd.setMessage(message);
+ }
- switch (result.getMergeStatus()) {
- case ALREADY_UP_TO_DATE:
- if (squash)
- outw.print(CLIText.get().nothingToSquash);
- outw.println(CLIText.get().alreadyUpToDate);
- break;
- case FAST_FORWARD:
- ObjectId oldHeadId = oldHead.getObjectId();
- outw.println(MessageFormat.format(CLIText.get().updating, oldHeadId
- .abbreviate(7).name(), result.getNewHead().abbreviate(7)
- .name()));
- outw.println(result.getMergeStatus().toString());
- break;
- case CHECKOUT_CONFLICT:
- outw.println(CLIText.get().mergeCheckoutConflict);
- for (String collidingPath : result.getCheckoutConflicts())
- outw.println("\t" + collidingPath); //$NON-NLS-1$
- outw.println(CLIText.get().mergeCheckoutFailed);
- break;
- case CONFLICTING:
- for (String collidingPath : result.getConflicts().keySet())
- outw.println(MessageFormat.format(CLIText.get().mergeConflict,
- collidingPath));
- outw.println(CLIText.get().mergeFailed);
- break;
- case FAILED:
- for (Map.Entry<String, MergeFailureReason> entry : result
- .getFailingPaths().entrySet())
- switch (entry.getValue()) {
- case DIRTY_WORKTREE:
- case DIRTY_INDEX:
- outw.println(CLIText.get().dontOverwriteLocalChanges);
- outw.println(" " + entry.getKey()); //$NON-NLS-1$
- break;
- case COULD_NOT_DELETE:
- outw.println(CLIText.get().cannotDeleteFile);
- outw.println(" " + entry.getKey()); //$NON-NLS-1$
- break;
+ try {
+ result = mergeCmd.call();
+ } catch (CheckoutConflictException e) {
+ result = new MergeResult(e.getConflictingPaths()); // CHECKOUT_CONFLICT
+ }
+ }
+
+ switch (result.getMergeStatus()) {
+ case ALREADY_UP_TO_DATE:
+ if (squash) {
+ outw.print(CLIText.get().nothingToSquash);
+ }
+ outw.println(CLIText.get().alreadyUpToDate);
+ break;
+ case FAST_FORWARD:
+ ObjectId oldHeadId = oldHead.getObjectId();
+ if (oldHeadId != null) {
+ String oldId = oldHeadId
+ .abbreviate(OBJECT_ID_ABBREV_STRING_LENGTH).name();
+ String newId = result.getNewHead()
+ .abbreviate(OBJECT_ID_ABBREV_STRING_LENGTH).name();
+ outw.println(MessageFormat.format(CLIText.get().updating,
+ oldId, newId));
}
- break;
- case MERGED:
- String name;
- if (!isMergedInto(oldHead, src))
- name = mergeStrategy.getName();
- else
- name = "recursive"; //$NON-NLS-1$
- outw.println(MessageFormat.format(CLIText.get().mergeMadeBy, name));
- break;
- case MERGED_NOT_COMMITTED:
- outw.println(CLIText.get().mergeWentWellStoppedBeforeCommitting);
- break;
- case MERGED_SQUASHED:
- case FAST_FORWARD_SQUASHED:
- case MERGED_SQUASHED_NOT_COMMITTED:
- outw.println(CLIText.get().mergedSquashed);
- outw.println(CLIText.get().mergeWentWellStoppedBeforeCommitting);
- break;
- case ABORTED:
- throw die(CLIText.get().ffNotPossibleAborting);
- case NOT_SUPPORTED:
- outw.println(MessageFormat.format(
- CLIText.get().unsupportedOperation, result.toString()));
+ outw.println(result.getMergeStatus().toString());
+ break;
+ case CHECKOUT_CONFLICT:
+ outw.println(CLIText.get().mergeCheckoutConflict);
+ for (String collidingPath : result.getCheckoutConflicts()) {
+ outw.println("\t" + collidingPath); //$NON-NLS-1$
+ }
+ outw.println(CLIText.get().mergeCheckoutFailed);
+ break;
+ case CONFLICTING:
+ for (String collidingPath : result.getConflicts().keySet())
+ outw.println(MessageFormat.format(
+ CLIText.get().mergeConflict, collidingPath));
+ outw.println(CLIText.get().mergeFailed);
+ break;
+ case FAILED:
+ for (Map.Entry<String, MergeFailureReason> entry : result
+ .getFailingPaths().entrySet())
+ switch (entry.getValue()) {
+ case DIRTY_WORKTREE:
+ case DIRTY_INDEX:
+ outw.println(CLIText.get().dontOverwriteLocalChanges);
+ outw.println(" " + entry.getKey()); //$NON-NLS-1$
+ break;
+ case COULD_NOT_DELETE:
+ outw.println(CLIText.get().cannotDeleteFile);
+ outw.println(" " + entry.getKey()); //$NON-NLS-1$
+ break;
+ }
+ break;
+ case MERGED:
+ MergeStrategy strategy = isMergedInto(oldHead, src)
+ ? MergeStrategy.RECURSIVE
+ : mergeStrategy;
+ outw.println(MessageFormat.format(CLIText.get().mergeMadeBy,
+ strategy.getName()));
+ break;
+ case MERGED_NOT_COMMITTED:
+ outw.println(
+ CLIText.get().mergeWentWellStoppedBeforeCommitting);
+ break;
+ case MERGED_SQUASHED:
+ case FAST_FORWARD_SQUASHED:
+ case MERGED_SQUASHED_NOT_COMMITTED:
+ outw.println(CLIText.get().mergedSquashed);
+ outw.println(
+ CLIText.get().mergeWentWellStoppedBeforeCommitting);
+ break;
+ case ABORTED:
+ throw die(CLIText.get().ffNotPossibleAborting);
+ case NOT_SUPPORTED:
+ outw.println(MessageFormat.format(
+ CLIText.get().unsupportedOperation, result.toString()));
+ }
+ } catch (GitAPIException | IOException e) {
+ throw die(e.getMessage(), e);
+ }
+
+ }
+
+ private Ref getOldHead() throws IOException {
+ Ref oldHead = db.exactRef(Constants.HEAD);
+ if (oldHead == null) {
+ throw die(CLIText.get().onBranchToBeBorn);
}
+ return oldHead;
}
private boolean isMergedInto(Ref oldHead, AnyObjectId src)
throws IOException {
- RevWalk revWalk = new RevWalk(db);
- ObjectId oldHeadObjectId = oldHead.getPeeledObjectId();
- if (oldHeadObjectId == null)
- oldHeadObjectId = oldHead.getObjectId();
- RevCommit oldHeadCommit = revWalk.lookupCommit(oldHeadObjectId);
- RevCommit srcCommit = revWalk.lookupCommit(src);
- return revWalk.isMergedInto(oldHeadCommit, srcCommit);
+ try (RevWalk revWalk = new RevWalk(db)) {
+ ObjectId oldHeadObjectId = oldHead.getPeeledObjectId();
+ if (oldHeadObjectId == null)
+ oldHeadObjectId = oldHead.getObjectId();
+ RevCommit oldHeadCommit = revWalk.lookupCommit(oldHeadObjectId);
+ RevCommit srcCommit = revWalk.lookupCommit(src);
+ return revWalk.isMergedInto(oldHeadCommit, srcCommit);
+ }
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeBase.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeBase.java
index 29cbb53a98..a29c4d9f36 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeBase.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeBase.java
@@ -1,56 +1,24 @@
/*
* Copyright (C) 2008, Jonas Fonseca <fonseca@diku.dk>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import org.kohsuke.args4j.Argument;
-import org.kohsuke.args4j.Option;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.filter.RevFilter;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
@Command(usage = "usage_MergeBase")
class MergeBase extends TextBuiltin {
@@ -58,24 +26,25 @@ class MergeBase extends TextBuiltin {
private boolean all;
@Argument(index = 0, metaVar = "metaVar_commitish", required = true)
- void commit_0(final RevCommit c) {
- commits.add(c);
- }
-
- @Argument(index = 1, metaVar = "metaVar_commitish", required = true)
- private final List<RevCommit> commits = new ArrayList<RevCommit>();
+ private List<RevCommit> commits = new ArrayList<>();
@Override
- protected void run() throws Exception {
- for (final RevCommit c : commits)
- argWalk.markStart(c);
- argWalk.setRevFilter(RevFilter.MERGE_BASE);
- int max = all ? Integer.MAX_VALUE : 1;
- while (max-- > 0) {
- final RevCommit b = argWalk.next();
- if (b == null)
- break;
- outw.println(b.getId().name());
+ protected void run() {
+ try {
+ for (RevCommit c : commits) {
+ argWalk.markStart(c);
+ }
+ argWalk.setRevFilter(RevFilter.MERGE_BASE);
+ int max = all ? Integer.MAX_VALUE : 1;
+ while (max-- > 0) {
+ final RevCommit b = argWalk.next();
+ if (b == null) {
+ break;
+ }
+ outw.println(b.getId().name());
+ }
+ } catch (IOException e) {
+ throw die(e.getMessage(), e);
}
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeTool.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeTool.java
new file mode 100644
index 0000000000..9d0b65c479
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeTool.java
@@ -0,0 +1,485 @@
+/*
+ * Copyright (C) 2018-2022, Andre Bossert <andre.bossert@siemens.com>
+ * Copyright (C) 2019, Tim Neumann <tim.neumann@advantest.com>
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.pgm;
+
+import static org.eclipse.jgit.treewalk.TreeWalk.OperationType.CHECKOUT_OP;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.TreeMap;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.Status;
+import org.eclipse.jgit.api.StatusCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.diff.ContentSource;
+import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.dircache.DirCacheCheckout;
+import org.eclipse.jgit.dircache.DirCacheCheckout.CheckoutMetadata;
+import org.eclipse.jgit.dircache.DirCacheEntry;
+import org.eclipse.jgit.dircache.DirCacheIterator;
+import org.eclipse.jgit.errors.NoWorkTreeException;
+import org.eclipse.jgit.errors.RevisionSyntaxException;
+import org.eclipse.jgit.internal.diffmergetool.ExternalMergeTool;
+import org.eclipse.jgit.internal.diffmergetool.FileElement;
+import org.eclipse.jgit.internal.diffmergetool.MergeTools;
+import org.eclipse.jgit.internal.diffmergetool.ToolException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.CoreConfig.EolStreamType;
+import org.eclipse.jgit.lib.IndexDiff.StageState;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.internal.BooleanTriState;
+import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.WorkingTreeOptions;
+import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
+import org.eclipse.jgit.util.FS.ExecutionResult;
+import org.eclipse.jgit.util.SystemReader;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+import org.kohsuke.args4j.spi.RestOfArgumentsHandler;
+
+@Command(name = "mergetool", common = true, usage = "usage_MergeTool")
+class MergeTool extends TextBuiltin {
+ private MergeTools mergeTools;
+
+ private Optional<String> toolName = Optional.empty();
+
+ @Option(name = "--tool", aliases = {
+ "-t" }, metaVar = "metaVar_tool", usage = "usage_ToolForMerge")
+ void setToolName(String name) {
+ toolName = Optional.of(name);
+ }
+
+ private BooleanTriState prompt = BooleanTriState.UNSET;
+
+ @Option(name = "--prompt", usage = "usage_prompt")
+ void setPrompt(@SuppressWarnings("unused") boolean on) {
+ prompt = BooleanTriState.TRUE;
+ }
+
+ @Option(name = "--no-prompt", aliases = { "-y" }, usage = "usage_noPrompt")
+ void noPrompt(@SuppressWarnings("unused") boolean on) {
+ prompt = BooleanTriState.FALSE;
+ }
+
+ @Option(name = "--tool-help", usage = "usage_toolHelp")
+ private boolean toolHelp;
+
+ private boolean gui = false;
+
+ @Option(name = "--gui", aliases = { "-g" }, usage = "usage_MergeGuiTool")
+ void setGui(@SuppressWarnings("unused") boolean on) {
+ gui = true;
+ }
+
+ @Option(name = "--no-gui", usage = "usage_noGui")
+ void noGui(@SuppressWarnings("unused") boolean on) {
+ gui = false;
+ }
+
+ @Argument(required = false, index = 0, metaVar = "metaVar_paths")
+ @Option(name = "--", metaVar = "metaVar_paths", handler = RestOfArgumentsHandler.class)
+ protected List<String> filterPaths;
+
+ private BufferedReader inputReader;
+
+ @Override
+ protected void init(Repository repository, String gitDir) {
+ super.init(repository, gitDir);
+ mergeTools = new MergeTools(repository);
+ inputReader = new BufferedReader(
+ new InputStreamReader(ins,
+ SystemReader.getInstance().getDefaultCharset()));
+ }
+
+ enum MergeResult {
+ SUCCESSFUL, FAILED, ABORTED
+ }
+
+ @Override
+ protected void run() {
+ try {
+ if (toolHelp) {
+ showToolHelp();
+ } else {
+ // get the changed files
+ Map<String, StageState> files = getFiles();
+ if (files.size() > 0) {
+ merge(files);
+ } else {
+ outw.println(CLIText.get().mergeToolNoFiles);
+ }
+ }
+ outw.flush();
+ } catch (Exception e) {
+ throw die(e.getMessage(), e);
+ }
+ }
+
+ private void informUserNoTool(List<String> tools) {
+ try {
+ StringBuilder toolNames = new StringBuilder();
+ for (String name : tools) {
+ toolNames.append(name + " "); //$NON-NLS-1$
+ }
+ outw.println(MessageFormat
+ .format(CLIText.get().mergeToolPromptToolName, toolNames));
+ outw.flush();
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot output text", e); //$NON-NLS-1$
+ }
+ }
+
+ private void merge(Map<String, StageState> files) throws Exception {
+ // sort file names
+ List<String> mergedFilePaths = new ArrayList<>(files.keySet());
+ Collections.sort(mergedFilePaths);
+ // show the files
+ StringBuilder mergedFiles = new StringBuilder();
+ for (String mergedFilePath : mergedFilePaths) {
+ mergedFiles.append(MessageFormat.format("{0}\n", mergedFilePath)); //$NON-NLS-1$
+ }
+ outw.println(MessageFormat.format(CLIText.get().mergeToolMerging,
+ mergedFiles));
+ outw.flush();
+ boolean showPrompt = mergeTools.isInteractive();
+ if (prompt != BooleanTriState.UNSET) {
+ showPrompt = prompt == BooleanTriState.TRUE;
+ }
+ // merge the files
+ MergeResult mergeResult = MergeResult.SUCCESSFUL;
+ for (String mergedFilePath : mergedFilePaths) {
+ // if last merge failed...
+ if (mergeResult == MergeResult.FAILED) {
+ // check if user wants to continue
+ if (showPrompt && !isContinueUnresolvedPaths()) {
+ mergeResult = MergeResult.ABORTED;
+ }
+ }
+ // aborted ?
+ if (mergeResult == MergeResult.ABORTED) {
+ break;
+ }
+ // get file stage state and merge
+ StageState fileState = files.get(mergedFilePath);
+ if (fileState == StageState.BOTH_MODIFIED) {
+ mergeResult = mergeModified(mergedFilePath, showPrompt);
+ } else if ((fileState == StageState.DELETED_BY_US)
+ || (fileState == StageState.DELETED_BY_THEM)) {
+ mergeResult = mergeDeleted(mergedFilePath,
+ fileState == StageState.DELETED_BY_US);
+ } else {
+ outw.println(MessageFormat.format(
+ CLIText.get().mergeToolUnknownConflict,
+ mergedFilePath));
+ mergeResult = MergeResult.ABORTED;
+ }
+ }
+ }
+
+ private MergeResult mergeModified(String mergedFilePath, boolean showPrompt)
+ throws Exception {
+ outw.println(MessageFormat.format(CLIText.get().mergeToolNormalConflict,
+ mergedFilePath));
+ outw.flush();
+ boolean isMergeSuccessful = true;
+ ContentSource baseSource = ContentSource.create(db.newObjectReader());
+ ContentSource localSource = ContentSource.create(db.newObjectReader());
+ ContentSource remoteSource = ContentSource.create(db.newObjectReader());
+ // temporary directory if mergetool.writeToTemp == true
+ File tempDir = mergeTools.createTempDirectory();
+ // the parent directory for temp files (can be same as tempDir or just
+ // the worktree dir)
+ File tempFilesParent = tempDir != null ? tempDir : db.getWorkTree();
+ try {
+ FileElement base = null;
+ FileElement local = null;
+ FileElement remote = null;
+ FileElement merged = new FileElement(mergedFilePath,
+ FileElement.Type.MERGED, db.getWorkTree());
+ DirCache cache = db.readDirCache();
+ try (RevWalk revWalk = new RevWalk(db);
+ TreeWalk treeWalk = new TreeWalk(db,
+ revWalk.getObjectReader())) {
+ treeWalk.setFilter(
+ PathFilterGroup.createFromStrings(mergedFilePath));
+ DirCacheIterator cacheIter = new DirCacheIterator(cache);
+ treeWalk.addTree(cacheIter);
+ while (treeWalk.next()) {
+ if (treeWalk.isSubtree()) {
+ treeWalk.enterSubtree();
+ continue;
+ }
+ final EolStreamType eolStreamType = treeWalk
+ .getEolStreamType(CHECKOUT_OP);
+ final String filterCommand = treeWalk.getFilterCommand(
+ Constants.ATTR_FILTER_TYPE_SMUDGE);
+ WorkingTreeOptions opt = db.getConfig()
+ .get(WorkingTreeOptions.KEY);
+ CheckoutMetadata checkoutMetadata = new CheckoutMetadata(
+ eolStreamType, filterCommand);
+ DirCacheEntry entry = treeWalk
+ .getTree(DirCacheIterator.class).getDirCacheEntry();
+ if (entry == null) {
+ continue;
+ }
+ ObjectId id = entry.getObjectId();
+ switch (entry.getStage()) {
+ case DirCacheEntry.STAGE_1:
+ base = new FileElement(mergedFilePath,
+ FileElement.Type.BASE);
+ DirCacheCheckout.getContent(db, mergedFilePath,
+ checkoutMetadata,
+ baseSource.open(mergedFilePath, id), opt,
+ new FileOutputStream(
+ base.createTempFile(tempFilesParent)));
+ break;
+ case DirCacheEntry.STAGE_2:
+ local = new FileElement(mergedFilePath,
+ FileElement.Type.LOCAL);
+ DirCacheCheckout.getContent(db, mergedFilePath,
+ checkoutMetadata,
+ localSource.open(mergedFilePath, id), opt,
+ new FileOutputStream(
+ local.createTempFile(tempFilesParent)));
+ break;
+ case DirCacheEntry.STAGE_3:
+ remote = new FileElement(mergedFilePath,
+ FileElement.Type.REMOTE);
+ DirCacheCheckout.getContent(db, mergedFilePath,
+ checkoutMetadata,
+ remoteSource.open(mergedFilePath, id), opt,
+ new FileOutputStream(remote
+ .createTempFile(tempFilesParent)));
+ break;
+ }
+ }
+ }
+ if ((local == null) || (remote == null)) {
+ throw die(MessageFormat.format(CLIText.get().mergeToolDied,
+ mergedFilePath));
+ }
+ long modifiedBefore = merged.getFile().lastModified();
+ try {
+ // TODO: check how to return the exit-code of the
+ // tool to jgit / java runtime ?
+ // int rc =...
+ Optional<ExecutionResult> optionalResult = mergeTools.merge(
+ local, remote, merged, base, tempDir, toolName, prompt,
+ gui, this::promptForLaunch, this::informUserNoTool);
+ if (optionalResult.isPresent()) {
+ ExecutionResult result = optionalResult.get();
+ Charset defaultCharset = SystemReader.getInstance()
+ .getDefaultCharset();
+ outw.println(new String(result.getStdout().toByteArray(),
+ defaultCharset));
+ outw.flush();
+ errw.println(new String(result.getStderr().toByteArray(),
+ defaultCharset));
+ errw.flush();
+ } else {
+ return MergeResult.ABORTED;
+ }
+ } catch (ToolException e) {
+ isMergeSuccessful = false;
+ outw.println(e.getResultStdout());
+ outw.flush();
+ errw.println(e.getMessage());
+ errw.println(MessageFormat.format(
+ CLIText.get().mergeToolMergeFailed, mergedFilePath));
+ errw.flush();
+ if (e.isCommandExecutionError()) {
+ throw die(CLIText.get().mergeToolExecutionError, e);
+ }
+ }
+ // if merge was successful check file modified
+ if (isMergeSuccessful) {
+ long modifiedAfter = merged.getFile().lastModified();
+ if (modifiedBefore == modifiedAfter) {
+ outw.println(MessageFormat.format(
+ CLIText.get().mergeToolFileUnchanged,
+ mergedFilePath));
+ isMergeSuccessful = !showPrompt || isMergeSuccessful();
+ }
+ }
+ // if automatically or manually successful
+ // -> add the file to the index
+ if (isMergeSuccessful) {
+ addFile(mergedFilePath);
+ }
+ } finally {
+ baseSource.close();
+ localSource.close();
+ remoteSource.close();
+ }
+ return isMergeSuccessful ? MergeResult.SUCCESSFUL : MergeResult.FAILED;
+ }
+
+ private MergeResult mergeDeleted(String mergedFilePath, boolean deletedByUs)
+ throws Exception {
+ outw.println(MessageFormat.format(CLIText.get().mergeToolFileUnchanged,
+ mergedFilePath));
+ if (deletedByUs) {
+ outw.println(CLIText.get().mergeToolDeletedConflictByUs);
+ } else {
+ outw.println(CLIText.get().mergeToolDeletedConflictByThem);
+ }
+ int mergeDecision = getDeletedMergeDecision();
+ if (mergeDecision == 1) {
+ // add modified file
+ addFile(mergedFilePath);
+ } else if (mergeDecision == -1) {
+ // remove deleted file
+ rmFile(mergedFilePath);
+ } else {
+ return MergeResult.ABORTED;
+ }
+ return MergeResult.SUCCESSFUL;
+ }
+
+ private void addFile(String fileName) throws Exception {
+ try (Git git = new Git(db)) {
+ git.add().addFilepattern(fileName).call();
+ }
+ }
+
+ private void rmFile(String fileName) throws Exception {
+ try (Git git = new Git(db)) {
+ git.rm().addFilepattern(fileName).call();
+ }
+ }
+
+ private boolean hasUserAccepted(String message) throws IOException {
+ boolean yes = true;
+ outw.print(message + " "); //$NON-NLS-1$
+ outw.flush();
+ BufferedReader br = inputReader;
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ if (line.equalsIgnoreCase("y")) { //$NON-NLS-1$
+ yes = true;
+ break;
+ } else if (line.equalsIgnoreCase("n")) { //$NON-NLS-1$
+ yes = false;
+ break;
+ }
+ outw.print(message);
+ outw.flush();
+ }
+ return yes;
+ }
+
+ private boolean isContinueUnresolvedPaths() throws IOException {
+ return hasUserAccepted(CLIText.get().mergeToolContinueUnresolvedPaths);
+ }
+
+ private boolean isMergeSuccessful() throws IOException {
+ return hasUserAccepted(CLIText.get().mergeToolWasMergeSuccessfull);
+ }
+
+ private boolean promptForLaunch(String toolNamePrompt) {
+ try {
+ boolean launch = true;
+ outw.print(MessageFormat.format(CLIText.get().mergeToolLaunch,
+ toolNamePrompt) + " "); //$NON-NLS-1$
+ outw.flush();
+ BufferedReader br = inputReader;
+ String line = null;
+ if ((line = br.readLine()) != null) {
+ if (!line.equalsIgnoreCase("y") && !line.equalsIgnoreCase("")) { //$NON-NLS-1$ //$NON-NLS-2$
+ launch = false;
+ }
+ }
+ return launch;
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot output text", e); //$NON-NLS-1$
+ }
+ }
+
+ private int getDeletedMergeDecision() throws IOException {
+ int ret = 0; // abort
+ final String message = CLIText.get().mergeToolDeletedMergeDecision
+ + " "; //$NON-NLS-1$
+ outw.print(message);
+ outw.flush();
+ BufferedReader br = inputReader;
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ if (line.equalsIgnoreCase("m")) { //$NON-NLS-1$
+ ret = 1; // modified
+ break;
+ } else if (line.equalsIgnoreCase("d")) { //$NON-NLS-1$
+ ret = -1; // deleted
+ break;
+ } else if (line.equalsIgnoreCase("a")) { //$NON-NLS-1$
+ break;
+ }
+ outw.print(message);
+ outw.flush();
+ }
+ return ret;
+ }
+
+ private void showToolHelp() throws IOException {
+ Map<String, ExternalMergeTool> predefTools = mergeTools
+ .getPredefinedTools(true);
+ StringBuilder availableToolNames = new StringBuilder();
+ StringBuilder notAvailableToolNames = new StringBuilder();
+ for (String name : predefTools.keySet()) {
+ if (predefTools.get(name).isAvailable()) {
+ availableToolNames.append(MessageFormat.format("\t\t{0}\n", name)); //$NON-NLS-1$
+ } else {
+ notAvailableToolNames.append(MessageFormat.format("\t\t{0}\n", name)); //$NON-NLS-1$
+ }
+ }
+ StringBuilder userToolNames = new StringBuilder();
+ Map<String, ExternalMergeTool> userTools = mergeTools
+ .getUserDefinedTools();
+ for (String name : userTools.keySet()) {
+ userToolNames.append(MessageFormat.format("\t\t{0}.cmd {1}\n", //$NON-NLS-1$
+ name, userTools.get(name).getCommand()));
+ }
+ outw.println(MessageFormat.format(
+ CLIText.get().mergeToolHelpSetToFollowing, availableToolNames,
+ userToolNames, notAvailableToolNames));
+ }
+
+ private Map<String, StageState> getFiles() throws RevisionSyntaxException,
+ NoWorkTreeException, GitAPIException {
+ Map<String, StageState> files = new TreeMap<>();
+ try (Git git = new Git(db)) {
+ StatusCommand statusCommand = git.status();
+ if (filterPaths != null && filterPaths.size() > 0) {
+ for (String path : filterPaths) {
+ statusCommand.addPath(path);
+ }
+ }
+ Status status = statusCommand.call();
+ files = status.getConflictingStageState();
+ }
+ return files;
+ }
+
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MultiPackIndex.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MultiPackIndex.java
new file mode 100644
index 0000000000..1844223cc9
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MultiPackIndex.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2025, Google LLC.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.pgm;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jgit.internal.storage.file.ObjectDirectory;
+import org.eclipse.jgit.internal.storage.file.Pack;
+import org.eclipse.jgit.internal.storage.file.PackFile;
+import org.eclipse.jgit.internal.storage.file.PackIndex;
+import org.eclipse.jgit.internal.storage.midx.MultiPackIndexPrettyPrinter;
+import org.eclipse.jgit.internal.storage.midx.MultiPackIndexWriter;
+import org.eclipse.jgit.internal.storage.pack.PackExt;
+import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+
+@Command(common = true, usage = "usage_MultiPackIndex")
+@SuppressWarnings("nls")
+class MultiPackIndex extends TextBuiltin {
+ @Argument(index = 0, required = true, usage = "write, print")
+ private String command;
+
+ @Option(name = "--midx")
+ private String midxPath;
+
+ /** {@inheritDoc} */
+ @Override
+ protected void run() throws IOException {
+ switch (command) {
+ case "print":
+ printMultiPackIndex();
+ break;
+ case "write":
+ writeMultiPackIndex();
+ break;
+ default:
+ outw.println("Unknown command " + command);
+ }
+ }
+
+ private void printMultiPackIndex() {
+ if (midxPath == null || midxPath.isEmpty()) {
+ throw die("'print' requires the path of a multipack "
+ + "index file with --midx option.");
+ }
+
+ try (FileInputStream is = new FileInputStream(midxPath)) {
+ PrintWriter pw = new PrintWriter(outw, true);
+ MultiPackIndexPrettyPrinter.prettyPrint(is.readAllBytes(), pw);
+ } catch (FileNotFoundException e) {
+ throw die(true, e);
+ } catch (IOException e) {
+ throw die(true, e);
+ }
+ }
+
+ private void writeMultiPackIndex() throws IOException {
+ if (!(db.getObjectDatabase() instanceof ObjectDirectory)) {
+ throw die("This repository object db doesn't have packs");
+ }
+
+ File midx;
+ if (midxPath == null || midxPath.isEmpty()) {
+ midx = new File(((ObjectDirectory) db.getObjectDatabase())
+ .getPackDirectory(), "multi-pack-index");
+ } else {
+ midx = new File(midxPath);
+ }
+
+ errw.println("Writing " + midx.getAbsolutePath());
+
+ ObjectDirectory odb = (ObjectDirectory) db.getObjectDatabase();
+
+ Map<String, PackIndex> indexes = new HashMap<>();
+ for (Pack pack : odb.getPacks()) {
+ PackFile packFile = pack.getPackFile().create(PackExt.INDEX);
+ try {
+ indexes.put(packFile.getName(), pack.getIndex());
+ } catch (IOException e) {
+ throw die("Cannot open index in pack", e);
+ }
+ }
+
+ MultiPackIndexWriter writer = new MultiPackIndexWriter();
+ try (FileOutputStream out = new FileOutputStream(midxPath)) {
+ writer.write(NullProgressMonitor.INSTANCE, out, indexes);
+ } catch (IOException e) {
+ throw die("Cannot write midx " + midxPath, e);
+ }
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ObjectSizeIndex.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ObjectSizeIndex.java
new file mode 100644
index 0000000000..a40c3964fb
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ObjectSizeIndex.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2025, Google LLC.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.pgm;
+
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_MIN_BYTES_OBJ_SIZE_INDEX;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_USE_OBJECT_SIZE_INDEX;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_PACK_SECTION;
+
+import java.io.IOException;
+
+import org.eclipse.jgit.internal.storage.file.ObjectDirectory;
+import org.eclipse.jgit.internal.storage.file.Pack;
+import org.eclipse.jgit.internal.storage.file.PackObjectSizeIndexHelper;
+import org.eclipse.jgit.lib.TextProgressMonitor;
+import org.kohsuke.args4j.Argument;
+
+@Command(common = true, usage = "usage_ObjectSizeIndex")
+@SuppressWarnings("nls")
+class ObjectSizeIndex extends TextBuiltin {
+ @Argument(index = 0, required = true, usage = "write, check")
+ private String command;
+
+ @Override
+ protected void run() throws IOException {
+ switch (command) {
+ case "write":
+ writeObjectSizeIndex();
+ break;
+ case "check":
+ checkObjectSizeIndex();
+ break;
+ default:
+ outw.println("Unknown command " + command);
+ }
+ }
+
+ private void writeObjectSizeIndex() throws IOException {
+ if (!(db.getObjectDatabase() instanceof ObjectDirectory)) {
+ throw die("This repository object db doesn't have packs");
+ }
+ PackObjectSizeIndexHelper.forAllPacks(
+ (ObjectDirectory) db.getObjectDatabase(),
+ new TextProgressMonitor());
+ }
+
+ private void checkObjectSizeIndex() throws IOException {
+ if (!(db.getObjectDatabase() instanceof ObjectDirectory)) {
+ throw die("This repository object db doesn't have packs");
+ }
+
+ outw.println("Object size index configuration for this repo:");
+ outw.println("\n* Writing:");
+ printInt(CONFIG_PACK_SECTION, CONFIG_KEY_MIN_BYTES_OBJ_SIZE_INDEX);
+
+ outw.println("\n* Reading:");
+ printBoolean(CONFIG_PACK_SECTION, CONFIG_KEY_USE_OBJECT_SIZE_INDEX);
+
+ outw.println("\n* Packs - have object size index:");
+ for (Pack pack : ((ObjectDirectory) db.getObjectDatabase())
+ .getPacks()) {
+ String name = pack.getPackName();
+ boolean hasObjectSizeIndex = pack.hasObjectSizeIndex();
+ outw.println(
+ String.format(" - %s - %b", name, hasObjectSizeIndex));
+ }
+ }
+
+ private void printInt(String section, String name) throws IOException {
+ Integer value = db.getConfig().getInt(section, name);
+ String key = String.join(".", section, name);
+ outw.println(" - " + key + " = " + value);
+ }
+
+ private void printBoolean(String section, String name) throws IOException {
+ Boolean value = db.getConfig().getBoolean(section, name);
+ String key = String.join(".", section, name);
+ outw.println(" - " + key + " = " + value);
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/PackRefs.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/PackRefs.java
new file mode 100644
index 0000000000..ee05f5ca0b
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/PackRefs.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.pgm;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.TextProgressMonitor;
+import org.kohsuke.args4j.Option;
+
+@Command(common = true, usage = "usage_PackRefs")
+class PackRefs extends TextBuiltin {
+ @Option(name = "--all", usage = "usage_All")
+ private boolean all;
+
+ @Override
+ protected void run() {
+ Git git = Git.wrap(db);
+ try {
+ git.packRefs().setProgressMonitor(new TextProgressMonitor(errw))
+ .setAll(all).call();
+ } catch (GitAPIException e) {
+ throw die(e.getMessage(), e);
+ }
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java
index 4268f214fd..b1a5daaa65 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Push.java
@@ -1,51 +1,16 @@
/*
* Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com>
- * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
-import static java.lang.Character.valueOf;
-
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
@@ -53,6 +18,7 @@ import java.util.List;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.PushCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
@@ -77,11 +43,14 @@ class Push extends TextBuiltin {
private String remote = Constants.DEFAULT_REMOTE_NAME;
@Argument(index = 1, metaVar = "metaVar_refspec")
- private final List<RefSpec> refSpecs = new ArrayList<RefSpec>();
+ private List<RefSpec> refSpecs = new ArrayList<>();
@Option(name = "--all")
private boolean all;
+ @Option(name = "--atomic")
+ private boolean atomic;
+
@Option(name = "--tags")
private boolean tags;
@@ -105,29 +74,41 @@ class Push extends TextBuiltin {
@Option(name = "--dry-run")
private boolean dryRun;
+ @Option(name = "--push-option", aliases = { "-t" })
+ private List<String> pushOptions = new ArrayList<>();
+
private boolean shownURI;
@Override
- protected void run() throws Exception {
- Git git = new Git(db);
- PushCommand push = git.push();
- push.setDryRun(dryRun);
- push.setForce(force);
- push.setProgressMonitor(new TextProgressMonitor(errw));
- push.setReceivePack(receivePack);
- push.setRefSpecs(refSpecs);
- if (all)
- push.setPushAll();
- if (tags)
- push.setPushTags();
- push.setRemote(remote);
- push.setThin(thin);
- push.setTimeout(timeout);
- Iterable<PushResult> results = push.call();
- for (PushResult result : results) {
- try (ObjectReader reader = db.newObjectReader()) {
- printPushResult(reader, result.getURI(), result);
+ protected void run() {
+ try (Git git = new Git(db)) {
+ PushCommand push = git.push();
+ push.setDryRun(dryRun);
+ push.setForce(force);
+ push.setProgressMonitor(new TextProgressMonitor(errw));
+ push.setReceivePack(receivePack);
+ push.setRefSpecs(refSpecs);
+ if (all) {
+ push.setPushAll();
+ }
+ if (tags) {
+ push.setPushTags();
+ }
+ push.setRemote(remote);
+ push.setThin(thin);
+ push.setAtomic(atomic);
+ push.setTimeout(timeout);
+ if (!pushOptions.isEmpty()) {
+ push.setPushOptions(pushOptions);
+ }
+ Iterable<PushResult> results = push.call();
+ for (PushResult result : results) {
+ try (ObjectReader reader = db.newObjectReader()) {
+ printPushResult(reader, result.getURI(), result);
+ }
}
+ } catch (GitAPIException | IOException e) {
+ throw die(e.getMessage(), e);
}
}
@@ -137,7 +118,7 @@ class Push extends TextBuiltin {
boolean everythingUpToDate = true;
// at first, print up-to-date ones...
- for (final RemoteRefUpdate rru : result.getRemoteUpdates()) {
+ for (RemoteRefUpdate rru : result.getRemoteUpdates()) {
if (rru.getStatus() == Status.UP_TO_DATE) {
if (verbose)
printRefUpdateResult(reader, uri, result, rru);
@@ -145,13 +126,13 @@ class Push extends TextBuiltin {
everythingUpToDate = false;
}
- for (final RemoteRefUpdate rru : result.getRemoteUpdates()) {
+ for (RemoteRefUpdate rru : result.getRemoteUpdates()) {
// ...then successful updates...
if (rru.getStatus() == Status.OK)
printRefUpdateResult(reader, uri, result, rru);
}
- for (final RemoteRefUpdate rru : result.getRemoteUpdates()) {
+ for (RemoteRefUpdate rru : result.getRemoteUpdates()) {
// ...finally, others (problematic)
if (rru.getStatus() != Status.OK
&& rru.getStatus() != Status.UP_TO_DATE)
@@ -177,15 +158,15 @@ class Push extends TextBuiltin {
switch (rru.getStatus()) {
case OK:
if (rru.isDelete())
- printUpdateLine('-', "[deleted]", null, remoteName, null);
+ printUpdateLine('-', "[deleted]", null, remoteName, null); //$NON-NLS-1$
else {
final Ref oldRef = result.getAdvertisedRef(remoteName);
if (oldRef == null) {
final String summary;
if (remoteName.startsWith(Constants.R_TAGS))
- summary = "[new tag]";
+ summary = "[new tag]"; //$NON-NLS-1$
else
- summary = "[new branch]";
+ summary = "[new branch]"; //$NON-NLS-1$
printUpdateLine('*', summary, srcRef, remoteName, null);
} else {
boolean fastForward = rru.isFastForward();
@@ -201,16 +182,16 @@ class Push extends TextBuiltin {
break;
case NON_EXISTING:
- printUpdateLine('X', "[no match]", null, remoteName, null);
+ printUpdateLine('X', "[no match]", null, remoteName, null); //$NON-NLS-1$
break;
case REJECTED_NODELETE:
- printUpdateLine('!', "[rejected]", null, remoteName,
+ printUpdateLine('!', "[rejected]", null, remoteName, //$NON-NLS-1$
CLIText.get().remoteSideDoesNotSupportDeletingRefs);
break;
case REJECTED_NONFASTFORWARD:
- printUpdateLine('!', "[rejected]", srcRef, remoteName,
+ printUpdateLine('!', "[rejected]", srcRef, remoteName, //$NON-NLS-1$
CLIText.get().nonFastForward);
break;
@@ -218,22 +199,22 @@ class Push extends TextBuiltin {
final String message = MessageFormat.format(
CLIText.get().remoteRefObjectChangedIsNotExpectedOne,
safeAbbreviate(reader, rru.getExpectedOldObjectId()));
- printUpdateLine('!', "[rejected]", srcRef, remoteName, message);
+ printUpdateLine('!', "[rejected]", srcRef, remoteName, message); //$NON-NLS-1$
break;
case REJECTED_OTHER_REASON:
- printUpdateLine('!', "[remote rejected]", srcRef, remoteName, rru
+ printUpdateLine('!', "[remote rejected]", srcRef, remoteName, rru //$NON-NLS-1$
.getMessage());
break;
case UP_TO_DATE:
if (verbose)
- printUpdateLine('=', "[up to date]", srcRef, remoteName, null);
+ printUpdateLine('=', "[up to date]", srcRef, remoteName, null); //$NON-NLS-1$
break;
case NOT_ATTEMPTED:
case AWAITING_REPORT:
- printUpdateLine('?', "[unexpected push-process behavior]", srcRef,
+ printUpdateLine('?', "[unexpected push-process behavior]", srcRef, //$NON-NLS-1$
remoteName, rru.getMessage());
break;
}
@@ -250,7 +231,7 @@ class Push extends TextBuiltin {
private void printUpdateLine(final char flag, final String summary,
final String srcRef, final String destRef, final String message)
throws IOException {
- outw.format(" %c %-17s", valueOf(flag), summary); //$NON-NLS-1$
+ outw.format(" %c %-17s", Character.valueOf(flag), summary); //$NON-NLS-1$
if (srcRef != null)
outw.format(" %s ->", abbreviateRef(srcRef, true)); //$NON-NLS-1$
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java
index d7f895a300..f89a4d12be 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java
@@ -1,50 +1,18 @@
/*
* Copyright (C) 2008-2009, Google Inc.
- * Copyright (C) 2009-2010, Robin Rosenberg <robin.rosenberg@dewire.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2009-2010, Robin Rosenberg <robin.rosenberg@dewire.com> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
import java.io.File;
+import java.io.IOException;
import java.text.MessageFormat;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
@@ -64,7 +32,7 @@ class ReceivePack extends TextBuiltin {
}
@Override
- protected void run() throws Exception {
+ protected void run() {
final org.eclipse.jgit.transport.ReceivePack rp;
try {
@@ -72,10 +40,16 @@ class ReceivePack extends TextBuiltin {
db = key.open(true /* must exist */);
} catch (RepositoryNotFoundException notFound) {
throw die(MessageFormat.format(CLIText.get().notAGitRepository,
- dstGitdir.getPath()));
+ dstGitdir.getPath()), notFound);
+ } catch (IOException e) {
+ throw die(e.getMessage(), e);
}
rp = new org.eclipse.jgit.transport.ReceivePack(db);
- rp.receive(ins, outs, errs);
+ try {
+ rp.receive(ins, outs, errs);
+ } catch (IOException e) {
+ throw die(e.getMessage(), e);
+ }
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reflog.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reflog.java
index aa90f8d50c..46485cc5ef 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reflog.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reflog.java
@@ -1,51 +1,22 @@
/*
- * Copyright (C) 2012, Tomasz Zarna <tomasz.zarna@tasktop.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2012, Tomasz Zarna <tomasz.zarna@tasktop.com> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
+import static org.eclipse.jgit.lib.Constants.OBJECT_ID_ABBREV_STRING_LENGTH;
+
+import java.io.IOException;
import java.util.Collection;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ReflogCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ReflogEntry;
import org.eclipse.jgit.lib.Repository;
@@ -58,20 +29,25 @@ class Reflog extends TextBuiltin {
private String ref;
@Override
- protected void run() throws Exception {
- ReflogCommand cmd = new Git(db).reflog();
- if (ref != null)
- cmd.setRef(ref);
- Collection<ReflogEntry> entries = cmd.call();
- int i = 0;
- for (ReflogEntry entry : entries) {
- outw.println(toString(entry, i++));
+ protected void run() {
+ try (Git git = new Git(db)) {
+ ReflogCommand cmd = git.reflog();
+ if (ref != null)
+ cmd.setRef(ref);
+ Collection<ReflogEntry> entries = cmd.call();
+ int i = 0;
+ for (ReflogEntry entry : entries) {
+ outw.println(toString(entry, i++));
+ }
+ } catch (GitAPIException | IOException e) {
+ throw die(e.getMessage(), e);
}
}
private String toString(ReflogEntry entry, int i) {
final StringBuilder s = new StringBuilder();
- s.append(entry.getNewId().abbreviate(7).name());
+ s.append(entry.getNewId().abbreviate(OBJECT_ID_ABBREV_STRING_LENGTH)
+ .name());
s.append(" "); //$NON-NLS-1$
s.append(ref == null ? Constants.HEAD : Repository.shortenRefName(ref));
s.append("@{" + i + "}:"); //$NON-NLS-1$ //$NON-NLS-2$
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Remote.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Remote.java
new file mode 100644
index 0000000000..a3100ac8ed
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Remote.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2015, Kaloyan Raev <kaloyan.r@zend.com> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.pgm;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.RemoteAddCommand;
+import org.eclipse.jgit.api.RemoteListCommand;
+import org.eclipse.jgit.api.RemoteRemoveCommand;
+import org.eclipse.jgit.api.RemoteSetUrlCommand;
+import org.eclipse.jgit.api.RemoteSetUrlCommand.UriType;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.pgm.opt.CmdLineParser;
+import org.eclipse.jgit.transport.RemoteConfig;
+import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.util.io.ThrowingPrintWriter;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+
+@Command(common = false, usage = "usage_Remote")
+class Remote extends TextBuiltin {
+
+ @Option(name = "--verbose", aliases = { "-v" }, usage = "usage_beVerbose")
+ private boolean verbose = false;
+
+ @Option(name = "--prune", aliases = {
+ "-p" }, usage = "usage_pruneStaleTrackingRefs")
+ private boolean prune;
+
+ @Option(name = "--push", usage = "usage_pushUrls")
+ private boolean push;
+
+ @Argument(index = 0, metaVar = "metaVar_command")
+ private String command;
+
+ @Argument(index = 1, metaVar = "metaVar_remoteName")
+ private String name;
+
+ @Argument(index = 2, metaVar = "metaVar_uriish")
+ private String uri;
+
+ @Override
+ protected void run() {
+ try (Git git = new Git(db)) {
+ if (command == null) {
+ RemoteListCommand cmd = git.remoteList();
+ List<RemoteConfig> remotes = cmd.call();
+ print(remotes);
+ return;
+ }
+ switch (command) {
+ case "add": //$NON-NLS-1$
+ RemoteAddCommand add = git.remoteAdd();
+ add.setName(name);
+ add.setUri(new URIish(uri));
+ add.call();
+ break;
+ case "remove": //$NON-NLS-1$
+ case "rm": //$NON-NLS-1$
+ RemoteRemoveCommand rm = git.remoteRemove();
+ rm.setRemoteName(name);
+ rm.call();
+ break;
+ case "set-url": //$NON-NLS-1$
+ RemoteSetUrlCommand remoteSetUrl = git.remoteSetUrl();
+ remoteSetUrl.setRemoteName(name);
+ remoteSetUrl.setRemoteUri(new URIish(uri));
+ remoteSetUrl.setUriType(push ? UriType.PUSH : UriType.FETCH);
+ remoteSetUrl.call();
+ break;
+ case "update": //$NON-NLS-1$
+ Fetch fetch = new Fetch();
+ fetch.init(db, gitdir);
+ StringWriter osw = new StringWriter();
+ fetch.outw = new ThrowingPrintWriter(osw);
+ StringWriter esw = new StringWriter();
+ fetch.errw = new ThrowingPrintWriter(esw);
+ List<String> fetchArgs = new ArrayList<>();
+ if (verbose) {
+ fetchArgs.add("--verbose"); //$NON-NLS-1$
+ }
+ if (prune) {
+ fetchArgs.add("--prune"); //$NON-NLS-1$
+ }
+ if (name != null) {
+ fetchArgs.add(name);
+ }
+ fetch.execute(fetchArgs.toArray(new String[0]));
+ fetch.outw.flush();
+ fetch.errw.flush();
+ outw.println(osw.toString());
+ errw.println(esw.toString());
+ break;
+ default:
+ throw new JGitInternalException(MessageFormat
+ .format(CLIText.get().unknownSubcommand, command));
+ }
+ } catch (Exception e) {
+ throw die(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public void printUsage(String message, CmdLineParser clp)
+ throws IOException {
+ errw.println(message);
+ errw.println("jgit remote [--verbose (-v)] [--help (-h)]"); //$NON-NLS-1$
+ errw.println("jgit remote add name uri-ish [--help (-h)]"); //$NON-NLS-1$
+ errw.println("jgit remote remove name [--help (-h)]"); //$NON-NLS-1$
+ errw.println("jgit remote rm name [--help (-h)]"); //$NON-NLS-1$
+ errw.println(
+ "jgit remote [--verbose (-v)] update [name] [--prune (-p)] [--help (-h)]"); //$NON-NLS-1$
+ errw.println("jgit remote set-url name uri-ish [--push] [--help (-h)]"); //$NON-NLS-1$
+
+ errw.println();
+ clp.printUsage(errw, getResourceBundle());
+ errw.println();
+
+ errw.flush();
+ }
+
+ private void print(List<RemoteConfig> remotes) throws IOException {
+ for (RemoteConfig remote : remotes) {
+ String remoteName = remote.getName();
+ if (verbose) {
+ List<URIish> fetchURIs = remote.getURIs();
+ List<URIish> pushURIs = remote.getPushURIs();
+
+ String fetchURI = ""; //$NON-NLS-1$
+ if (!fetchURIs.isEmpty()) {
+ fetchURI = fetchURIs.get(0).toString();
+ } else if (!pushURIs.isEmpty()) {
+ fetchURI = pushURIs.get(0).toString();
+ }
+
+ String pushURI = ""; //$NON-NLS-1$
+ if (!pushURIs.isEmpty()) {
+ pushURI = pushURIs.get(0).toString();
+ } else if (!fetchURIs.isEmpty()) {
+ pushURI = fetchURIs.get(0).toString();
+ }
+
+ outw.println(
+ String.format("%s\t%s (fetch)", remoteName, fetchURI)); //$NON-NLS-1$
+ outw.println(
+ String.format("%s\t%s (push)", remoteName, pushURI)); //$NON-NLS-1$
+ } else {
+ outw.println(remoteName);
+ }
+ }
+ }
+
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java
index 9b191e6796..da622e1130 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java
@@ -1,47 +1,15 @@
/*
- * Copyright (C) 2014, Google Inc.
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2014, Google Inc. and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.gitrepo.RepoCommand;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@@ -55,15 +23,19 @@ class Repo extends TextBuiltin {
@Option(name = "--groups", aliases = { "-g" }, usage = "usage_groups")
private String groups = "default"; //$NON-NLS-1$
- @Argument(required = true, usage = "usage_pathToXml")
+ @Argument(required = true, metaVar = "metaVar_path", usage = "usage_pathToXml")
private String path;
@Override
- protected void run() throws Exception {
- new RepoCommand(db)
- .setURI(uri)
- .setPath(path)
- .setGroups(groups)
- .call();
+ protected void run() {
+ try {
+ new RepoCommand(db)
+ .setURI(uri)
+ .setPath(path)
+ .setGroups(groups)
+ .call();
+ } catch (GitAPIException e) {
+ throw die(e.getMessage(), e);
+ }
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java
index f4cbcafed1..f33cb6be71 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Reset.java
@@ -1,53 +1,26 @@
/*
- * Copyright (C) 2011, Chris Aniszczyk <caniszczyk@gmail.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2011, Chris Aniszczyk <caniszczyk@gmail.com> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
+import java.util.ArrayList;
+import java.util.List;
+
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ResetCommand;
import org.eclipse.jgit.api.ResetCommand.ResetType;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.pgm.internal.CLIText;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
+import org.kohsuke.args4j.spi.RestOfArgumentsHandler;
@Command(common = true, usage = "usage_reset")
class Reset extends TextBuiltin {
@@ -61,29 +34,47 @@ class Reset extends TextBuiltin {
@Option(name = "--hard", usage = "usage_resetHard")
private boolean hard = false;
- @Argument(required = true, metaVar = "metaVar_name", usage = "usage_reset")
+ @Argument(required = false, index = 0, metaVar = "metaVar_commitish", usage = "usage_resetReference")
private String commit;
+ @Argument(required = false, index = 1, metaVar = "metaVar_paths")
+ @Option(name = "--", metaVar = "metaVar_paths", handler = RestOfArgumentsHandler.class)
+ private List<String> paths = new ArrayList<>();
+
@Override
- protected void run() throws Exception {
- ResetCommand command = new Git(db).reset();
- command.setRef(commit);
- ResetType mode = null;
- if (soft)
- mode = selectMode(mode, ResetType.SOFT);
- if (mixed)
- mode = selectMode(mode, ResetType.MIXED);
- if (hard)
- mode = selectMode(mode, ResetType.HARD);
- if (mode == null)
- throw die("no reset mode set");
- command.setMode(mode);
- command.call();
+ protected void run() {
+ try (Git git = new Git(db)) {
+ ResetCommand command = git.reset();
+ command.setRef(commit);
+ if (!paths.isEmpty()) {
+ for (String path : paths) {
+ command.addPath(path);
+ }
+ } else {
+ ResetType mode = null;
+ if (soft) {
+ mode = selectMode(mode, ResetType.SOFT);
+ }
+ if (mixed) {
+ mode = selectMode(mode, ResetType.MIXED);
+ }
+ if (hard) {
+ mode = selectMode(mode, ResetType.HARD);
+ }
+ if (mode == null) {
+ throw die(CLIText.get().resetNoMode);
+ }
+ command.setMode(mode);
+ }
+ command.call();
+ } catch (GitAPIException e) {
+ throw die(e.getMessage(), e);
+ }
}
private static ResetType selectMode(ResetType mode, ResetType want) {
if (mode != null)
- throw die("reset modes are mutually exclusive, select one");
+ throw die("reset modes are mutually exclusive, select one"); //$NON-NLS-1$
return want;
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevList.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevList.java
index 4420abec16..59fc5f296c 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevList.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevList.java
@@ -1,44 +1,11 @@
/*
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
@@ -52,7 +19,7 @@ import org.eclipse.jgit.revwalk.RevTree;
@Command(usage = "usage_RevList")
class RevList extends RevWalkTextBuiltin {
@Override
- protected void show(final RevCommit c) throws Exception {
+ protected void show(RevCommit c) throws Exception {
if (c.has(RevFlag.UNINTERESTING))
outw.print('-');
c.getId().copyTo(outbuffer, outw);
@@ -65,7 +32,7 @@ class RevList extends RevWalkTextBuiltin {
}
@Override
- protected void show(final ObjectWalk ow, final RevObject obj)
+ protected void show(ObjectWalk ow, RevObject obj)
throws Exception {
if (obj.has(RevFlag.UNINTERESTING))
outw.print('-');
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevParse.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevParse.java
index 5530ac5c99..b1fb07b5b8 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevParse.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevParse.java
@@ -1,77 +1,66 @@
/*
* Copyright (C) 2009, Daniel Cheng (aka SDiZ) <git@sdiz.net>
* Copyright (C) 2009, Daniel Cheng (aka SDiZ) <j16sdiz+freenet@gmail.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2015 Thomas Meyer <thomas@m3y3r.de> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
-import static org.eclipse.jgit.lib.RefDatabase.ALL;
-
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
-import org.kohsuke.args4j.Argument;
-import org.kohsuke.args4j.Option;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.pgm.opt.CmdLineParser;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.Option;
@Command(usage = "usage_RevParse")
class RevParse extends TextBuiltin {
@Option(name = "--all", usage = "usage_RevParseAll")
- boolean all = false;
+ boolean all;
+
+ @Option(name = "--verify", usage = "usage_RevParseVerify")
+ boolean verify;
@Argument(index = 0, metaVar = "metaVar_commitish")
- private final List<ObjectId> commits = new ArrayList<ObjectId>();
+ private List<ObjectId> commits = new ArrayList<>();
@Override
- protected void run() throws Exception {
- if (all) {
- Map<String, Ref> allRefs = db.getRefDatabase().getRefs(ALL);
- for (final Ref r : allRefs.values())
- outw.println(r.getObjectId().name());
- } else {
- for (final ObjectId o : commits)
- outw.println(o.name());
+ protected void run() {
+ try {
+ if (all) {
+ for (Ref r : db.getRefDatabase().getRefs()) {
+ ObjectId objectId = r.getObjectId();
+ // getRefs skips dangling symrefs, so objectId should never
+ // be null.
+ if (objectId == null) {
+ throw new NullPointerException();
+ }
+ outw.println(objectId.name());
+ }
+ } else {
+ if (verify && commits.size() > 1) {
+ final CmdLineParser clp = new CmdLineParser(this);
+ throw new CmdLineException(clp,
+ CLIText.format(CLIText.get().needSingleRevision));
+ }
+
+ for (ObjectId o : commits) {
+ outw.println(o.name());
+ }
+ }
+ } catch (IOException | CmdLineException e) {
+ throw die(e.getMessage(), e);
}
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java
index d6063c31b4..51e597c57a 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/RevWalkTextBuiltin.java
@@ -1,44 +1,11 @@
/*
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
@@ -47,16 +14,12 @@ import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
-import java.util.Map;
-import org.kohsuke.args4j.Argument;
-import org.kohsuke.args4j.Option;
import org.eclipse.jgit.diff.DiffConfig;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.pgm.opt.PathTreeFilterHandler;
import org.eclipse.jgit.revwalk.FollowFilter;
@@ -73,6 +36,8 @@ import org.eclipse.jgit.revwalk.filter.MessageRevFilter;
import org.eclipse.jgit.revwalk.filter.RevFilter;
import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
abstract class RevWalkTextBuiltin extends TextBuiltin {
RevWalk walk;
@@ -93,7 +58,7 @@ abstract class RevWalkTextBuiltin extends TextBuiltin {
private final EnumSet<RevSort> sorting = EnumSet.noneOf(RevSort.class);
- private void enableRevSort(final RevSort type, final boolean on) {
+ private void enableRevSort(RevSort type, boolean on) {
if (on)
sorting.add(type);
else
@@ -101,22 +66,22 @@ abstract class RevWalkTextBuiltin extends TextBuiltin {
}
@Option(name = "--date-order")
- void enableDateOrder(final boolean on) {
+ void enableDateOrder(boolean on) {
enableRevSort(RevSort.COMMIT_TIME_DESC, on);
}
@Option(name = "--topo-order")
- void enableTopoOrder(final boolean on) {
+ void enableTopoOrder(boolean on) {
enableRevSort(RevSort.TOPO, on);
}
@Option(name = "--reverse")
- void enableReverse(final boolean on) {
+ void enableReverse(boolean on) {
enableRevSort(RevSort.REVERSE, on);
}
@Option(name = "--boundary")
- void enableBoundary(final boolean on) {
+ void enableBoundary(boolean on) {
enableRevSort(RevSort.BOUNDARY, on);
}
@@ -124,25 +89,25 @@ abstract class RevWalkTextBuiltin extends TextBuiltin {
private String followPath;
@Argument(index = 0, metaVar = "metaVar_commitish")
- private final List<RevCommit> commits = new ArrayList<RevCommit>();
+ private List<RevCommit> commits = new ArrayList<>();
- @Option(name = "--", metaVar = "metaVar_path", multiValued = true, handler = PathTreeFilterHandler.class)
+ @Option(name = "--", metaVar = "metaVar_path", handler = PathTreeFilterHandler.class)
protected TreeFilter pathFilter = TreeFilter.ALL;
- private final List<RevFilter> revLimiter = new ArrayList<RevFilter>();
+ private final List<RevFilter> revLimiter = new ArrayList<>();
@Option(name = "--author")
- void addAuthorRevFilter(final String who) {
+ void addAuthorRevFilter(String who) {
revLimiter.add(AuthorRevFilter.create(who));
}
@Option(name = "--committer")
- void addCommitterRevFilter(final String who) {
+ void addCommitterRevFilter(String who) {
revLimiter.add(CommitterRevFilter.create(who));
}
@Option(name = "--grep")
- void addCMessageRevFilter(final String msg) {
+ void addCMessageRevFilter(String msg) {
revLimiter.add(MessageRevFilter.create(msg));
}
@@ -152,7 +117,7 @@ abstract class RevWalkTextBuiltin extends TextBuiltin {
@Override
protected void run() throws Exception {
walk = createWalk();
- for (final RevSort s : sorting)
+ for (RevSort s : sorting)
walk.sort(s, true);
if (pathFilter == TreeFilter.ALL) {
@@ -163,6 +128,9 @@ abstract class RevWalkTextBuiltin extends TextBuiltin {
walk.setTreeFilter(AndTreeFilter.create(pathFilter,
TreeFilter.ANY_DIFF));
}
+ if (parents) {
+ walk.setRewriteParents(true);
+ }
if (revLimiter.size() == 1)
walk.setRevFilter(revLimiter.get(0));
@@ -170,9 +138,7 @@ abstract class RevWalkTextBuiltin extends TextBuiltin {
walk.setRevFilter(AndRevFilter.create(revLimiter));
if (all) {
- Map<String, Ref> refs =
- db.getRefDatabase().getRefs(RefDatabase.ALL);
- for (Ref a : refs.values()) {
+ for (Ref a : db.getRefDatabase().getRefs()) {
ObjectId oid = a.getPeeledObjectId();
if (oid == null)
oid = a.getObjectId();
@@ -190,7 +156,7 @@ abstract class RevWalkTextBuiltin extends TextBuiltin {
throw die(MessageFormat.format(CLIText.get().cannotResolve, Constants.HEAD));
commits.add(walk.parseCommit(head));
}
- for (final RevCommit c : commits) {
+ for (RevCommit c : commits) {
final RevCommit real = argWalk == walk ? c : walk.parseCommit(c);
if (c.has(RevFlag.UNINTERESTING))
walk.markUninteresting(real);
@@ -210,6 +176,11 @@ abstract class RevWalkTextBuiltin extends TextBuiltin {
}
}
+ /**
+ * Create RevWalk
+ *
+ * @return a {@link org.eclipse.jgit.revwalk.RevWalk} object.
+ */
protected RevWalk createWalk() {
RevWalk result;
if (objects)
@@ -222,9 +193,16 @@ abstract class RevWalkTextBuiltin extends TextBuiltin {
return result;
}
+ /**
+ * Loop the walk
+ *
+ * @return number of RevCommits walked
+ * @throws java.lang.Exception
+ * if any.
+ */
protected int walkLoop() throws Exception {
int n = 0;
- for (final RevCommit c : walk) {
+ for (RevCommit c : walk) {
if (++n > maxCount && maxCount >= 0)
break;
show(c);
@@ -248,10 +226,11 @@ abstract class RevWalkTextBuiltin extends TextBuiltin {
* RevWalkTextBuiltin.
*
* @param c
- * The current {@link RevCommit}
+ * The current {@link org.eclipse.jgit.revwalk.RevCommit}
* @throws Exception
+ * if an error occurred
*/
- protected abstract void show(final RevCommit c) throws Exception;
+ protected abstract void show(RevCommit c) throws Exception;
/**
* "Show" the current RevCommit when called from the main processing loop.
@@ -260,10 +239,12 @@ abstract class RevWalkTextBuiltin extends TextBuiltin {
* process RevCommits.
*
* @param objectWalk
- * the {@link ObjectWalk} used by {@link #walkLoop()}
+ * the {@link org.eclipse.jgit.revwalk.ObjectWalk} used by
+ * {@link #walkLoop()}
* @param currentObject
- * The current {@link RevObject}
+ * The current {@link org.eclipse.jgit.revwalk.RevObject}
* @throws Exception
+ * if an error occurred
*/
protected void show(final ObjectWalk objectWalk,
final RevObject currentObject) throws Exception {
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Rm.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Rm.java
index 816b3104c2..234da1a1c5 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Rm.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Rm.java
@@ -1,45 +1,12 @@
/*
* Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com>
- * Copyright (C) 2008, Google Inc.
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Google Inc. and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
@@ -49,24 +16,27 @@ import java.util.List;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.RmCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
import org.kohsuke.args4j.spi.StopOptionHandler;
@Command(usage = "usage_StopTrackingAFile", common = true)
class Rm extends TextBuiltin {
- @Argument(metaVar = "metaVar_path", usage = "usage_path", multiValued = true, required = true)
-
+ @Argument(metaVar = "metaVar_path", usage = "usage_path", required = true)
@Option(name = "--", handler = StopOptionHandler.class)
- private List<String> paths = new ArrayList<String>();
-
+ private List<String> paths = new ArrayList<>();
@Override
- protected void run() throws Exception {
- RmCommand command = new Git(db).rm();
- for (String p : paths)
- command.addFilepattern(p);
- command.call();
+ protected void run() {
+ try (Git git = new Git(db)) {
+ RmCommand command = git.rm();
+ for (String p : paths) {
+ command.addFilepattern(p);
+ }
+ command.call();
+ } catch (GitAPIException e) {
+ throw die(e.getMessage(), e);
+ }
}
-
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java
index b668139b5e..a3a6782a71 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java
@@ -1,57 +1,23 @@
/*
* Copyright (C) 2010, Google Inc.
* Copyright (C) 2006-2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
import java.io.BufferedOutputStream;
import java.io.IOException;
-import java.text.DateFormat;
import java.text.MessageFormat;
-import java.text.SimpleDateFormat;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
import java.util.Locale;
-import java.util.TimeZone;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.RawTextComparator;
@@ -59,11 +25,17 @@ import org.eclipse.jgit.diff.RenameDetector;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.errors.RevisionSyntaxException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.GpgConfig;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.SignatureVerifier.SignatureVerification;
+import org.eclipse.jgit.lib.SignatureVerifiers;
import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.pgm.internal.VerificationUtils;
import org.eclipse.jgit.pgm.opt.PathTreeFilterHandler;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
@@ -72,24 +44,31 @@ import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
+import org.eclipse.jgit.util.RawParseUtils;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@Command(common = true, usage = "usage_show")
class Show extends TextBuiltin {
- private final TimeZone myTZ = TimeZone.getDefault();
+ private final ZoneId myTZ = ZoneId.systemDefault();
- private final DateFormat fmt;
+ private final DateTimeFormatter fmt;
- private final DiffFormatter diffFmt = new DiffFormatter( //
- new BufferedOutputStream(System.out));
+ private DiffFormatter diffFmt;
+
+ private boolean showNameOnly = false;
+
+ private boolean showNameAndStatusOnly = false;
@Argument(index = 0, metaVar = "metaVar_object")
private String objectName;
- @Option(name = "--", metaVar = "metaVar_path", multiValued = true, handler = PathTreeFilterHandler.class)
+ @Option(name = "--", metaVar = "metaVar_path", handler = PathTreeFilterHandler.class)
protected TreeFilter pathFilter = TreeFilter.ALL;
+ @Option(name = "--show-signature", usage = "usage_showSignature")
+ private boolean showSignature;
+
// BEGIN -- Options shared with Diff
@Option(name = "-p", usage = "usage_showPatch")
boolean showPatch;
@@ -106,7 +85,22 @@ class Show extends TextBuiltin {
private Integer renameLimit;
@Option(name = "--name-status", usage = "usage_nameStatus")
- private boolean showNameAndStatusOnly;
+ void nameAndStatusOnly(boolean on) {
+ if (showNameOnly) {
+ throw new IllegalArgumentException(
+ CLIText.get().cannotUseNameStatusOnlyAndNameOnly);
+ }
+ showNameAndStatusOnly = on;
+ }
+
+ @Option(name = "--name-only", usage = "usage_nameOnly")
+ void nameOnly(boolean on) {
+ if (showNameAndStatusOnly) {
+ throw new IllegalArgumentException(
+ CLIText.get().cannotUseNameStatusOnlyAndNameOnly);
+ }
+ showNameOnly = on;
+ }
@Option(name = "--ignore-space-at-eol")
void ignoreSpaceAtEol(@SuppressWarnings("unused") boolean on) {
@@ -162,27 +156,36 @@ class Show extends TextBuiltin {
// END -- Options shared with Diff
Show() {
- fmt = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy ZZZZZ", Locale.US); //$NON-NLS-1$
+ fmt = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss yyyy ZZ", //$NON-NLS-1$
+ Locale.US);
+ }
+
+ @Override
+ protected void init(Repository repository, String gitDir) {
+ super.init(repository, gitDir);
+ diffFmt = new DiffFormatter(new BufferedOutputStream(outs));
}
@SuppressWarnings("boxing")
@Override
- protected void run() throws Exception {
+ protected void run() {
diffFmt.setRepository(db);
try {
diffFmt.setPathFilter(pathFilter);
- if (detectRenames != null)
+ if (detectRenames != null) {
diffFmt.setDetectRenames(detectRenames.booleanValue());
+ }
if (renameLimit != null && diffFmt.isDetectRenames()) {
RenameDetector rd = diffFmt.getRenameDetector();
rd.setRenameLimit(renameLimit.intValue());
}
ObjectId objectId;
- if (objectName == null)
+ if (objectName == null) {
objectId = db.resolve(Constants.HEAD);
- else
+ } else {
objectId = db.resolve(objectName);
+ }
try (RevWalk rw = new RevWalk(db)) {
RevObject obj = rw.parseAny(objectId);
@@ -216,6 +219,8 @@ class Show extends TextBuiltin {
obj.getType()));
}
}
+ } catch (RevisionSyntaxException | IOException e) {
+ throw die(e.getMessage(), e);
} finally {
diffFmt.close();
}
@@ -227,44 +232,54 @@ class Show extends TextBuiltin {
outw.print(tag.getTagName());
outw.println();
- final PersonIdent tagger = tag.getTaggerIdent();
+ PersonIdent tagger = tag.getTaggerIdent();
if (tagger != null) {
outw.println(MessageFormat.format(CLIText.get().taggerInfo,
tagger.getName(), tagger.getEmailAddress()));
- final TimeZone taggerTZ = tagger.getTimeZone();
- fmt.setTimeZone(taggerTZ != null ? taggerTZ : myTZ);
+ ZoneId taggerTZ = tagger.getZoneId();
+ String formattedTaggerTime = fmt
+ .withZone(taggerTZ != null ? taggerTZ : myTZ)
+ .format(tagger.getWhenAsInstant());
outw.println(MessageFormat.format(CLIText.get().dateInfo,
- fmt.format(tagger.getWhen())));
+ formattedTaggerTime));
}
outw.println();
- final String[] lines = tag.getFullMessage().split("\n"); //$NON-NLS-1$
- for (final String s : lines) {
- outw.print(" "); //$NON-NLS-1$
- outw.print(s);
- outw.println();
+ String fullMessage = tag.getFullMessage();
+ if (!fullMessage.isEmpty()) {
+ String[] lines = tag.getFullMessage().split("\n"); //$NON-NLS-1$
+ for (String s : lines) {
+ outw.println(s);
+ }
+ }
+ byte[] rawSignature = tag.getRawGpgSignature();
+ if (rawSignature != null) {
+ String[] lines = RawParseUtils.decode(rawSignature).split("\n"); //$NON-NLS-1$
+ for (String s : lines) {
+ outw.println(s);
+ }
}
-
outw.println();
}
private void show(RevTree obj) throws MissingObjectException,
IncorrectObjectTypeException, CorruptObjectException, IOException {
- final TreeWalk walk = new TreeWalk(db);
- walk.reset();
- walk.addTree(obj);
-
- while (walk.next()) {
- outw.print(walk.getPathString());
- final FileMode mode = walk.getFileMode(0);
- if (mode == FileMode.TREE)
- outw.print("/"); //$NON-NLS-1$
- outw.println();
+ try (TreeWalk walk = new TreeWalk(db)) {
+ walk.reset();
+ walk.addTree(obj);
+
+ while (walk.next()) {
+ outw.print(walk.getPathString());
+ final FileMode mode = walk.getFileMode(0);
+ if (mode == FileMode.TREE)
+ outw.print("/"); //$NON-NLS-1$
+ outw.println();
+ }
}
}
- private void show(RevWalk rw, final RevCommit c) throws Exception {
+ private void show(RevWalk rw, RevCommit c) throws IOException {
char[] outbuffer = new char[Constants.OBJECT_ID_LENGTH * 2];
outw.print(CLIText.get().commitLabel);
@@ -272,18 +287,24 @@ class Show extends TextBuiltin {
c.getId().copyTo(outbuffer, outw);
outw.println();
+ if (showSignature) {
+ showSignature(c);
+ }
+
final PersonIdent author = c.getAuthorIdent();
outw.println(MessageFormat.format(CLIText.get().authorInfo,
author.getName(), author.getEmailAddress()));
- final TimeZone authorTZ = author.getTimeZone();
- fmt.setTimeZone(authorTZ != null ? authorTZ : myTZ);
+ final ZoneId authorTZ = author.getZoneId();
+ String formattedAuthorTime = fmt
+ .withZone(authorTZ != null ? authorTZ : myTZ)
+ .format(author.getWhenAsInstant());
outw.println(MessageFormat.format(CLIText.get().dateInfo,
- fmt.format(author.getWhen())));
+ formattedAuthorTime));
outw.println();
final String[] lines = c.getFullMessage().split("\n"); //$NON-NLS-1$
- for (final String s : lines) {
+ for (String s : lines) {
outw.print(" "); //$NON-NLS-1$
outw.print(s);
outw.println();
@@ -301,13 +322,29 @@ class Show extends TextBuiltin {
final RevTree a = c.getParent(0).getTree();
final RevTree b = c.getTree();
- if (showNameAndStatusOnly)
+ if (showNameAndStatusOnly) {
Diff.nameStatus(outw, diffFmt.scan(a, b));
- else {
+ } else if (showNameOnly) {
+ Diff.nameOnly(outw, diffFmt.scan(a, b));
+ } else {
outw.flush();
diffFmt.format(a, b);
diffFmt.flush();
}
outw.println();
}
+
+ private void showSignature(RevCommit c) throws IOException {
+ if (c.getRawGpgSignature() == null) {
+ return;
+ }
+ GpgConfig config = new GpgConfig(db.getConfig());
+ SignatureVerification verification = SignatureVerifiers.verify(db,
+ config, c);
+ if (verification == null) {
+ throw die(CLIText.get().logNoSignatureVerifier, null);
+ }
+ VerificationUtils.writeVerification(outw, verification,
+ verification.verifierName(), c.getCommitterIdent());
+ }
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ShowRef.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ShowRef.java
index e9d9df6a19..64b182e17d 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ShowRef.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ShowRef.java
@@ -1,81 +1,48 @@
/*
* Copyright (C) 2010, Google Inc.
* Copyright (C) 2008, Jonas Fonseca <fonseca@diku.dk>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
-import static org.eclipse.jgit.lib.RefDatabase.ALL;
-
import java.io.IOException;
-import java.util.Map;
-import java.util.SortedMap;
+import java.util.List;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefComparator;
-import org.eclipse.jgit.util.RefMap;
@Command(usage = "usage_ShowRef")
class ShowRef extends TextBuiltin {
@Override
- protected void run() throws Exception {
- for (final Ref r : getSortedRefs()) {
- show(r.getObjectId(), r.getName());
- if (r.getPeeledObjectId() != null)
- show(r.getPeeledObjectId(), r.getName() + "^{}"); //$NON-NLS-1$
+ protected void run() {
+ try {
+ for (Ref r : getSortedRefs()) {
+ show(r.getObjectId(), r.getName());
+ if (r.getPeeledObjectId() != null) {
+ show(r.getPeeledObjectId(), r.getName() + "^{}"); //$NON-NLS-1$
+ }
+ }
+ } catch (IOException e) {
+ throw die(e.getMessage(), e);
}
}
- private Iterable<Ref> getSortedRefs() throws Exception {
- Map<String, Ref> all = db.getRefDatabase().getRefs(ALL);
- if (all instanceof RefMap
- || (all instanceof SortedMap && ((SortedMap) all).comparator() == null))
- return all.values();
- return RefComparator.sort(all.values());
+ private Iterable<Ref> getSortedRefs() throws IOException {
+ List<Ref> all = db.getRefDatabase().getRefs();
+ // TODO(jrn) check if we can reintroduce fast-path by e.g. implementing
+ // SortedList
+ return RefComparator.sort(all);
}
- private void show(final AnyObjectId id, final String name)
+ private void show(AnyObjectId id, String name)
throws IOException {
outw.print(id.name());
outw.print('\t');
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java
index 12d4208152..c96e475613 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Status.java
@@ -1,44 +1,11 @@
/*
- * Copyright (C) 2011, 2015 François Rey <eclipse.org_@_francois_._rey_._name>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2011, 2015 François Rey <eclipse.org_@_francois_._rey_._name> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
@@ -54,14 +21,17 @@ import java.util.TreeSet;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.StatusCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.IndexDiff.StageState;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.pgm.internal.CLIText;
-import org.kohsuke.args4j.Option;
-
import org.eclipse.jgit.pgm.opt.UntrackedFilesHandler;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+import org.kohsuke.args4j.spi.RestOfArgumentsHandler;
/**
* Status command
@@ -69,8 +39,6 @@ import org.eclipse.jgit.pgm.opt.UntrackedFilesHandler;
@Command(usage = "usage_Status", common = true)
class Status extends TextBuiltin {
- protected final String lineFormat = CLIText.get().lineFormat;
-
protected final String statusFileListFormat = CLIText.get().statusFileListFormat;
protected final String statusFileListFormatWithPrefix = CLIText.get().statusFileListFormatWithPrefix;
@@ -83,17 +51,24 @@ class Status extends TextBuiltin {
@Option(name = "--untracked-files", aliases = { "-u", "-uno", "-uall" }, usage = "usage_untrackedFilesMode", handler = UntrackedFilesHandler.class)
protected String untrackedFilesMode = "all"; // default value //$NON-NLS-1$
- @Option(name = "--", metaVar = "metaVar_path", multiValued = true)
+ @Argument(required = false, index = 0, metaVar = "metaVar_paths")
+ @Option(name = "--", metaVar = "metaVar_paths", handler = RestOfArgumentsHandler.class)
protected List<String> filterPaths;
@Override
- protected void run() throws Exception {
- StatusCommand statusCommand = new Git(db).status();
- if (filterPaths != null && filterPaths.size() > 0)
- for (String path : filterPaths)
- statusCommand.addPath(path);
- org.eclipse.jgit.api.Status status = statusCommand.call();
- printStatus(status);
+ protected void run() {
+ try (Git git = new Git(db)) {
+ StatusCommand statusCommand = git.status();
+ if (filterPaths != null) {
+ for (String path : filterPaths) {
+ statusCommand.addPath(path);
+ }
+ }
+ org.eclipse.jgit.api.Status status = statusCommand.call();
+ printStatus(status);
+ } catch (GitAPIException | NoWorkTreeException | IOException e) {
+ throw die(e.getMessage(), e);
+ }
}
private void printStatus(org.eclipse.jgit.api.Status status)
@@ -115,7 +90,7 @@ class Status extends TextBuiltin {
Map<String, StageState> conflicting = status.getConflictingStageState();
// build a sorted list of all paths except untracked and ignored
- TreeSet<String> sorted = new TreeSet<String>();
+ TreeSet<String> sorted = new TreeSet<>();
sorted.addAll(added);
sorted.addAll(changed);
sorted.addAll(removed);
@@ -183,7 +158,7 @@ class Status extends TextBuiltin {
// untracked are always at the end of the list
if ("all".equals(untrackedFilesMode)) { //$NON-NLS-1$
- TreeSet<String> untracked = new TreeSet<String>(
+ TreeSet<String> untracked = new TreeSet<>(
status.getUntracked());
for (String path : untracked)
printPorcelainLine('?', '?', path);
@@ -200,7 +175,7 @@ class Status extends TextBuiltin {
private void printLongStatus(org.eclipse.jgit.api.Status status)
throws IOException {
// Print current branch name
- final Ref head = db.getRef(Constants.HEAD);
+ final Ref head = db.exactRef(Constants.HEAD);
if (head != null && head.isSymbolic()) {
String branch = Repository.shortenRefName(head.getLeaf().getName());
outw.println(CLIText.formatLine(MessageFormat.format(
@@ -219,7 +194,7 @@ class Status extends TextBuiltin {
Collection<String> untracked = status.getUntracked();
Map<String, StageState> unmergedStates = status
.getConflictingStageState();
- Collection<String> toBeCommitted = new ArrayList<String>(added);
+ Collection<String> toBeCommitted = new ArrayList<>(added);
toBeCommitted.addAll(changed);
toBeCommitted.addAll(removed);
int nbToBeCommitted = toBeCommitted.size();
@@ -230,7 +205,7 @@ class Status extends TextBuiltin {
toBeCommitted, added, changed, removed);
firstHeader = false;
}
- Collection<String> notStagedForCommit = new ArrayList<String>(modified);
+ Collection<String> notStagedForCommit = new ArrayList<>(modified);
notStagedForCommit.addAll(missing);
int nbNotStagedForCommit = notStagedForCommit.size();
if (nbNotStagedForCommit > 0) {
@@ -251,7 +226,7 @@ class Status extends TextBuiltin {
firstHeader = false;
}
int nbUntracked = untracked.size();
- if (nbUntracked > 0 && ("all".equals(untrackedFilesMode))) { //$NON-NLS-1$
+ if (nbUntracked > 0 && "all".equals(untrackedFilesMode)) { //$NON-NLS-1$
if (!firstHeader)
printSectionHeader(""); //$NON-NLS-1$
printSectionHeader(CLIText.get().untrackedFiles);
@@ -259,20 +234,39 @@ class Status extends TextBuiltin {
}
}
+ /**
+ * Print section header
+ *
+ * @param pattern
+ * a {@link String} object.
+ * @param arguments
+ * a {@link Object} object.
+ * @throws IOException
+ * if an IO error occurred
+ */
protected void printSectionHeader(String pattern, Object... arguments)
throws IOException {
if (!porcelain) {
outw.println(CLIText.formatLine(MessageFormat.format(pattern,
arguments)));
- if (!pattern.equals("")) //$NON-NLS-1$
+ if (!pattern.isEmpty())
outw.println(CLIText.formatLine("")); //$NON-NLS-1$
outw.flush();
}
}
+ /**
+ * Print String list
+ *
+ * @param list
+ * a {@link Collection} object.
+ * @return size of the list
+ * @throws IOException
+ * if an IO error occurred
+ */
protected int printList(Collection<String> list) throws IOException {
if (!list.isEmpty()) {
- List<String> sortedList = new ArrayList<String>(list);
+ List<String> sortedList = new ArrayList<>(list);
java.util.Collections.sort(sortedList);
for (String filename : sortedList) {
outw.println(CLIText.formatLine(String.format(
@@ -280,16 +274,37 @@ class Status extends TextBuiltin {
}
outw.flush();
return list.size();
- } else
- return 0;
+ }
+ return 0;
}
+ /**
+ * Print String list
+ *
+ * @param status1
+ * a {@link String} object.
+ * @param status2
+ * a {@link String} object.
+ * @param status3
+ * a {@link String} object.
+ * @param list
+ * a {@link Collection} object.
+ * @param set1
+ * a {@link Collection} object.
+ * @param set2
+ * a {@link Collection} object.
+ * @param set3
+ * a {@link Collection} object.
+ * @return a int.
+ * @throws IOException
+ * if an IO error occurred
+ */
protected int printList(String status1, String status2, String status3,
Collection<String> list, Collection<String> set1,
Collection<String> set2,
- @SuppressWarnings("unused") Collection<String> set3)
+ Collection<String> set3)
throws IOException {
- List<String> sortedList = new ArrayList<String>(list);
+ List<String> sortedList = new ArrayList<>(list);
java.util.Collections.sort(sortedList);
for (String filename : sortedList) {
String prefix;
@@ -309,7 +324,7 @@ class Status extends TextBuiltin {
private void printUnmerged(Map<String, StageState> unmergedStates)
throws IOException {
- List<String> paths = new ArrayList<String>(unmergedStates.keySet());
+ List<String> paths = new ArrayList<>(unmergedStates.keySet());
Collections.sort(paths);
for (String path : paths) {
StageState state = unmergedStates.get(path);
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java
index a90d4c4dad..6be30c9447 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Tag.java
@@ -4,72 +4,83 @@
* Copyright (C) 2008, Charles O'Farrell <charleso@charleso.org>
* Copyright (C) 2008, Robin Rosenberg <robin.rosenberg.lists@dewire.com>
* Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, 2021 Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
+import java.io.IOException;
import java.text.MessageFormat;
import java.util.List;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ListTagCommand;
import org.eclipse.jgit.api.TagCommand;
+import org.eclipse.jgit.api.VerificationResult;
+import org.eclipse.jgit.api.VerifySignatureCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
+import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.SignatureVerifier.SignatureVerification;
import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.pgm.internal.VerificationUtils;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.revwalk.RevWalk;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@Command(common = true, usage = "usage_CreateATag")
class Tag extends TextBuiltin {
- @Option(name = "-f", usage = "usage_forceReplacingAnExistingTag")
+
+ @Option(name = "--force", aliases = { "-f" }, forbids = { "--delete",
+ "--verify" }, usage = "usage_forceReplacingAnExistingTag")
private boolean force;
- @Option(name = "-m", metaVar = "metaVar_message", usage = "usage_tagMessage")
- private String message = ""; //$NON-NLS-1$
+ @Option(name = "--delete", aliases = { "-d" }, forbids = {
+ "--verify" }, usage = "usage_tagDelete")
+ private boolean delete;
+
+ @Option(name = "--annotate", aliases = {
+ "-a" }, forbids = { "--delete",
+ "--verify" }, usage = "usage_tagAnnotated")
+ private boolean annotated;
+
+ @Option(name = "-m", forbids = { "--delete",
+ "--verify" }, metaVar = "metaVar_message", usage = "usage_tagMessage")
+ private String message;
+
+ @Option(name = "--sign", aliases = { "-s" }, forbids = {
+ "--no-sign", "--delete", "--verify" }, usage = "usage_tagSign")
+ private boolean sign;
+
+ @Option(name = "--no-sign", usage = "usage_tagNoSign", forbids = {
+ "--sign", "--delete", "--verify" })
+ private boolean noSign;
+
+ @Option(name = "--local-user", aliases = {
+ "-u" }, forbids = { "--delete",
+ "--verify" }, metaVar = "metaVar_tagLocalUser", usage = "usage_tagLocalUser")
+ private String gpgKeyId;
+
+ @Option(name = "--verify", aliases = { "-v" }, forbids = { "--delete",
+ "--force", "--annotate", "-m", "--sign", "--no-sign",
+ "--local-user" }, usage = "usage_tagVerify")
+ private boolean verify;
+
+ @Option(name = "--contains", forbids = { "--delete", "--force",
+ "--annotate", "-m", "--sign", "--no-sign",
+ "--local-user" }, metaVar = "metaVar_commitish", usage = "usage_tagContains")
+ private RevCommit contains;
@Argument(index = 0, metaVar = "metaVar_name")
private String tagName;
@@ -78,28 +89,107 @@ class Tag extends TextBuiltin {
private ObjectId object;
@Override
- protected void run() throws Exception {
- Git git = new Git(db);
- if (tagName != null) {
- TagCommand command = git.tag().setForceUpdate(force)
- .setMessage(message).setName(tagName);
-
- if (object != null) {
- RevWalk walk = new RevWalk(db);
- command.setObjectId(walk.parseAny(object));
+ protected void run() {
+ try (Git git = new Git(db)) {
+ if (tagName != null) {
+ if (verify) {
+ VerifySignatureCommand verifySig = git.verifySignature()
+ .setMode(VerifySignatureCommand.VerifyMode.TAGS)
+ .addName(tagName);
+
+ VerificationResult verification = verifySig.call()
+ .get(tagName);
+ if (verification == null) {
+ showUnsigned(git, tagName);
+ } else {
+ Throwable error = verification.getException();
+ if (error != null) {
+ throw die(error.getMessage(), error);
+ }
+ writeVerification(
+ verification.getVerification().verifierName(),
+ (RevTag) verification.getObject(),
+ verification.getVerification());
+ }
+ } else if (delete) {
+ List<String> deletedTags = git.tagDelete().setTags(tagName)
+ .call();
+ if (deletedTags.isEmpty()) {
+ throw die(MessageFormat
+ .format(CLIText.get().tagNotFound, tagName));
+ }
+ } else {
+ TagCommand command = git.tag().setForceUpdate(force)
+ .setMessage(message).setName(tagName);
+
+ if (object != null) {
+ try (RevWalk walk = new RevWalk(db)) {
+ command.setObjectId(walk.parseAny(object));
+ }
+ }
+ if (noSign) {
+ command.setSigned(false);
+ } else if (sign) {
+ command.setSigned(true);
+ }
+ if (annotated) {
+ command.setAnnotated(true);
+ } else if (message == null && !sign && gpgKeyId == null) {
+ // None of -a, -m, -s, -u given
+ command.setAnnotated(false);
+ }
+ command.setSigningKey(gpgKeyId);
+ try {
+ command.call();
+ } catch (RefAlreadyExistsException e) {
+ throw die(MessageFormat.format(
+ CLIText.get().tagAlreadyExists, tagName), e);
+ }
+ }
+ } else {
+ ListTagCommand command = git.tagList();
+ if (contains != null) {
+ command.setContains(contains);
+ }
+ List<Ref> list = command.call();
+ for (Ref ref : list) {
+ outw.println(Repository.shortenRefName(ref.getName()));
+ }
}
- try {
- command.call();
- } catch (RefAlreadyExistsException e) {
- throw die(MessageFormat.format(CLIText.get().tagAlreadyExists,
- tagName));
+ } catch (GitAPIException | IOException e) {
+ throw die(e.getMessage(), e);
+ }
+ }
+
+ private void showUnsigned(Git git, String wantedTag) throws IOException {
+ ObjectId id = git.getRepository().resolve(wantedTag);
+ if (id != null && !ObjectId.zeroId().equals(id)) {
+ try (RevWalk walk = new RevWalk(git.getRepository())) {
+ showTag(walk.parseTag(id));
}
} else {
- ListTagCommand command = git.tagList();
- List<Ref> list = command.call();
- for (Ref ref : list) {
- outw.println(Repository.shortenRefName(ref.getName()));
- }
+ throw die(
+ MessageFormat.format(CLIText.get().tagNotFound, wantedTag));
+ }
+ }
+
+ private void showTag(RevTag tag) throws IOException {
+ outw.println("object " + tag.getObject().name()); //$NON-NLS-1$
+ outw.println("type " + Constants.typeString(tag.getObject().getType())); //$NON-NLS-1$
+ outw.println("tag " + tag.getTagName()); //$NON-NLS-1$
+ outw.println("tagger " + tag.getTaggerIdent().toExternalString()); //$NON-NLS-1$
+ outw.println();
+ outw.print(tag.getFullMessage());
+ }
+
+ private void writeVerification(String name, RevTag tag,
+ SignatureVerification verification) throws IOException {
+ showTag(tag);
+ if (verification == null) {
+ outw.println();
+ return;
}
+ VerificationUtils.writeVerification(outw, verification, name,
+ tag.getTaggerIdent());
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java
index 8e8b82fe07..c572e3bc7d 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java
@@ -1,49 +1,19 @@
/*
* Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_LOG_OUTPUT_ENCODING;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_SECTION_I18N;
import static org.eclipse.jgit.lib.Constants.R_HEADS;
import static org.eclipse.jgit.lib.Constants.R_REMOTES;
import static org.eclipse.jgit.lib.Constants.R_TAGS;
@@ -56,15 +26,21 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
+import java.nio.charset.Charset;
import java.text.MessageFormat;
import java.util.ResourceBundle;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.pgm.internal.SshDriver;
import org.eclipse.jgit.pgm.opt.CmdLineParser;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.transport.SshSessionFactory;
+import org.eclipse.jgit.transport.ssh.jsch.JschConfigSessionFactory;
+import org.eclipse.jgit.transport.sshd.DefaultProxyDataFactory;
+import org.eclipse.jgit.transport.sshd.JGitKeyCache;
+import org.eclipse.jgit.transport.sshd.SshdSessionFactory;
import org.eclipse.jgit.util.io.ThrowingPrintWriter;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.Option;
@@ -86,6 +62,9 @@ public abstract class TextBuiltin {
@Option(name = "--help", usage = "usage_displayThisHelpText", aliases = { "-h" })
private boolean help;
+ @Option(name = "--ssh", usage = "usage_sshDriver")
+ private SshDriver sshDriver = SshDriver.APACHE;
+
/**
* Input stream, typically this is standard input.
*
@@ -108,14 +87,6 @@ public abstract class TextBuiltin {
protected OutputStream outs;
/**
- * Stream to output to, typically this is standard output.
- *
- * @deprecated Use outw instead
- */
- @Deprecated
- protected PrintWriter out;
-
- /**
* Error writer, typically this is standard error.
*
* @since 3.4
@@ -138,52 +109,90 @@ public abstract class TextBuiltin {
/** RevWalk used during command line parsing, if it was required. */
protected RevWalk argWalk;
- final void setCommandName(final String name) {
+ final void setCommandName(String name) {
commandName = name;
}
- /** @return true if {@link #db}/{@link #getRepository()} is required. */
+ /**
+ * If this command requires a repository.
+ *
+ * @return true if {@link #db}/{@link #getRepository()} is required
+ */
protected boolean requiresRepository() {
return true;
}
/**
- * Initialize the command to work with a repository.
+ * Initializes the command to work with a repository, including setting the
+ * output and error streams.
*
* @param repository
* the opened repository that the command should work on.
* @param gitDir
* value of the {@code --git-dir} command line option, if
* {@code repository} is null.
+ * @param input
+ * input stream from which input will be read
+ * @param output
+ * output stream to which output will be written
+ * @param error
+ * error stream to which errors will be written
+ * @since 4.9
*/
- protected void init(final Repository repository, final String gitDir) {
- try {
- final String outputEncoding = repository != null ? repository
- .getConfig().getString("i18n", null, "logOutputEncoding") : null; //$NON-NLS-1$ //$NON-NLS-2$
- if (ins == null)
- ins = new FileInputStream(FileDescriptor.in);
- if (outs == null)
- outs = new FileOutputStream(FileDescriptor.out);
- if (errs == null)
- errs = new FileOutputStream(FileDescriptor.err);
- BufferedWriter outbufw;
- if (outputEncoding != null)
- outbufw = new BufferedWriter(new OutputStreamWriter(outs,
- outputEncoding));
- else
- outbufw = new BufferedWriter(new OutputStreamWriter(outs));
- out = new PrintWriter(outbufw);
- outw = new ThrowingPrintWriter(outbufw);
- BufferedWriter errbufw;
- if (outputEncoding != null)
- errbufw = new BufferedWriter(new OutputStreamWriter(errs,
- outputEncoding));
- else
- errbufw = new BufferedWriter(new OutputStreamWriter(errs));
- errw = new ThrowingPrintWriter(errbufw);
- } catch (IOException e) {
- throw die(CLIText.get().cannotCreateOutputStream);
+ public void initRaw(final Repository repository, final String gitDir,
+ InputStream input, OutputStream output, OutputStream error) {
+ this.ins = input;
+ this.outs = output;
+ this.errs = error;
+ init(repository, gitDir);
+ }
+
+ /**
+ * Get the log output encoding specified in the repository's
+ * {@code i18n.logOutputEncoding} configuration.
+ *
+ * @param repository
+ * the repository.
+ * @return Charset corresponding to {@code i18n.logOutputEncoding}, or
+ * {@code UTF_8}.
+ */
+ private Charset getLogOutputEncodingCharset(Repository repository) {
+ if (repository != null) {
+ String logOutputEncoding = repository.getConfig().getString(
+ CONFIG_SECTION_I18N, null, CONFIG_KEY_LOG_OUTPUT_ENCODING);
+ if (logOutputEncoding != null) {
+ try {
+ return Charset.forName(logOutputEncoding);
+ } catch (IllegalArgumentException e) {
+ throw die(CLIText.get().cannotCreateOutputStream, e);
+ }
+ }
}
+ return UTF_8;
+ }
+
+ /**
+ * Initialize the command to work with a repository.
+ *
+ * @param repository
+ * the opened repository that the command should work on.
+ * @param gitDir
+ * value of the {@code --git-dir} command line option, if
+ * {@code repository} is null.
+ */
+ protected void init(Repository repository, String gitDir) {
+ Charset charset = getLogOutputEncodingCharset(repository);
+
+ if (ins == null)
+ ins = new FileInputStream(FileDescriptor.in);
+ if (outs == null)
+ outs = new FileOutputStream(FileDescriptor.out);
+ if (errs == null)
+ errs = new FileOutputStream(FileDescriptor.err);
+ outw = new ThrowingPrintWriter(new BufferedWriter(
+ new OutputStreamWriter(outs, charset)));
+ errw = new ThrowingPrintWriter(new BufferedWriter(
+ new OutputStreamWriter(errs, charset)));
if (repository != null && repository.getDirectory() != null) {
db = repository;
@@ -199,13 +208,34 @@ public abstract class TextBuiltin {
*
* @param args
* command line arguments passed after the command name.
- * @throws Exception
+ * @throws java.lang.Exception
* an error occurred while processing the command. The main
* framework will catch the exception and print a message on
* standard error.
*/
public final void execute(String[] args) throws Exception {
parseArguments(args);
+ switch (sshDriver) {
+ case APACHE: {
+ SshdSessionFactory factory = new SshdSessionFactory(
+ new JGitKeyCache(), new DefaultProxyDataFactory());
+ try {
+ Runtime.getRuntime()
+ .addShutdownHook(new Thread(factory::close));
+ } catch (IllegalStateException e) {
+ // ignore - the VM is already shutting down
+ }
+ SshSessionFactory.setInstance(factory);
+ break;
+ }
+ case JSCH:
+ JschConfigSessionFactory factory = new JschConfigSessionFactory();
+ SshSessionFactory.setInstance(factory);
+ break;
+ default:
+ SshSessionFactory.setInstance(null);
+ break;
+ }
run();
}
@@ -218,21 +248,25 @@ public abstract class TextBuiltin {
*
* @param args
* the arguments supplied on the command line, if any.
- * @throws IOException
+ * @throws java.io.IOException
+ * if an IO error occurred
*/
- protected void parseArguments(final String[] args) throws IOException {
+ protected void parseArguments(String[] args) throws IOException {
final CmdLineParser clp = new CmdLineParser(this);
+ help = containsHelp(args);
try {
clp.parseArgument(args);
} catch (CmdLineException err) {
- if (!help) {
- this.errw.println(MessageFormat.format(CLIText.get().fatalError, err.getMessage()));
- throw die(true);
+ this.errw.println(CLIText.fatalError(err.getMessage()));
+ if (help) {
+ printUsage("", clp); //$NON-NLS-1$
}
+ throw die(true, err);
}
if (help) {
- printUsageAndExit(clp);
+ printUsage("", clp); //$NON-NLS-1$
+ throw new TerminatedByHelpException();
}
argWalk = clp.getRevWalkGently();
@@ -242,9 +276,11 @@ public abstract class TextBuiltin {
* Print the usage line
*
* @param clp
- * @throws IOException
+ * a {@link org.eclipse.jgit.pgm.opt.CmdLineParser} object.
+ * @throws java.io.IOException
+ * if an IO error occurred
*/
- public void printUsageAndExit(final CmdLineParser clp) throws IOException {
+ public void printUsageAndExit(CmdLineParser clp) throws IOException {
printUsageAndExit("", clp); //$NON-NLS-1$
}
@@ -252,10 +288,30 @@ public abstract class TextBuiltin {
* Print an error message and the usage line
*
* @param message
+ * a {@link java.lang.String} object.
* @param clp
- * @throws IOException
+ * a {@link org.eclipse.jgit.pgm.opt.CmdLineParser} object.
+ * @throws java.io.IOException
+ * if an IO error occurred
*/
- public void printUsageAndExit(final String message, final CmdLineParser clp) throws IOException {
+ public void printUsageAndExit(String message, CmdLineParser clp) throws IOException {
+ printUsage(message, clp);
+ throw die(true);
+ }
+
+ /**
+ * Print usage help text.
+ *
+ * @param message
+ * non null
+ * @param clp
+ * parser used to print options
+ * @throws java.io.IOException
+ * if an IO error occurred
+ * @since 4.2
+ */
+ protected void printUsage(String message, CmdLineParser clp)
+ throws IOException {
errw.println(message);
errw.print("jgit "); //$NON-NLS-1$
errw.print(commandName);
@@ -267,12 +323,33 @@ public abstract class TextBuiltin {
errw.println();
errw.flush();
- throw die(true);
}
/**
- * @return the resource bundle that will be passed to args4j for purpose
- * of string localization
+ * Get error writer
+ *
+ * @return error writer, typically this is standard error.
+ * @since 4.2
+ */
+ public ThrowingPrintWriter getErrorWriter() {
+ return errw;
+ }
+
+ /**
+ * Get output writer
+ *
+ * @return output writer, typically this is standard output.
+ * @since 4.9
+ */
+ public ThrowingPrintWriter getOutputWriter() {
+ return outw;
+ }
+
+ /**
+ * Get resource bundle with localized texts
+ *
+ * @return the resource bundle that will be passed to args4j for purpose of
+ * string localization
*/
protected ResourceBundle getResourceBundle() {
return CLIText.get().resourceBundle();
@@ -283,7 +360,7 @@ public abstract class TextBuiltin {
* <p>
* This method should only be invoked by {@link #execute(String[])}.
*
- * @throws Exception
+ * @throws java.lang.Exception
* an error occurred while processing the command. The main
* framework will catch the exception and print a message on
* standard error.
@@ -291,13 +368,15 @@ public abstract class TextBuiltin {
protected abstract void run() throws Exception;
/**
+ * Get the repository
+ *
* @return the repository this command accesses.
*/
public Repository getRepository() {
return db;
}
- ObjectId resolve(final String s) throws IOException {
+ ObjectId resolve(String s) throws IOException {
final ObjectId r = db.resolve(s);
if (r == null)
throw die(MessageFormat.format(CLIText.get().notARevision, s));
@@ -305,28 +384,35 @@ public abstract class TextBuiltin {
}
/**
+ * Exit the command with an error message
+ *
* @param why
* textual explanation
* @return a runtime exception the caller is expected to throw
*/
- protected static Die die(final String why) {
+ protected static Die die(String why) {
return new Die(why);
}
/**
+ * Exit the command with an error message and an exception
+ *
* @param why
* textual explanation
* @param cause
* why the command has failed.
* @return a runtime exception the caller is expected to throw
*/
- protected static Die die(final String why, final Throwable cause) {
+ protected static Die die(String why, Throwable cause) {
return new Die(why, cause);
}
/**
+ * Exit the command
+ *
* @param aborted
- * boolean indicating that the execution has been aborted before running
+ * boolean indicating that the execution has been aborted before
+ * running
* @return a runtime exception the caller is expected to throw
* @since 3.4
*/
@@ -334,6 +420,21 @@ public abstract class TextBuiltin {
return new Die(aborted);
}
+ /**
+ * Exit the command
+ *
+ * @param aborted
+ * boolean indicating that the execution has been aborted before
+ * running
+ * @param cause
+ * why the command has failed.
+ * @return a runtime exception the caller is expected to throw
+ * @since 4.2
+ */
+ protected static Die die(boolean aborted, Throwable cause) {
+ return new Die(aborted, cause);
+ }
+
String abbreviateRef(String dst, boolean abbreviateRemote) {
if (dst.startsWith(R_HEADS))
dst = dst.substring(R_HEADS.length());
@@ -343,4 +444,38 @@ public abstract class TextBuiltin {
dst = dst.substring(R_REMOTES.length());
return dst;
}
+
+ /**
+ * Check if the arguments contain a help option
+ *
+ * @param args
+ * non null
+ * @return true if the given array contains help option
+ * @since 4.2
+ */
+ public static boolean containsHelp(String[] args) {
+ for (String str : args) {
+ if (str.equals("-h") || str.equals("--help")) { //$NON-NLS-1$ //$NON-NLS-2$
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Exception thrown by {@link TextBuiltin} if it proceeds 'help' option
+ *
+ * @since 4.2
+ */
+ public static class TerminatedByHelpException extends Die {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Default constructor
+ */
+ public TerminatedByHelpException() {
+ super(true);
+ }
+
+ }
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java
index 447374d699..db2c393b9a 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java
@@ -1,50 +1,18 @@
/*
* Copyright (C) 2008-2009, Google Inc.
- * Copyright (C) 2009-2010, Robin Rosenberg <robin.rosenberg@dewire.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2009-2010, Robin Rosenberg <robin.rosenberg@dewire.com> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
import java.io.File;
+import java.io.IOException;
import java.text.MessageFormat;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
@@ -68,20 +36,22 @@ class UploadPack extends TextBuiltin {
}
@Override
- protected void run() throws Exception {
- final org.eclipse.jgit.transport.UploadPack up;
-
+ protected void run() {
try {
FileKey key = FileKey.lenient(srcGitdir, FS.DETECTED);
db = key.open(true /* must exist */);
+ try (org.eclipse.jgit.transport.UploadPack up = new org.eclipse.jgit.transport.UploadPack(
+ db)) {
+ if (0 <= timeout) {
+ up.setTimeout(timeout);
+ }
+ up.upload(ins, outs, errs);
+ }
} catch (RepositoryNotFoundException notFound) {
throw die(MessageFormat.format(CLIText.get().notAGitRepository,
- srcGitdir.getPath()));
+ srcGitdir.getPath()), notFound);
+ } catch (IOException e) {
+ throw die(e.getMessage(), e);
}
-
- up = new org.eclipse.jgit.transport.UploadPack(db);
- if (0 <= timeout)
- up.setTimeout(timeout);
- up.upload(ins, outs, errs);
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Version.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Version.java
index 6bed9c6025..8546094ac2 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Version.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Version.java
@@ -1,44 +1,11 @@
/*
- * Copyright (C) 2008, Google Inc.
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Google Inc. and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm;
@@ -56,21 +23,28 @@ import org.eclipse.jgit.pgm.internal.CLIText;
@Command(common = true, usage = "usage_DisplayTheVersionOfJgit")
class Version extends TextBuiltin {
@Override
- protected void run() throws Exception {
+ protected void run() {
// read the Implementation-Version from Manifest
String version = getImplementationVersion();
// if Implementation-Version is not available then try reading
// Bundle-Version
- if (version == null)
+ if (version == null) {
version = getBundleVersion();
+ }
// if both Implementation-Version and Bundle-Version are not available
// then throw an exception
- if (version == null)
+ if (version == null) {
throw die(CLIText.get().cannotReadPackageInformation);
+ }
- outw.println(MessageFormat.format(CLIText.get().jgitVersion, version));
+ try {
+ outw.println(
+ MessageFormat.format(CLIText.get().jgitVersion, version));
+ } catch (IOException e) {
+ throw die(e.getMessage(), e);
+ }
}
@Override
@@ -94,14 +68,9 @@ class Version extends TextBuiltin {
}
private static String getBundleVersion(URL url) {
- try {
- InputStream is = url.openStream();
- try {
- Manifest manifest = new Manifest(is);
- return manifest.getMainAttributes().getValue("Bundle-Version"); //$NON-NLS-1$
- } finally {
- is.close();
- }
+ try (InputStream is = url.openStream()) {
+ Manifest manifest = new Manifest(is);
+ return manifest.getMainAttributes().getValue("Bundle-Version"); //$NON-NLS-1$
} catch (IOException e) {
// do nothing - will return null
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java
new file mode 100644
index 0000000000..b7a7ec2feb
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/BenchmarkReftable.java
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2017, Google Inc. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.pgm.debug;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.eclipse.jgit.lib.Constants.HEAD;
+import static org.eclipse.jgit.lib.Constants.MASTER;
+import static org.eclipse.jgit.lib.Constants.R_HEADS;
+import static org.eclipse.jgit.lib.Ref.Storage.NEW;
+import static org.eclipse.jgit.lib.Ref.Storage.PACKED;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.eclipse.jgit.internal.storage.file.FileReftableStack;
+import org.eclipse.jgit.internal.storage.io.BlockSource;
+import org.eclipse.jgit.internal.storage.reftable.RefCursor;
+import org.eclipse.jgit.internal.storage.reftable.ReftableReader;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdRef;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.SymbolicRef;
+import org.eclipse.jgit.pgm.Command;
+import org.eclipse.jgit.pgm.TextBuiltin;
+import org.eclipse.jgit.util.RefList;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+
+@Command
+class BenchmarkReftable extends TextBuiltin {
+ enum Test {
+ SCAN,
+ SEEK_COLD, SEEK_HOT,
+ BY_ID_COLD, BY_ID_HOT,
+ WRITE_STACK,
+ GET_REFS_EXCLUDING_REF
+ }
+
+ @Option(name = "--tries")
+ private int tries = 10;
+
+ @Option(name = "--test")
+ private Test test = Test.SCAN;
+
+ @Option(name = "--ref")
+ private String ref;
+
+ @Option(name = "--object-id")
+ private String objectId;
+
+ @Argument(index = 0)
+ private String lsRemotePath;
+
+ @Argument(index = 1)
+ private String reftablePath;
+
+ @Override
+ protected void run() throws Exception {
+ switch (test) {
+ case SCAN:
+ scan();
+ break;
+
+ case SEEK_COLD:
+ seekCold(ref);
+ break;
+ case SEEK_HOT:
+ seekHot(ref);
+ break;
+
+ case BY_ID_COLD:
+ byIdCold(ObjectId.fromString(objectId));
+ break;
+ case BY_ID_HOT:
+ byIdHot(ObjectId.fromString(objectId));
+ break;
+ case WRITE_STACK:
+ writeStack();
+ break;
+ case GET_REFS_EXCLUDING_REF :
+ getRefsExcludingWithSeekPast(ref);
+ getRefsExcludingWithFilter(ref);
+ break;
+ }
+ }
+
+ private void printf(String fmt, Object... args) throws IOException {
+ errw.println(String.format(fmt, args));
+ }
+
+ @SuppressWarnings({ "nls", "boxing" })
+ private void writeStack() throws Exception {
+ File dir = new File(reftablePath);
+
+ dir.mkdirs();
+
+ long start = System.currentTimeMillis();
+ try (FileReftableStack stack = new FileReftableStack(dir, null,
+ () -> new Config())) {
+
+ List<Ref> refs = readLsRemote().asList();
+ for (Ref r : refs) {
+ final long j = stack.getMergedReftable().maxUpdateIndex() + 1;
+ if (!stack.addReftable(w -> {
+ w.setMaxUpdateIndex(j).setMinUpdateIndex(j).begin()
+ .writeRef(r);
+ })) {
+ throw new IOException("should succeed");
+ }
+ }
+ long dt = System.currentTimeMillis() - start;
+ printf("%12s %10d ms avg %6d us/write", "reftable", dt,
+ (dt * 1000) / refs.size());
+ }
+ }
+
+ @SuppressWarnings({ "nls", "boxing" })
+ private void scan() throws Exception {
+ long start, tot;
+
+ start = System.currentTimeMillis();
+ for (int i = 0; i < tries; i++) {
+ readLsRemote();
+ }
+ tot = System.currentTimeMillis() - start;
+ printf("%12s %10d ms %6d ms/run", "packed-refs", tot, tot / tries);
+
+ start = System.currentTimeMillis();
+ for (int i = 0; i < tries; i++) {
+ try (FileInputStream in = new FileInputStream(reftablePath);
+ BlockSource src = BlockSource.from(in);
+ ReftableReader reader = new ReftableReader(src)) {
+ try (RefCursor rc = reader.allRefs()) {
+ while (rc.next()) {
+ rc.getRef();
+ }
+ }
+ }
+ }
+ tot = System.currentTimeMillis() - start;
+ printf("%12s %10d ms %6d ms/run", "reftable", tot, tot / tries);
+ }
+
+ private RefList<Ref> readLsRemote()
+ throws IOException, FileNotFoundException {
+ RefList.Builder<Ref> list = new RefList.Builder<>();
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(
+ new FileInputStream(lsRemotePath), UTF_8))) {
+ Ref last = null;
+ String line;
+ while ((line = br.readLine()) != null) {
+ ObjectId id = ObjectId.fromString(line.substring(0, 40));
+ String name = line.substring(41, line.length());
+ if (last != null && name.endsWith("^{}")) { //$NON-NLS-1$
+ last = new ObjectIdRef.PeeledTag(PACKED, last.getName(),
+ last.getObjectId(), id);
+ list.set(list.size() - 1, last);
+ continue;
+ }
+
+ if (name.equals(HEAD)) {
+ last = new SymbolicRef(name, new ObjectIdRef.Unpeeled(NEW,
+ R_HEADS + MASTER, null));
+ } else {
+ last = new ObjectIdRef.PeeledNonTag(PACKED, name, id);
+ }
+ list.add(last);
+ }
+ }
+ list.sort();
+ return list.toRefList();
+ }
+
+ @SuppressWarnings({ "nls", "boxing" })
+ private void seekCold(String refName) throws Exception {
+ long start, tot;
+
+ int lsTries = Math.min(tries, 64);
+ start = System.nanoTime();
+ for (int i = 0; i < lsTries; i++) {
+ readLsRemote().get(refName);
+ }
+ tot = System.nanoTime() - start;
+ printf("%12s %10d usec %9.1f usec/run %5d runs", "packed-refs",
+ tot / 1000,
+ (((double) tot) / lsTries) / 1000,
+ lsTries);
+
+ start = System.nanoTime();
+ for (int i = 0; i < tries; i++) {
+ try (FileInputStream in = new FileInputStream(reftablePath);
+ BlockSource src = BlockSource.from(in);
+ ReftableReader reader = new ReftableReader(src)) {
+ try (RefCursor rc = reader.seekRef(refName)) {
+ while (rc.next()) {
+ rc.getRef();
+ }
+ }
+ }
+ }
+ tot = System.nanoTime() - start;
+ printf("%12s %10d usec %9.1f usec/run %5d runs", "reftable",
+ tot / 1000,
+ (((double) tot) / tries) / 1000,
+ tries);
+ }
+
+ @SuppressWarnings({ "nls", "boxing" })
+ private void seekHot(String refName) throws Exception {
+ long start, tot;
+
+ int lsTries = Math.min(tries, 64);
+ start = System.nanoTime();
+ RefList<Ref> lsRemote = readLsRemote();
+ for (int i = 0; i < lsTries; i++) {
+ lsRemote.get(refName);
+ }
+ tot = System.nanoTime() - start;
+ printf("%12s %10d usec %9.1f usec/run %5d runs", "packed-refs",
+ tot / 1000, (((double) tot) / lsTries) / 1000, lsTries);
+
+ start = System.nanoTime();
+ try (FileInputStream in = new FileInputStream(reftablePath);
+ BlockSource src = BlockSource.from(in);
+ ReftableReader reader = new ReftableReader(src)) {
+ for (int i = 0; i < tries; i++) {
+ try (RefCursor rc = reader.seekRef(refName)) {
+ while (rc.next()) {
+ rc.getRef();
+ }
+ }
+ }
+ }
+ tot = System.nanoTime() - start;
+ printf("%12s %10d usec %9.1f usec/run %5d runs", "reftable",
+ tot / 1000, (((double) tot) / tries) / 1000, tries);
+ }
+
+ @SuppressWarnings({ "nls", "boxing" })
+ private void byIdCold(ObjectId id) throws Exception {
+ long start, tot;
+
+ int lsTries = Math.min(tries, 64);
+ start = System.nanoTime();
+ for (int i = 0; i < lsTries; i++) {
+ for (Ref r : readLsRemote()) {
+ if (id.equals(r.getObjectId())) {
+ continue;
+ }
+ }
+ }
+ tot = System.nanoTime() - start;
+ printf("%12s %10d usec %9.1f usec/run %5d runs", "packed-refs",
+ tot / 1000, (((double) tot) / lsTries) / 1000, lsTries);
+
+ start = System.nanoTime();
+ for (int i = 0; i < tries; i++) {
+ try (FileInputStream in = new FileInputStream(reftablePath);
+ BlockSource src = BlockSource.from(in);
+ ReftableReader reader = new ReftableReader(src)) {
+ try (RefCursor rc = reader.byObjectId(id)) {
+ while (rc.next()) {
+ rc.getRef();
+ }
+ }
+ }
+ }
+ tot = System.nanoTime() - start;
+ printf("%12s %10d usec %9.1f usec/run %5d runs", "reftable",
+ tot / 1000, (((double) tot) / tries) / 1000, tries);
+ }
+
+ @SuppressWarnings({ "nls", "boxing" })
+ private void byIdHot(ObjectId id) throws Exception {
+ long start, tot;
+
+ int lsTries = Math.min(tries, 64);
+ start = System.nanoTime();
+ RefList<Ref> lsRemote = readLsRemote();
+ for (int i = 0; i < lsTries; i++) {
+ for (Ref r : lsRemote) {
+ if (id.equals(r.getObjectId())) {
+ continue;
+ }
+ }
+ }
+ tot = System.nanoTime() - start;
+ printf("%12s %10d usec %9.1f usec/run %5d runs", "packed-refs",
+ tot / 1000, (((double) tot) / lsTries) / 1000, lsTries);
+
+ start = System.nanoTime();
+ try (FileInputStream in = new FileInputStream(reftablePath);
+ BlockSource src = BlockSource.from(in);
+ ReftableReader reader = new ReftableReader(src)) {
+ for (int i = 0; i < tries; i++) {
+ try (RefCursor rc = reader.byObjectId(id)) {
+ while (rc.next()) {
+ rc.getRef();
+ }
+ }
+ }
+ }
+ tot = System.nanoTime() - start;
+ printf("%12s %10d usec %9.1f usec/run %5d runs", "reftable",
+ tot / 1000, (((double) tot) / tries) / 1000, tries);
+ }
+
+ @SuppressWarnings({"nls", "boxing"})
+ private void getRefsExcludingWithFilter(String prefix) throws Exception {
+ long startTime = System.nanoTime();
+ List<Ref> allRefs = new ArrayList<>();
+ try (FileInputStream in = new FileInputStream(reftablePath);
+ BlockSource src = BlockSource.from(in);
+ ReftableReader reader = new ReftableReader(src)) {
+ try (RefCursor rc = reader.allRefs()) {
+ while (rc.next()) {
+ allRefs.add(rc.getRef());
+ }
+ }
+ }
+ int total = allRefs.size();
+ allRefs = allRefs.stream().filter(r -> r.getName().startsWith(prefix)).collect(Collectors.toList());
+ int notStartWithPrefix = allRefs.size();
+ int startWithPrefix = total - notStartWithPrefix;
+ long totalTime = System.nanoTime() - startTime;
+ printf("total time the action took using filter: %10d usec", totalTime / 1000);
+ printf("number of refs that start with prefix: %d", startWithPrefix);
+ printf("number of refs that don't start with prefix: %d", notStartWithPrefix);
+ }
+
+ @SuppressWarnings({"nls", "boxing"})
+ private void getRefsExcludingWithSeekPast(String prefix) throws Exception {
+ long start = System.nanoTime();
+ try (FileInputStream in = new FileInputStream(reftablePath);
+ BlockSource src = BlockSource.from(in);
+ ReftableReader reader = new ReftableReader(src)) {
+ try (RefCursor rc = reader.allRefs()) {
+ while (rc.next()) {
+ if (rc.getRef().getName().startsWith(prefix)) {
+ break;
+ }
+ }
+ rc.seekPastPrefix(prefix);
+ while (rc.next()) {
+ rc.getRef();
+ }
+ }
+ }
+ long tot = System.nanoTime() - start;
+ printf("total time the action took using seek: %10d usec", tot / 1000);
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java
index 24d717dfd8..2bdca24336 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java
@@ -1,58 +1,21 @@
/*
- * Copyright (C) 2010, Google Inc.
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2010, Google Inc. and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.debug;
-import static java.lang.Integer.valueOf;
-import static java.lang.Long.valueOf;
-
import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Comparator;
import java.util.List;
import org.eclipse.jgit.diff.DiffAlgorithm;
@@ -84,12 +47,14 @@ import org.kohsuke.args4j.Option;
class DiffAlgorithms extends TextBuiltin {
final Algorithm myers = new Algorithm() {
+ @Override
DiffAlgorithm create() {
return MyersDiff.INSTANCE;
}
};
final Algorithm histogram = new Algorithm() {
+ @Override
DiffAlgorithm create() {
HistogramDiff d = new HistogramDiff();
d.setFallbackAlgorithm(null);
@@ -98,6 +63,7 @@ class DiffAlgorithms extends TextBuiltin {
};
final Algorithm histogram_myers = new Algorithm() {
+ @Override
DiffAlgorithm create() {
HistogramDiff d = new HistogramDiff();
d.setFallbackAlgorithm(MyersDiff.INSTANCE);
@@ -111,14 +77,14 @@ class DiffAlgorithms extends TextBuiltin {
//
//
- @Option(name = "--algorithm", multiValued = true, metaVar = "NAME", usage = "Enable algorithm(s)")
- List<String> algorithms = new ArrayList<String>();
+ @Option(name = "--algorithm", metaVar = "NAME", usage = "Enable algorithm(s)")
+ List<String> algorithms = new ArrayList<>();
@Option(name = "--text-limit", metaVar = "LIMIT", usage = "Maximum size in KiB to scan per file revision")
int textLimit = 15 * 1024; // 15 MiB as later we do * 1024.
- @Option(name = "--repository", aliases = { "-r" }, multiValued = true, metaVar = "GIT_DIR", usage = "Repository to scan")
- List<File> gitDirs = new ArrayList<File>();
+ @Option(name = "--repository", aliases = { "-r" }, metaVar = "GIT_DIR", usage = "Repository to scan")
+ List<File> gitDirs = new ArrayList<>();
@Option(name = "--count", metaVar = "LIMIT", usage = "Number of file revisions to be compared")
int count = 0; // unlimited
@@ -136,7 +102,7 @@ class DiffAlgorithms extends TextBuiltin {
protected void run() throws Exception {
mxBean = ManagementFactory.getThreadMXBean();
if (!mxBean.isCurrentThreadCpuTimeSupported())
- throw die("Current thread CPU time not supported on this JRE");
+ throw die("Current thread CPU time not supported on this JRE"); //$NON-NLS-1$
if (gitDirs.isEmpty()) {
RepositoryBuilder rb = new RepositoryBuilder() //
@@ -155,16 +121,13 @@ class DiffAlgorithms extends TextBuiltin {
else
rb.findGitDir(dir);
- Repository db = rb.build();
- try {
- run(db);
- } finally {
- db.close();
+ try (Repository repo = rb.build()) {
+ run(repo);
}
}
}
- private void run(Repository db) throws Exception {
+ private void run(Repository repo) throws Exception {
List<Test> all = init();
long files = 0;
@@ -173,14 +136,14 @@ class DiffAlgorithms extends TextBuiltin {
int maxN = 0;
AbbreviatedObjectId startId;
- try (ObjectReader or = db.newObjectReader()) {
+ try (ObjectReader or = repo.newObjectReader();
+ RevWalk rw = new RevWalk(or)) {
final MutableObjectId id = new MutableObjectId();
- RevWalk rw = new RevWalk(or);
TreeWalk tw = new TreeWalk(or);
tw.setFilter(TreeFilter.ANY_DIFF);
tw.setRecursive(true);
- ObjectId start = db.resolve(Constants.HEAD);
+ ObjectId start = repo.resolve(Constants.HEAD);
startId = or.abbreviate(start);
rw.markStart(rw.parseCommit(start));
for (;;) {
@@ -205,7 +168,7 @@ class DiffAlgorithms extends TextBuiltin {
} catch (LargeObjectException tooBig) {
continue;
}
- if (RawText.isBinary(raw0))
+ if (RawText.isBinary(raw0, raw0.length, true))
continue;
byte[] raw1;
@@ -215,7 +178,7 @@ class DiffAlgorithms extends TextBuiltin {
} catch (LargeObjectException tooBig) {
continue;
}
- if (RawText.isBinary(raw1))
+ if (RawText.isBinary(raw1, raw1.length, true))
continue;
RawText txt0 = new RawText(raw0);
@@ -233,41 +196,41 @@ class DiffAlgorithms extends TextBuiltin {
}
}
- Collections.sort(all, new Comparator<Test>() {
- public int compare(Test a, Test b) {
- int cmp = Long.signum(a.runningTimeNanos - b.runningTimeNanos);
- if (cmp == 0)
- cmp = a.algorithm.name.compareTo(b.algorithm.name);
- return cmp;
+ Collections.sort(all, (Test a, Test b) -> {
+ int result = Long.signum(a.runningTimeNanos - b.runningTimeNanos);
+ if (result == 0) {
+ result = a.algorithm.name.compareTo(b.algorithm.name);
}
+ return result;
});
- if (db.getDirectory() != null) {
- String name = db.getDirectory().getName();
- File parent = db.getDirectory().getParentFile();
+ File directory = repo.getDirectory();
+ if (directory != null) {
+ String name = directory.getName();
+ File parent = directory.getParentFile();
if (name.equals(Constants.DOT_GIT) && parent != null)
name = parent.getName();
- outw.println(name + ": start at " + startId.name());
+ outw.println(name + ": start at " + startId.name()); //$NON-NLS-1$
}
- outw.format(" %12d files, %8d commits\n", valueOf(files),
- valueOf(commits));
- outw.format(" N=%10d min lines, %8d max lines\n", valueOf(minN),
- valueOf(maxN));
+ outw.format(" %12d files, %8d commits\n", Long.valueOf(files), //$NON-NLS-1$
+ Integer.valueOf(commits));
+ outw.format(" N=%10d min lines, %8d max lines\n", //$NON-NLS-1$
+ Integer.valueOf(minN), Integer.valueOf(maxN));
- outw.format("%-25s %12s ( %12s %12s )\n", //
- "Algorithm", "Time(ns)", "Time(ns) on", "Time(ns) on");
- outw.format("%-25s %12s ( %12s %12s )\n", //
- "", "", "N=" + minN, "N=" + maxN);
+ outw.format("%-25s %12s ( %12s %12s )\n", //$NON-NLS-1$
+ "Algorithm", "Time(ns)", "Time(ns) on", "Time(ns) on"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ outw.format("%-25s %12s ( %12s %12s )\n", //$NON-NLS-1$
+ "", "", "N=" + minN, "N=" + maxN); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
outw.println("-----------------------------------------------------" //$NON-NLS-1$
+ "----------------"); //$NON-NLS-1$
for (Test test : all) {
outw.format("%-25s %12d ( %12d %12d )", // //$NON-NLS-1$
test.algorithm.name, //
- valueOf(test.runningTimeNanos), //
- valueOf(test.minN.runningTimeNanos), //
- valueOf(test.maxN.runningTimeNanos));
+ Long.valueOf(test.runningTimeNanos), //
+ Long.valueOf(test.minN.runningTimeNanos), //
+ Long.valueOf(test.maxN.runningTimeNanos));
outw.println();
}
outw.println();
@@ -318,7 +281,7 @@ class DiffAlgorithms extends TextBuiltin {
}
private List<Test> init() {
- List<Test> all = new ArrayList<Test>();
+ List<Test> all = new ArrayList<>();
try {
for (Field f : DiffAlgorithms.class.getDeclaredFields()) {
@@ -333,12 +296,9 @@ class DiffAlgorithms extends TextBuiltin {
}
}
}
- } catch (IllegalArgumentException e) {
- throw die("Cannot determine names", e);
- } catch (IllegalAccessException e) {
- throw die("Cannot determine names", e);
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ throw die("Cannot determine names", e); //$NON-NLS-1$
}
-
return all;
}
@@ -352,7 +312,7 @@ class DiffAlgorithms extends TextBuiltin {
return false;
}
- private static abstract class Algorithm {
+ private abstract static class Algorithm {
String name;
abstract DiffAlgorithm create();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java
new file mode 100644
index 0000000000..757c435722
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/LfsStore.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2015, Sasa Zivkov <sasa.zivkov@sap.com> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.pgm.debug;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.MessageFormat;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.handler.ContextHandlerCollection;
+import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
+import org.eclipse.jetty.ee10.servlet.ServletHolder;
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lfs.server.LargeFileRepository;
+import org.eclipse.jgit.lfs.server.LfsProtocolServlet;
+import org.eclipse.jgit.lfs.server.fs.FileLfsRepository;
+import org.eclipse.jgit.lfs.server.fs.FileLfsServlet;
+import org.eclipse.jgit.lfs.server.s3.S3Config;
+import org.eclipse.jgit.lfs.server.s3.S3Repository;
+import org.eclipse.jgit.pgm.Command;
+import org.eclipse.jgit.pgm.TextBuiltin;
+import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.util.FS;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+
+@Command(common = true, usage = "usage_runLfsStore")
+class LfsStore extends TextBuiltin {
+
+ /**
+ * Tiny web application server for testing
+ */
+ static class AppServer {
+
+ private final Server server;
+
+ private final ServerConnector connector;
+
+ private final ContextHandlerCollection contexts;
+
+ private URI uri;
+
+ AppServer(int port) {
+ server = new Server();
+
+ HttpConfiguration http_config = new HttpConfiguration();
+ http_config.setOutputBufferSize(32768);
+
+ connector = new ServerConnector(server,
+ new HttpConnectionFactory(http_config));
+ connector.setPort(port);
+ try {
+ String host = InetAddress.getByName("localhost") //$NON-NLS-1$
+ .getHostAddress();
+ connector.setHost(host);
+ if (host.contains(":") && !host.startsWith("[")) //$NON-NLS-1$ //$NON-NLS-2$
+ host = "[" + host + "]"; //$NON-NLS-1$//$NON-NLS-2$
+ uri = new URI("http://" + host + ":" + port); //$NON-NLS-1$ //$NON-NLS-2$
+ } catch (UnknownHostException e) {
+ throw new RuntimeException("Cannot find localhost", e); //$NON-NLS-1$
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Unexpected URI error on " + uri, e); //$NON-NLS-1$
+ }
+
+ contexts = new ContextHandlerCollection();
+ server.setHandler(contexts);
+ server.setConnectors(new Connector[] { connector });
+ }
+
+ /**
+ * Create a new servlet context within the server.
+ * <p>
+ * This method should be invoked before the server is started, once for
+ * each context the caller wants to register.
+ *
+ * @param path
+ * path of the context; use "/" for the root context if
+ * binding to the root is desired.
+ * @return the context to add servlets into.
+ */
+ ServletContextHandler addContext(String path) {
+ assertNotRunning();
+ if ("".equals(path)) //$NON-NLS-1$
+ path = "/"; //$NON-NLS-1$
+
+ ServletContextHandler ctx = new ServletContextHandler();
+ ctx.setContextPath(path);
+ contexts.addHandler(ctx);
+
+ return ctx;
+ }
+
+ void start() throws Exception {
+ server.start();
+ }
+
+ void stop() throws Exception {
+ server.stop();
+ }
+
+ URI getURI() {
+ return uri;
+ }
+
+ private void assertNotRunning() {
+ if (server.isRunning()) {
+ throw new IllegalStateException("server is running"); //$NON-NLS-1$
+ }
+ }
+ }
+
+ private enum StoreType {
+ FS, S3;
+ }
+
+ private enum StorageClass {
+ REDUCED_REDUNDANCY, STANDARD
+ }
+
+ private static final String OBJECTS = "objects/"; //$NON-NLS-1$
+
+ private static final String STORE_PATH = "/" + OBJECTS + "*"; //$NON-NLS-1$//$NON-NLS-2$
+
+ private static final String PROTOCOL_PATH = "/lfs/objects/batch"; //$NON-NLS-1$
+
+ @Option(name = "--port", aliases = {"-p" },
+ metaVar = "metaVar_port", usage = "usage_LFSPort")
+ int port;
+
+ @Option(name = "--store", metaVar = "metaVar_lfsStorage", usage = "usage_LFSRunStore")
+ StoreType storeType;
+
+ @Option(name = "--store-url", aliases = {"-u" }, metaVar = "metaVar_url",
+ usage = "usage_LFSStoreUrl")
+ String storeUrl;
+
+ @Option(name = "--region", aliases = {"-r" },
+ metaVar = "metaVar_s3Region", usage = "usage_S3Region")
+ String region; // $NON-NLS-1$
+
+ @Option(name = "--bucket", aliases = {"-b" },
+ metaVar = "metaVar_s3Bucket", usage = "usage_S3Bucket")
+ String bucket; // $NON-NLS-1$
+
+ @Option(name = "--storage-class", aliases = {"-c" },
+ metaVar = "metaVar_s3StorageClass", usage = "usage_S3StorageClass")
+ StorageClass storageClass = StorageClass.REDUCED_REDUNDANCY;
+
+ @Option(name = "--expire", aliases = {"-e" },
+ metaVar = "metaVar_seconds", usage = "usage_S3Expiration")
+ int expirationSeconds = 600;
+
+ @Option(name = "--no-ssl-verify", usage = "usage_S3NoSslVerify")
+ boolean disableSslVerify = false;
+
+ @Argument(required = false, metaVar = "metaVar_directory", usage = "usage_LFSDirectory")
+ String directory;
+
+ String protocolUrl;
+
+ String accessKey;
+
+ String secretKey;
+
+ @Override
+ protected boolean requiresRepository() {
+ return false;
+ }
+
+ @Override
+ protected void run() throws Exception {
+ AppServer server = new AppServer(port);
+ URI baseURI = server.getURI();
+ ServletContextHandler app = server.addContext("/"); //$NON-NLS-1$
+
+ final LargeFileRepository repository;
+ switch (storeType) {
+ case FS:
+ Path dir = Paths.get(directory);
+ FileLfsRepository fsRepo = new FileLfsRepository(
+ getStoreUrl(baseURI), dir);
+ FileLfsServlet content = new FileLfsServlet(fsRepo, 30000);
+ app.addServlet(new ServletHolder(content), STORE_PATH);
+ repository = fsRepo;
+ break;
+
+ case S3:
+ readAWSKeys();
+ checkOptions();
+ S3Config config = new S3Config(region, bucket,
+ storageClass.toString(), accessKey, secretKey,
+ expirationSeconds, disableSslVerify);
+ repository = new S3Repository(config);
+ break;
+ default:
+ throw new IllegalArgumentException(MessageFormat
+ .format(CLIText.get().lfsUnknownStoreType, storeType));
+ }
+
+ LfsProtocolServlet protocol = new LfsProtocolServlet() {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected LargeFileRepository getLargeFileRepository(
+ LfsRequest request, String path, String auth) {
+ return repository;
+ }
+ };
+ app.addServlet(new ServletHolder(protocol), PROTOCOL_PATH);
+
+ server.start();
+
+ outw.println(MessageFormat.format(CLIText.get().lfsProtocolUrl,
+ getProtocolUrl(baseURI)));
+ if (storeType == StoreType.FS) {
+ outw.println(MessageFormat.format(CLIText.get().lfsStoreDirectory,
+ directory));
+ outw.println(MessageFormat.format(CLIText.get().lfsStoreUrl,
+ getStoreUrl(baseURI)));
+ }
+ }
+
+ private void checkOptions() {
+ if (bucket == null || bucket.length() == 0) {
+ throw die(MessageFormat.format(CLIText.get().s3InvalidBucket,
+ bucket));
+ }
+ }
+
+ private void readAWSKeys() throws IOException, ConfigInvalidException {
+ String credentialsPath = System.getProperty("user.home") //$NON-NLS-1$
+ + "/.aws/credentials"; //$NON-NLS-1$
+ FileBasedConfig c = new FileBasedConfig(new File(credentialsPath),
+ FS.DETECTED);
+ c.load();
+ accessKey = c.getString("default", null, "accessKey"); //$NON-NLS-1$//$NON-NLS-2$
+ secretKey = c.getString("default", null, "secretKey"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (accessKey == null || accessKey.isEmpty()) {
+ throw die(MessageFormat.format(CLIText.get().lfsNoAccessKey,
+ credentialsPath));
+ }
+ if (secretKey == null || secretKey.isEmpty()) {
+ throw die(MessageFormat.format(CLIText.get().lfsNoSecretKey,
+ credentialsPath));
+ }
+ }
+
+ private String getStoreUrl(URI baseURI) {
+ if (storeUrl == null) {
+ if (storeType == StoreType.FS) {
+ storeUrl = baseURI + "/" + OBJECTS; //$NON-NLS-1$
+ } else {
+ die("Local store not running and no --store-url specified"); //$NON-NLS-1$
+ }
+ }
+ return storeUrl;
+ }
+
+ private String getProtocolUrl(URI baseURI) {
+ if (protocolUrl == null) {
+ protocolUrl = baseURI + PROTOCOL_PATH;
+ }
+ return protocolUrl;
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/MakeCacheTree.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/MakeCacheTree.java
index d3a0a3e14e..eec10c774f 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/MakeCacheTree.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/MakeCacheTree.java
@@ -1,51 +1,16 @@
/*
* Copyright (C) 2008, Google Inc.
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.debug;
-import static java.lang.Integer.valueOf;
-
import java.io.IOException;
import java.text.MessageFormat;
@@ -64,10 +29,10 @@ class MakeCacheTree extends TextBuiltin {
show(tree);
}
- private void show(final DirCacheTree tree) throws IOException {
+ private void show(DirCacheTree tree) throws IOException {
outw.println(MessageFormat.format(CLIText.get().cacheTreePathInfo,
- tree.getPathString(), valueOf(tree.getEntrySpan()),
- valueOf(tree.getChildCount())));
+ tree.getPathString(), Integer.valueOf(tree.getEntrySpan()),
+ Integer.valueOf(tree.getChildCount())));
for (int i = 0; i < tree.getChildCount(); i++)
show(tree.getChild(i));
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadChangedPathFilter.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadChangedPathFilter.java
new file mode 100644
index 0000000000..1414165e54
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadChangedPathFilter.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2023, Google LLC
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.pgm.debug;
+
+import java.io.FileInputStream;
+import java.util.HashSet;
+
+import org.eclipse.jgit.pgm.Command;
+import org.eclipse.jgit.pgm.TextBuiltin;
+import org.eclipse.jgit.util.NB;
+import org.kohsuke.args4j.Argument;
+
+/**
+ * Prints the contents of the BDAT chunk from commit-graph file.
+ * <p>
+ * This is a debugging tool for changed path filter development.
+ */
+@Command
+class ReadChangedPathFilter extends TextBuiltin {
+
+ static final int CHUNK_ID_OID_FANOUT = 0x4f494446; /* "OIDF" */
+
+ static final int CHUNK_ID_BLOOM_FILTER_INDEX = 0x42494458; /* "BIDX" */
+
+ static final int CHUNK_ID_BLOOM_FILTER_DATA = 0x42444154; /* "BDAT" */
+
+ @Argument(index = 0)
+ private String input;
+
+ static HashSet<String> changedPathStrings(byte[] data) {
+ int oidf_offset = -1;
+ int bidx_offset = -1;
+ int bdat_offset = -1;
+ for (int i = 8; i < data.length - 4; i += 12) {
+ switch (NB.decodeInt32(data, i)) {
+ case CHUNK_ID_OID_FANOUT:
+ oidf_offset = (int) NB.decodeInt64(data, i + 4);
+ break;
+ case CHUNK_ID_BLOOM_FILTER_INDEX:
+ bidx_offset = (int) NB.decodeInt64(data, i + 4);
+ break;
+ case CHUNK_ID_BLOOM_FILTER_DATA:
+ bdat_offset = (int) NB.decodeInt64(data, i + 4);
+ break;
+ }
+ }
+ bdat_offset += 12; // skip version, hash count, bits per entry
+ int commit_count = NB.decodeInt32(data, oidf_offset + 255 * 4);
+ int[] changed_path_length_cumuls = new int[commit_count];
+ for (int i = 0; i < commit_count; i++) {
+ changed_path_length_cumuls[i] = NB.decodeInt32(data,
+ bidx_offset + i * 4);
+ }
+ HashSet<String> changed_paths = new HashSet<>();
+ for (int i = 0; i < commit_count; i++) {
+ int prior_cumul = i == 0 ? 0 : changed_path_length_cumuls[i - 1];
+ String changed_path = ""; //$NON-NLS-1$
+ for (int j = prior_cumul; j < changed_path_length_cumuls[i]; j++) {
+ changed_path += data[bdat_offset + j] + ","; //$NON-NLS-1$
+ }
+ changed_paths.add(changed_path);
+ }
+ return changed_paths;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void run() throws Exception {
+ try (FileInputStream in = new FileInputStream(input)
+ ) {
+ byte[] data = in.readAllBytes();
+ outw.println(changedPathStrings(data).toString());
+ }
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadDirCache.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadDirCache.java
index 07bfc4b5fe..3d20e01d3c 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadDirCache.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadDirCache.java
@@ -1,51 +1,16 @@
/*
* Copyright (C) 2008, Google Inc.
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.debug;
-import static java.lang.Long.valueOf;
-
import java.text.MessageFormat;
import org.eclipse.jgit.pgm.Command;
@@ -63,6 +28,6 @@ class ReadDirCache extends TextBuiltin {
final long end = System.currentTimeMillis();
outw.print(" "); //$NON-NLS-1$
outw.println(MessageFormat.format(CLIText.get().averageMSPerRead,
- valueOf((end - start) / cnt)));
+ Long.valueOf((end - start) / cnt)));
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadReftable.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadReftable.java
new file mode 100644
index 0000000000..a2443d315f
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ReadReftable.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017, Google Inc. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.pgm.debug;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import org.eclipse.jgit.internal.storage.io.BlockSource;
+import org.eclipse.jgit.internal.storage.reftable.RefCursor;
+import org.eclipse.jgit.internal.storage.reftable.ReftableReader;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.pgm.Command;
+import org.eclipse.jgit.pgm.TextBuiltin;
+import org.kohsuke.args4j.Argument;
+
+@Command
+class ReadReftable extends TextBuiltin {
+ @Argument(index = 0)
+ private String input;
+
+ @Argument(index = 1, required = false)
+ private String ref;
+
+ @Override
+ protected void run() throws Exception {
+ try (FileInputStream in = new FileInputStream(input);
+ BlockSource src = BlockSource.from(in);
+ ReftableReader reader = new ReftableReader(src)) {
+ try (RefCursor rc = ref != null
+ ? reader.seekRefsWithPrefix(ref)
+ : reader.allRefs()) {
+ while (rc.next()) {
+ write(rc.getRef());
+ }
+ }
+ }
+ }
+
+ private void write(Ref r) throws IOException {
+ if (r.isSymbolic()) {
+ outw.println(r.getTarget().getName() + '\t' + r.getName());
+ return;
+ }
+
+ ObjectId id1 = r.getObjectId();
+ if (id1 != null) {
+ outw.println(id1.name() + '\t' + r.getName());
+ }
+
+ ObjectId id2 = r.getPeeledObjectId();
+ if (id2 != null) {
+ outw.println('^' + id2.name());
+ }
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java
index 494055a265..22d9e3440a 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/RebuildCommitGraph.java
@@ -1,49 +1,16 @@
/*
- * Copyright (C) 2009-2010, Google Inc.
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2009-2010, Google Inc. and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.debug;
-import static org.eclipse.jgit.lib.RefDatabase.ALL;
+import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.BufferedReader;
import java.io.File;
@@ -51,8 +18,8 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.MessageFormat;
+import java.time.Instant;
import java.util.ArrayList;
-import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
@@ -112,14 +79,17 @@ class RebuildCommitGraph extends TextBuiltin {
private final ProgressMonitor pm = new TextProgressMonitor(errw);
- private Map<ObjectId, ObjectId> rewrites = new HashMap<ObjectId, ObjectId>();
+ private Map<ObjectId, ObjectId> rewrites = new HashMap<>();
@Override
protected void run() throws Exception {
- if (!really && !db.getRefDatabase().getRefs(ALL).isEmpty()) {
+ if (!really && db.getRefDatabase().hasRefs()) {
+ File directory = db.getDirectory();
+ String absolutePath = directory == null ? "null" //$NON-NLS-1$
+ : directory.getAbsolutePath();
errw.println(
MessageFormat.format(CLIText.get().fatalThisProgramWillDestroyTheRepository
- , db.getDirectory().getAbsolutePath(), REALLY));
+ , absolutePath, REALLY));
throw die(CLIText.get().needApprovalToDestroyCurrentRepository);
}
if (!refList.isFile())
@@ -134,12 +104,12 @@ class RebuildCommitGraph extends TextBuiltin {
}
private void recreateCommitGraph() throws IOException {
- final Map<ObjectId, ToRewrite> toRewrite = new HashMap<ObjectId, ToRewrite>();
- List<ToRewrite> queue = new ArrayList<ToRewrite>();
+ final Map<ObjectId, ToRewrite> toRewrite = new HashMap<>();
+ List<ToRewrite> queue = new ArrayList<>();
try (RevWalk rw = new RevWalk(db);
final BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream(graph),
- Constants.CHARSET))) {
+ UTF_8))) {
String line;
while ((line = br.readLine()) != null) {
final String[] parts = line.split("[ \t]{1,}"); //$NON-NLS-1$
@@ -164,7 +134,7 @@ class RebuildCommitGraph extends TextBuiltin {
}
}
- pm.beginTask("Rewriting commits", queue.size());
+ pm.beginTask("Rewriting commits", queue.size()); //$NON-NLS-1$
try (ObjectInserter oi = db.newObjectInserter()) {
final ObjectId emptyTree = oi.insert(Constants.OBJ_TREE,
new byte[] {});
@@ -173,7 +143,7 @@ class RebuildCommitGraph extends TextBuiltin {
while (!queue.isEmpty()) {
final ListIterator<ToRewrite> itr = queue
.listIterator(queue.size());
- queue = new ArrayList<ToRewrite>();
+ queue = new ArrayList<>();
REWRITE: while (itr.hasPrevious()) {
final ToRewrite t = itr.previous();
final ObjectId[] newParents = new ObjectId[t.oldParents.length];
@@ -185,9 +155,8 @@ class RebuildCommitGraph extends TextBuiltin {
// rewritten.
queue.add(t);
continue REWRITE;
- } else {
- newParents[k] = p.newId;
}
+ newParents[k] = p.newId;
} else {
// We have the old parent object. Use it.
//
@@ -197,10 +166,11 @@ class RebuildCommitGraph extends TextBuiltin {
final CommitBuilder newc = new CommitBuilder();
newc.setTreeId(emptyTree);
- newc.setAuthor(new PersonIdent(me, new Date(t.commitTime)));
+ newc.setAuthor(new PersonIdent(me,
+ Instant.ofEpochSecond(t.commitTime)));
newc.setCommitter(newc.getAuthor());
newc.setParentIds(newParents);
- newc.setMessage("ORIGINAL " + t.oldId.name() + "\n"); //$NON-NLS-2$
+ newc.setMessage("ORIGINAL " + t.oldId.name() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
t.newId = oi.insert(newc);
rewrites.put(t.oldId, t.newId);
pm.update(1);
@@ -220,7 +190,7 @@ class RebuildCommitGraph extends TextBuiltin {
ObjectId newId;
- ToRewrite(final ObjectId o, final long t, final ObjectId[] p) {
+ ToRewrite(ObjectId o, long t, ObjectId[] p) {
oldId = o;
commitTime = t;
oldParents = p;
@@ -232,7 +202,7 @@ class RebuildCommitGraph extends TextBuiltin {
final ObjectId id = db.resolve(Constants.HEAD);
if (!ObjectId.isId(head) && id != null) {
final LockFile lf;
- lf = new LockFile(new File(db.getDirectory(), Constants.HEAD), db.getFS());
+ lf = new LockFile(new File(db.getDirectory(), Constants.HEAD));
if (!lf.lock())
throw new IOException(MessageFormat.format(CLIText.get().cannotLock, Constants.HEAD));
lf.write(id);
@@ -243,8 +213,7 @@ class RebuildCommitGraph extends TextBuiltin {
private void deleteAllRefs() throws Exception {
final RevWalk rw = new RevWalk(db);
- Map<String, Ref> refs = db.getRefDatabase().getRefs(ALL);
- for (final Ref r : refs.values()) {
+ for (Ref r : db.getRefDatabase().getRefs()) {
if (Constants.HEAD.equals(r.getName()))
continue;
final RefUpdate u = db.updateRef(r.getName());
@@ -257,16 +226,18 @@ class RebuildCommitGraph extends TextBuiltin {
final Map<String, Ref> refs = computeNewRefs();
new RefWriter(refs.values()) {
@Override
- protected void writeFile(final String name, final byte[] content)
+ protected void writeFile(String name, byte[] content)
throws IOException {
final File file = new File(db.getDirectory(), name);
- final LockFile lck = new LockFile(file, db.getFS());
+ final LockFile lck = new LockFile(file);
if (!lck.lock())
throw new ObjectWritingException(MessageFormat.format(CLIText.get().cantWrite, file));
try {
lck.write(content);
} catch (IOException ioe) {
- throw new ObjectWritingException(MessageFormat.format(CLIText.get().cantWrite, file));
+ throw new ObjectWritingException(
+ MessageFormat.format(CLIText.get().cantWrite, file),
+ ioe);
}
if (!lck.commit())
throw new ObjectWritingException(MessageFormat.format(CLIText.get().cantWrite, file));
@@ -275,11 +246,11 @@ class RebuildCommitGraph extends TextBuiltin {
}
private Map<String, Ref> computeNewRefs() throws IOException {
- final Map<String, Ref> refs = new HashMap<String, Ref>();
+ final Map<String, Ref> refs = new HashMap<>();
try (RevWalk rw = new RevWalk(db);
BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream(refList),
- Constants.CHARSET))) {
+ UTF_8))) {
String line;
while ((line = br.readLine()) != null) {
final String[] parts = line.split("[ \t]{1,}"); //$NON-NLS-1$
@@ -297,7 +268,9 @@ class RebuildCommitGraph extends TextBuiltin {
errw.println(MessageFormat.format(CLIText.get().skippingObject, type, name));
continue;
}
- throw new MissingObjectException(id, type);
+ MissingObjectException mue1 = new MissingObjectException(id, type);
+ mue1.initCause(mue);
+ throw mue1;
}
refs.put(name, new ObjectIdRef.Unpeeled(Ref.Storage.PACKED,
name, id));
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCacheTree.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCacheTree.java
index e287425d7b..da16b33701 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCacheTree.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCacheTree.java
@@ -1,51 +1,16 @@
/*
* Copyright (C) 2008, Google Inc.
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.debug;
-import static java.lang.Integer.valueOf;
-
import java.io.IOException;
import java.text.MessageFormat;
@@ -66,10 +31,10 @@ class ShowCacheTree extends TextBuiltin {
show(tree);
}
- private void show(final DirCacheTree tree) throws IOException {
+ private void show(DirCacheTree tree) throws IOException {
outw.println(MessageFormat.format(CLIText.get().cacheTreePathInfo,
- tree.getPathString(), valueOf(tree.getEntrySpan()),
- valueOf(tree.getChildCount())));
+ tree.getPathString(), Integer.valueOf(tree.getEntrySpan()),
+ Integer.valueOf(tree.getChildCount())));
for (int i = 0; i < tree.getChildCount(); i++)
show(tree.getChild(i));
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java
index aa258073b6..e46d703592 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowCommands.java
@@ -1,44 +1,11 @@
/*
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.debug;
@@ -64,11 +31,11 @@ class ShowCommands extends TextBuiltin {
final CommandRef[] list = CommandCatalog.all();
int width = 0;
- for (final CommandRef c : list)
+ for (CommandRef c : list)
width = Math.max(width, c.getName().length());
width += 2;
- for (final CommandRef c : list) {
+ for (CommandRef c : list) {
errw.print(c.isCommon() ? '*' : ' ');
errw.print(' ');
@@ -82,26 +49,29 @@ class ShowCommands extends TextBuiltin {
errw.println();
}
- static enum Format {
- /** */
+ enum Format {
+ /** Get usage */
USAGE {
- void print(ThrowingPrintWriter err, final CommandRef c) throws IOException {
+ @Override
+ void print(ThrowingPrintWriter err, CommandRef c) throws IOException {
String usage = c.getUsage();
if (usage != null && usage.length() > 0)
err.print(CLIText.get().resourceBundle().getString(usage));
}
},
- /** */
+ /** Get implementation class name */
CLASSES {
- void print(ThrowingPrintWriter err, final CommandRef c) throws IOException {
+ @Override
+ void print(ThrowingPrintWriter err, CommandRef c) throws IOException {
err.print(c.getImplementationClassName());
}
},
- /** */
+ /** Get URL of implementation class */
URLS {
- void print(ThrowingPrintWriter err, final CommandRef c) throws IOException {
+ @Override
+ void print(ThrowingPrintWriter err, CommandRef c) throws IOException {
final ClassLoader ldr = c.getImplementationClassLoader();
String cn = c.getImplementationClassName();
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowDirCache.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowDirCache.java
index bb4f73d7d1..96add0f188 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowDirCache.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowDirCache.java
@@ -2,54 +2,21 @@
* Copyright (C) 2008, Google Inc.
* Copyright (C) 2008, Jonas Fonseca <fonseca@diku.dk>
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2011, Matthias Sohn <matthias.sohn@sap.com>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2011, Matthias Sohn <matthias.sohn@sap.com> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.debug;
-import static java.lang.Integer.valueOf;
-
-import java.text.SimpleDateFormat;
-import java.util.Date;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.Locale;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheEntry;
@@ -66,25 +33,27 @@ class ShowDirCache extends TextBuiltin {
@Override
protected void run() throws Exception {
- final SimpleDateFormat fmt;
- fmt = new SimpleDateFormat("yyyy-MM-dd,HH:mm:ss.SSS"); //$NON-NLS-1$
+ final DateTimeFormatter fmt = DateTimeFormatter
+ .ofPattern("yyyy-MM-dd,HH:mm:ss.nnnnnnnnn") //$NON-NLS-1$
+ .withLocale(Locale.getDefault())
+ .withZone(ZoneId.systemDefault());
final DirCache cache = db.readDirCache();
for (int i = 0; i < cache.getEntryCount(); i++) {
final DirCacheEntry ent = cache.getEntry(i);
final FileMode mode = FileMode.fromBits(ent.getRawMode());
final int len = ent.getLength();
- long lastModified = ent.getLastModified();
- final Date mtime = new Date(lastModified);
+ Instant mtime = ent.getLastModifiedInstant();
final int stage = ent.getStage();
outw.print(mode);
- outw.format(" %6d", valueOf(len)); //$NON-NLS-1$
+ outw.format(" %6d", Integer.valueOf(len)); //$NON-NLS-1$
outw.print(' ');
- if (millis)
- outw.print(lastModified);
- else
+ if (millis) {
+ outw.print(mtime.toEpochMilli());
+ } else {
outw.print(fmt.format(mtime));
+ }
outw.print(' ');
outw.print(ent.getObjectId().name());
outw.print(' ');
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowPackDelta.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowPackDelta.java
index 7b5cdbf8f7..80d3503851 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowPackDelta.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/ShowPackDelta.java
@@ -1,44 +1,11 @@
/*
- * Copyright (C) 2010, Google Inc.
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2010, Google Inc. and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.debug;
@@ -64,6 +31,7 @@ import org.eclipse.jgit.pgm.Command;
import org.eclipse.jgit.pgm.TextBuiltin;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.storage.pack.PackConfig;
import org.eclipse.jgit.util.TemporaryBuffer;
import org.kohsuke.args4j.Argument;
@@ -75,7 +43,10 @@ class ShowPackDelta extends TextBuiltin {
@Override
protected void run() throws Exception {
ObjectReader reader = db.newObjectReader();
- RevObject obj = new RevWalk(reader).parseAny(objectId);
+ RevObject obj;
+ try (RevWalk rw = new RevWalk(reader)) {
+ obj = rw.parseAny(objectId);
+ }
byte[] delta = getDelta(reader, obj);
// We're crossing our fingers that this will be a delta. Double
@@ -84,9 +55,9 @@ class ShowPackDelta extends TextBuiltin {
long size = reader.getObjectSize(obj, obj.getType());
try {
if (BinaryDelta.getResultSize(delta) != size)
- throw die("Object " + obj.name() + " is not a delta");
+ throw die("Object " + obj.name() + " is not a delta"); //$NON-NLS-1$ //$NON-NLS-2$
} catch (ArrayIndexOutOfBoundsException bad) {
- throw die("Object " + obj.name() + " is not a delta");
+ throw die("Object " + obj.name() + " is not a delta", bad); //$NON-NLS-1$ //$NON-NLS-2$
}
outw.println(BinaryDelta.format(delta));
@@ -98,10 +69,11 @@ class ShowPackDelta extends TextBuiltin {
ObjectReuseAsIs asis = (ObjectReuseAsIs) reader;
ObjectToPack target = asis.newObjectToPack(obj, obj.getType());
- PackWriter pw = new PackWriter(reader) {
+ PackWriter pw = new PackWriter(new PackConfig(), reader) {
@Override
- public void select(ObjectToPack otp, StoredObjectRepresentation next) {
+ public boolean select(ObjectToPack otp, StoredObjectRepresentation next) {
otp.select(next);
+ return true;
}
};
@@ -121,12 +93,13 @@ class ShowPackDelta extends TextBuiltin {
ptr++;
ptr++;
- @SuppressWarnings("resource" /* java 7 */)
- TemporaryBuffer.Heap raw = new TemporaryBuffer.Heap(bufArray.length);
- InflaterInputStream inf = new InflaterInputStream(
- new ByteArrayInputStream(bufArray, ptr, bufArray.length));
- raw.copy(inf);
- inf.close();
- return raw.toByteArray();
+ try (TemporaryBuffer.Heap raw = new TemporaryBuffer.Heap(
+ bufArray.length);
+ InflaterInputStream inf = new InflaterInputStream(
+ new ByteArrayInputStream(bufArray, ptr,
+ bufArray.length))) {
+ raw.copy(inf);
+ return raw.toByteArray();
+ }
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java
index dcfa8cf00a..2ce1711404 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java
@@ -1,51 +1,15 @@
/*
- * Copyright (C) 2010, Google Inc.
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2010, Google Inc. and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.debug;
-import static java.lang.Integer.valueOf;
-import static java.lang.Long.valueOf;
-
import java.io.File;
import java.lang.reflect.Field;
import java.security.MessageDigest;
@@ -138,9 +102,8 @@ class TextHashFunctions extends TextBuiltin {
Arrays.fill(buf16, (byte) 0);
System.arraycopy(raw, ptr, buf16, 0, end - ptr);
return rabin(buf16, 0);
- } else {
- return rabin(raw, ptr);
}
+ return rabin(raw, ptr);
}
private int rabin(byte[] raw, int ptr) {
@@ -250,17 +213,17 @@ class TextHashFunctions extends TextBuiltin {
//
//
- @Option(name = "--hash", multiValued = true, metaVar = "NAME", usage = "Enable hash function(s)")
- List<String> hashFunctions = new ArrayList<String>();
+ @Option(name = "--hash", metaVar = "NAME", usage = "Enable hash function(s)")
+ List<String> hashFunctions = new ArrayList<>();
- @Option(name = "--fold", multiValued = true, metaVar = "NAME", usage = "Enable fold function(s)")
- List<String> foldFunctions = new ArrayList<String>();
+ @Option(name = "--fold", metaVar = "NAME", usage = "Enable fold function(s)")
+ List<String> foldFunctions = new ArrayList<>();
@Option(name = "--text-limit", metaVar = "LIMIT", usage = "Maximum size in KiB to scan")
int textLimit = 15 * 1024; // 15 MiB as later we do * 1024.
- @Option(name = "--repository", aliases = { "-r" }, multiValued = true, metaVar = "GIT_DIR", usage = "Repository to scan")
- List<File> gitDirs = new ArrayList<File>();
+ @Option(name = "--repository", aliases = { "-r" }, metaVar = "GIT_DIR", usage = "Repository to scan")
+ List<File> gitDirs = new ArrayList<>();
@Override
protected boolean requiresRepository() {
@@ -286,25 +249,22 @@ class TextHashFunctions extends TextBuiltin {
else
rb.findGitDir(dir);
- Repository db = rb.build();
- try {
- run(db);
- } finally {
- db.close();
+ try (Repository repo = rb.build()) {
+ run(repo);
}
}
}
- private void run(Repository db) throws Exception {
+ private void run(Repository repo) throws Exception {
List<Function> all = init();
long fileCnt = 0;
long lineCnt = 0;
- try (ObjectReader or = db.newObjectReader()) {
- final MutableObjectId id = new MutableObjectId();
+ try (ObjectReader or = repo.newObjectReader();
RevWalk rw = new RevWalk(or);
- TreeWalk tw = new TreeWalk(or);
- tw.reset(rw.parseTree(db.resolve(Constants.HEAD)));
+ TreeWalk tw = new TreeWalk(or)) {
+ final MutableObjectId id = new MutableObjectId();
+ tw.reset(rw.parseTree(repo.resolve(Constants.HEAD)));
tw.setRecursive(true);
while (tw.next()) {
@@ -321,13 +281,13 @@ class TextHashFunctions extends TextBuiltin {
continue;
}
- if (RawText.isBinary(raw))
+ if (RawText.isBinary(raw, raw.length, true))
continue;
RawText txt = new RawText(raw);
int[] lines = new int[txt.size()];
int cnt = 0;
- HashSet<Line> u = new HashSet<Line>();
+ HashSet<Line> u = new HashSet<>();
for (int i = 0; i < txt.size(); i++) {
if (u.add(new Line(txt, i)))
lines[cnt++] = i;
@@ -341,17 +301,18 @@ class TextHashFunctions extends TextBuiltin {
}
}
- if (db.getDirectory() != null) {
- String name = db.getDirectory().getName();
- File parent = db.getDirectory().getParentFile();
+ File directory = repo.getDirectory();
+ if (directory != null) {
+ String name = directory.getName();
+ File parent = directory.getParentFile();
if (name.equals(Constants.DOT_GIT) && parent != null)
name = parent.getName();
outw.println(name + ":"); //$NON-NLS-1$
}
- outw.format(" %6d files; %5d avg. unique lines/file\n", //
- valueOf(fileCnt), //
- valueOf(lineCnt / fileCnt));
- outw.format("%-20s %-15s %9s\n", "Hash", "Fold", "Max Len");
+ outw.format(" %6d files; %5d avg. unique lines/file\n", //$NON-NLS-1$
+ Long.valueOf(fileCnt), //
+ Long.valueOf(lineCnt / fileCnt));
+ outw.format("%-20s %-15s %9s\n", "Hash", "Fold", "Max Len"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
outw.println("-----------------------------------------------"); //$NON-NLS-1$
String lastHashName = null;
for (Function fun : all) {
@@ -361,7 +322,7 @@ class TextHashFunctions extends TextBuiltin {
outw.format("%-20s %-15s %9d\n", // //$NON-NLS-1$
hashName, //
fun.fold.name, //
- valueOf(fun.maxChainLength));
+ Integer.valueOf(fun.maxChainLength));
lastHashName = fun.hash.name;
}
outw.println();
@@ -385,8 +346,8 @@ class TextHashFunctions extends TextBuiltin {
}
private List<Function> init() {
- List<Hash> hashes = new ArrayList<Hash>();
- List<Fold> folds = new ArrayList<Fold>();
+ List<Hash> hashes = new ArrayList<>();
+ List<Fold> folds = new ArrayList<>();
try {
for (Field f : TextHashFunctions.class.getDeclaredFields()) {
@@ -403,13 +364,11 @@ class TextHashFunctions extends TextBuiltin {
folds.add(fold);
}
}
- } catch (IllegalArgumentException e) {
- throw new RuntimeException("Cannot determine names", e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException("Cannot determine names", e);
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ throw new RuntimeException("Cannot determine names", e); //$NON-NLS-1$
}
- List<Function> all = new ArrayList<Function>();
+ List<Function> all = new ArrayList<>();
for (Hash cmp : hashes) {
if (include(cmp.name, hashFunctions)) {
for (Fold f : folds) {
@@ -446,7 +405,7 @@ class TextHashFunctions extends TextBuiltin {
}
/** Base class for any hashCode function to be tested. */
- private static abstract class Hash extends RawTextComparator {
+ private abstract static class Hash extends RawTextComparator {
String name;
@Override
@@ -456,7 +415,7 @@ class TextHashFunctions extends TextBuiltin {
}
/** Base class for any hashCode folding function to be tested. */
- private static abstract class Fold {
+ private abstract static class Fold {
String name;
/**
@@ -474,7 +433,7 @@ class TextHashFunctions extends TextBuiltin {
}
/** Utility to help us identify unique lines in a file. */
- private class Line {
+ private static class Line {
private final RawText txt;
private final int pos;
@@ -499,7 +458,7 @@ class TextHashFunctions extends TextBuiltin {
}
}
- private static int tableBits(final int sz) {
+ private static int tableBits(int sz) {
int bits = 31 - Integer.numberOfLeadingZeros(sz);
if (bits == 0)
bits = 1;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/VerifyReftable.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/VerifyReftable.java
new file mode 100644
index 0000000000..aa1b81f2b6
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/VerifyReftable.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2017, Google Inc. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.pgm.debug;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+import org.eclipse.jgit.internal.storage.io.BlockSource;
+import org.eclipse.jgit.internal.storage.reftable.RefCursor;
+import org.eclipse.jgit.internal.storage.reftable.ReftableReader;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefComparator;
+import org.eclipse.jgit.lib.TextProgressMonitor;
+import org.eclipse.jgit.pgm.Command;
+import org.eclipse.jgit.pgm.TextBuiltin;
+import org.kohsuke.args4j.Argument;
+
+@Command
+class VerifyReftable extends TextBuiltin {
+ private static final long SEED1 = 0xaba8bb4de4caf86cL;
+ private static final long SEED2 = 0x28bb5c25ad43ecb5L;
+
+ @Argument(index = 0)
+ private String lsRemotePath;
+
+ @Argument(index = 1)
+ private String reftablePath;
+
+ @Override
+ protected void run() throws Exception {
+ List<Ref> refs = WriteReftable.readRefs(lsRemotePath);
+
+ try (FileInputStream in = new FileInputStream(reftablePath);
+ BlockSource src = BlockSource.from(in);
+ ReftableReader reader = new ReftableReader(src)) {
+ scan(refs, reader);
+ seek(refs, reader);
+ byId(refs, reader);
+ }
+ }
+
+ @SuppressWarnings("nls")
+ private void scan(List<Ref> refs, ReftableReader reader)
+ throws IOException {
+ errw.print(String.format("%-20s", "sequential scan..."));
+ errw.flush();
+ try (RefCursor rc = reader.allRefs()) {
+ for (Ref exp : refs) {
+ verify(exp, rc);
+ }
+ if (rc.next()) {
+ throw die("expected end of table");
+ }
+ }
+ errw.println(" OK");
+ }
+
+ @SuppressWarnings("nls")
+ private void seek(List<Ref> refs, ReftableReader reader)
+ throws IOException {
+ List<Ref> rnd = new ArrayList<>(refs);
+ Collections.shuffle(rnd, new Random(SEED1));
+
+ TextProgressMonitor pm = new TextProgressMonitor(errw);
+ pm.beginTask("random seek", rnd.size());
+ for (Ref exp : rnd) {
+ try (RefCursor rc = reader.seekRef(exp.getName())) {
+ verify(exp, rc);
+ if (rc.next()) {
+ throw die("should not have ref after " + exp.getName());
+ }
+ }
+ pm.update(1);
+ }
+ pm.endTask();
+ }
+
+ @SuppressWarnings("nls")
+ private void byId(List<Ref> refs, ReftableReader reader)
+ throws IOException {
+ Map<ObjectId, List<Ref>> want = groupById(refs);
+ List<List<Ref>> rnd = new ArrayList<>(want.values());
+ Collections.shuffle(rnd, new Random(SEED2));
+
+ TextProgressMonitor pm = new TextProgressMonitor(errw);
+ pm.beginTask("byObjectId", rnd.size());
+ for (List<Ref> exp : rnd) {
+ Collections.sort(exp, RefComparator.INSTANCE);
+ ObjectId id = exp.get(0).getObjectId();
+ try (RefCursor rc = reader.byObjectId(id)) {
+ for (Ref r : exp) {
+ verify(r, rc);
+ }
+ }
+ pm.update(1);
+ }
+ pm.endTask();
+ }
+
+ private static Map<ObjectId, List<Ref>> groupById(List<Ref> refs) {
+ Map<ObjectId, List<Ref>> m = new HashMap<>();
+ for (Ref r : refs) {
+ ObjectId id = r.getObjectId();
+ if (id != null) {
+ List<Ref> c = m.get(id);
+ if (c == null) {
+ c = new ArrayList<>(2);
+ m.put(id, c);
+ }
+ c.add(r);
+ }
+ }
+ return m;
+ }
+
+ @SuppressWarnings("nls")
+ private void verify(Ref exp, RefCursor rc) throws IOException {
+ if (!rc.next()) {
+ throw die("ended before " + exp.getName());
+ }
+
+ Ref act = rc.getRef();
+ if (!exp.getName().equals(act.getName())) {
+ throw die(String.format("expected %s, found %s",
+ exp.getName(),
+ act.getName()));
+ }
+
+ if (exp.isSymbolic()) {
+ if (!act.isSymbolic()) {
+ throw die("expected " + act.getName() + " to be symbolic");
+ }
+ if (!exp.getTarget().getName().equals(act.getTarget().getName())) {
+ throw die(String.format("expected %s to be %s, found %s",
+ exp.getName(),
+ exp.getLeaf().getName(),
+ act.getLeaf().getName()));
+ }
+ return;
+ }
+
+ if (!AnyObjectId.isEqual(exp.getObjectId(), act.getObjectId())) {
+ throw die(String.format("expected %s to be %s, found %s",
+ exp.getName(),
+ id(exp.getObjectId()),
+ id(act.getObjectId())));
+ }
+
+ if (exp.getPeeledObjectId() != null
+ && !AnyObjectId.isEqual(exp.getPeeledObjectId(),
+ act.getPeeledObjectId())) {
+ throw die(String.format("expected %s to be %s, found %s",
+ exp.getName(),
+ id(exp.getPeeledObjectId()),
+ id(act.getPeeledObjectId())));
+ }
+ }
+
+ @SuppressWarnings("nls")
+ private static String id(ObjectId id) {
+ return id != null ? id.name() : "<null>";
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteDirCache.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteDirCache.java
index 42428c7740..d367f02497 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteDirCache.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteDirCache.java
@@ -1,45 +1,12 @@
/*
* Copyright (C) 2008, Google Inc.
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.debug;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java
new file mode 100644
index 0000000000..7aff2dd9cd
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/WriteReftable.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2017, Google Inc. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+package org.eclipse.jgit.pgm.debug;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.eclipse.jgit.lib.Constants.HEAD;
+import static org.eclipse.jgit.lib.Constants.MASTER;
+import static org.eclipse.jgit.lib.Constants.R_HEADS;
+import static org.eclipse.jgit.lib.Ref.Storage.NEW;
+import static org.eclipse.jgit.lib.Ref.Storage.PACKED;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.jgit.internal.storage.reftable.ReftableConfig;
+import org.eclipse.jgit.internal.storage.reftable.ReftableWriter;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdRef;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.SymbolicRef;
+import org.eclipse.jgit.pgm.Command;
+import org.eclipse.jgit.pgm.TextBuiltin;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+
+@Command
+class WriteReftable extends TextBuiltin {
+ private static final int KIB = 1 << 10;
+ private static final int MIB = 1 << 20;
+
+ @Option(name = "--block-size")
+ private int refBlockSize;
+
+ @Option(name = "--log-block-size")
+ private int logBlockSize;
+
+ @Option(name = "--restart-interval")
+ private int restartInterval;
+
+ @Option(name = "--index-levels")
+ private int indexLevels;
+
+ @Option(name = "--reflog-in")
+ private String reflogIn;
+
+ @Option(name = "--no-index-objects")
+ private boolean noIndexObjects;
+
+ @Argument(index = 0)
+ private String in;
+
+ @Argument(index = 1)
+ private String out;
+
+ @SuppressWarnings({ "nls", "boxing" })
+ @Override
+ protected void run() throws Exception {
+ List<Ref> refs = readRefs(in);
+ List<LogEntry> logs = readLog(reflogIn);
+
+ ReftableWriter.Stats stats;
+ try (OutputStream os = new FileOutputStream(out)) {
+ ReftableConfig cfg = new ReftableConfig();
+ cfg.setIndexObjects(!noIndexObjects);
+ if (refBlockSize > 0) {
+ cfg.setRefBlockSize(refBlockSize);
+ }
+ if (logBlockSize > 0) {
+ cfg.setLogBlockSize(logBlockSize);
+ }
+ if (restartInterval > 0) {
+ cfg.setRestartInterval(restartInterval);
+ }
+ if (indexLevels > 0) {
+ cfg.setMaxIndexLevels(indexLevels);
+ }
+
+ ReftableWriter w = new ReftableWriter(cfg, os);
+ w.setMinUpdateIndex(min(logs)).setMaxUpdateIndex(max(logs));
+ w.begin();
+ w.sortAndWriteRefs(refs);
+ for (LogEntry e : logs) {
+ w.writeLog(e.ref, e.updateIndex, e.who,
+ e.oldId, e.newId, e.message);
+ }
+ stats = w.finish().getStats();
+ }
+
+ double fileMiB = ((double) stats.totalBytes()) / MIB;
+ printf("Summary:");
+ printf(" file sz : %.1f MiB (%d bytes)", fileMiB, stats.totalBytes());
+ printf(" padding : %d KiB", stats.paddingBytes() / KIB);
+ errw.println();
+
+ printf("Refs:");
+ printf(" ref blk : %d", stats.refBlockSize());
+ printf(" restarts: %d", stats.restartInterval());
+ printf(" refs : %d", stats.refCount());
+ if (stats.refIndexLevels() > 0) {
+ int idxSize = (int) Math.round(((double) stats.refIndexSize()) / KIB);
+ printf(" idx sz : %d KiB", idxSize);
+ printf(" idx lvl : %d", stats.refIndexLevels());
+ }
+ printf(" avg ref : %d bytes", stats.refBytes() / refs.size());
+ errw.println();
+
+ if (stats.objCount() > 0) {
+ int objMiB = (int) Math.round(((double) stats.objBytes()) / MIB);
+ int idLen = stats.objIdLength();
+ printf("Objects:");
+ printf(" obj blk : %d", stats.refBlockSize());
+ printf(" restarts: %d", stats.restartInterval());
+ printf(" objects : %d", stats.objCount());
+ printf(" obj sz : %d MiB (%d bytes)", objMiB, stats.objBytes());
+ if (stats.objIndexSize() > 0) {
+ int s = (int) Math.round(((double) stats.objIndexSize()) / KIB);
+ printf(" idx sz : %d KiB", s);
+ printf(" idx lvl : %d", stats.objIndexLevels());
+ }
+ printf(" id len : %d bytes (%d hex digits)", idLen, 2 * idLen);
+ printf(" avg obj : %d bytes", stats.objBytes() / stats.objCount());
+ errw.println();
+ }
+ if (stats.logCount() > 0) {
+ int logMiB = (int) Math.round(((double) stats.logBytes()) / MIB);
+ printf("Log:");
+ printf(" log blk : %d", stats.logBlockSize());
+ printf(" logs : %d", stats.logCount());
+ printf(" log sz : %d MiB (%d bytes)", logMiB, stats.logBytes());
+ printf(" avg log : %d bytes", stats.logBytes() / logs.size());
+ errw.println();
+ }
+ }
+
+ private void printf(String fmt, Object... args) throws IOException {
+ errw.println(String.format(fmt, args));
+ }
+
+ static List<Ref> readRefs(String inputFile) throws IOException {
+ List<Ref> refs = new ArrayList<>();
+ try (BufferedReader br = new BufferedReader(
+ new InputStreamReader(new FileInputStream(inputFile), UTF_8))) {
+ String line;
+ while ((line = br.readLine()) != null) {
+ ObjectId id = ObjectId.fromString(line.substring(0, 40));
+ String name = line.substring(41, line.length());
+ if (name.endsWith("^{}")) { //$NON-NLS-1$
+ int lastIdx = refs.size() - 1;
+ Ref last = refs.get(lastIdx);
+ refs.set(lastIdx, new ObjectIdRef.PeeledTag(PACKED,
+ last.getName(), last.getObjectId(), id));
+ continue;
+ }
+
+ Ref ref;
+ if (name.equals(HEAD)) {
+ ref = new SymbolicRef(name, new ObjectIdRef.Unpeeled(NEW,
+ R_HEADS + MASTER, null));
+ } else {
+ ref = new ObjectIdRef.PeeledNonTag(PACKED, name, id);
+ }
+ refs.add(ref);
+ }
+ }
+ Collections.sort(refs, (a, b) -> a.getName().compareTo(b.getName()));
+ return refs;
+ }
+
+ private static List<LogEntry> readLog(String logPath)
+ throws FileNotFoundException, IOException {
+ if (logPath == null) {
+ return Collections.emptyList();
+ }
+
+ List<LogEntry> log = new ArrayList<>();
+ try (BufferedReader br = new BufferedReader(
+ new InputStreamReader(new FileInputStream(logPath), UTF_8))) {
+ @SuppressWarnings("nls")
+ Pattern pattern = Pattern.compile("([^,]+)" // 1: ref
+ + ",([0-9]+(?:[.][0-9]+)?)" // 2: time
+ + ",([^,]+)" // 3: who
+ + ",([^,]+)" // 4: old
+ + ",([^,]+)" // 5: new
+ + ",(.*)"); // 6: msg
+ String line;
+ while ((line = br.readLine()) != null) {
+ Matcher m = pattern.matcher(line);
+ if (!m.matches()) {
+ throw new IOException("unparsed line: " + line); //$NON-NLS-1$
+ }
+ String ref = m.group(1);
+ double t = Double.parseDouble(m.group(2));
+ Instant time = Instant.ofEpochSecond((long) t);
+ long index = (long) (t * 1e6);
+ String user = m.group(3);
+ ObjectId oldId = parseId(m.group(4));
+ ObjectId newId = parseId(m.group(5));
+ String msg = m.group(6);
+ String email = user + "@gerrit"; //$NON-NLS-1$
+ PersonIdent who = new PersonIdent(user, email, time,
+ ZoneOffset.ofHours(-8));
+ log.add(new LogEntry(ref, index, who, oldId, newId, msg));
+ }
+ }
+ Collections.sort(log, LogEntry::compare);
+ return log;
+ }
+
+ private static long min(List<LogEntry> log) {
+ return log.stream().mapToLong(e -> e.updateIndex).min().orElse(0);
+ }
+
+ private static long max(List<LogEntry> log) {
+ return log.stream().mapToLong(e -> e.updateIndex).max().orElse(0);
+ }
+
+ private static ObjectId parseId(String s) {
+ if ("NULL".equals(s)) { //$NON-NLS-1$
+ return ObjectId.zeroId();
+ }
+ return ObjectId.fromString(s);
+ }
+
+ private static class LogEntry {
+ static int compare(LogEntry a, LogEntry b) {
+ int cmp = a.ref.compareTo(b.ref);
+ if (cmp == 0) {
+ cmp = Long.signum(b.updateIndex - a.updateIndex);
+ }
+ return cmp;
+ }
+
+ final String ref;
+ final long updateIndex;
+ final PersonIdent who;
+ final ObjectId oldId;
+ final ObjectId newId;
+ final String message;
+
+ LogEntry(String ref, long updateIndex, PersonIdent who,
+ ObjectId oldId, ObjectId newId, String message) {
+ this.ref = ref;
+ this.updateIndex = updateIndex;
+ this.who = who;
+ this.oldId = oldId;
+ this.newId = newId;
+ this.message = message;
+ }
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java
index 433ddf2b13..bb1e950542 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java
@@ -1,60 +1,65 @@
/*
* Copyright (C) 2010, 2013 Sasa Zivkov <sasa.zivkov@sap.com>
- * Copyright (C) 2013, Obeo
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2013, 2025 Obeo and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.internal;
import java.text.MessageFormat;
+import java.util.Locale;
import org.eclipse.jgit.nls.NLS;
import org.eclipse.jgit.nls.TranslationBundle;
+import org.kohsuke.args4j.Localizable;
/**
* Translation bundle for JGit command line interface
*/
+@SuppressWarnings("MissingSummary")
public class CLIText extends TranslationBundle {
+ /**
+ * Formats text strings using {@code Localizable}.
+ *
+ */
+ public static class Format implements Localizable {
+ final String text;
+
+ Format(String text) {
+ this.text = text;
+ }
+
+ @Override
+ public String formatWithLocale(Locale locale, Object... args) {
+ // we don't care about Locale for now
+ return format(args);
+ }
+
+ @Override
+ public String format(Object... args) {
+ return MessageFormat.format(text, args);
+ }
+ }
/**
+ * Format text
+ *
+ * @param text
+ * the text to format.
+ * @return a new Format instance.
+ */
+ public static Format format(String text) {
+ return new Format(text);
+ }
+
+ /**
+ * Get an instance of this translation bundle
+ *
* @return an instance of this translation bundle
*/
public static CLIText get() {
@@ -68,13 +73,25 @@ public class CLIText extends TranslationBundle {
* @param line
* the line to format
* @return the formatted line
- * @since 2.2
*/
public static String formatLine(String line) {
return MessageFormat.format(get().lineFormat, line);
}
+ /**
+ * Format the given argument as fatal error using the format defined by
+ * {@link #fatalError} ("fatal: " by default).
+ *
+ * @param message
+ * the message to format
+ * @return the formatted line
+ */
+ public static String fatalError(String message) {
+ return MessageFormat.format(get().fatalError, message);
+ }
+
// @formatter:off
+ /***/ public String addIncompatibleOptions;
/***/ public String alreadyOnBranch;
/***/ public String alreadyUpToDate;
/***/ public String answerNo;
@@ -85,11 +102,11 @@ public class CLIText extends TranslationBundle {
/***/ public String branchCreatedFrom;
/***/ public String branchDetachedHEAD;
/***/ public String branchIsNotAnAncestorOfYourCurrentHEAD;
+ /***/ public String branchNameRequired;
/***/ public String branchNotFound;
/***/ public String cacheTreePathInfo;
/***/ public String configFileNotFound;
/***/ public String cannotBeRenamed;
- /***/ public String cannotChekoutNoHeadsAdvertisedByRemote;
/***/ public String cannotCombineSquashWithNoff;
/***/ public String cannotCreateCommand;
/***/ public String cannotCreateOutputStream;
@@ -98,27 +115,35 @@ public class CLIText extends TranslationBundle {
/***/ public String cannotDeleteTheBranchWhichYouAreCurrentlyOn;
/***/ public String cannotGuessLocalNameFrom;
/***/ public String cannotLock;
- /***/ public String cannotMergeDetachedHead;
/***/ public String cannotReadBecause;
/***/ public String cannotReadPackageInformation;
/***/ public String cannotRenameDetachedHEAD;
/***/ public String cannotResolve;
/***/ public String cannotSetupConsole;
/***/ public String cannotUseObjectsWithGlog;
+ /***/ public String cannotUseNameStatusOnlyAndNameOnly;
/***/ public String cantFindGitDirectory;
/***/ public String cantWrite;
/***/ public String changesNotStagedForCommit;
/***/ public String changesToBeCommitted;
+ /***/ public String checkingOut;
/***/ public String checkoutConflict;
/***/ public String checkoutConflictPathLine;
+ /***/ public String cleanRequireForce;
/***/ public String clonedEmptyRepository;
/***/ public String cloningInto;
/***/ public String commitLabel;
+ /***/ public String configOnlyListOptionSupported;
/***/ public String conflictingUsageOf_git_dir_andArguments;
/***/ public String couldNotCreateBranch;
/***/ public String dateInfo;
/***/ public String deletedBranch;
/***/ public String deletedRemoteBranch;
+ /***/ public String diffToolHelpSetToFollowing;
+ /***/ public String diffToolLaunch;
+ /***/ public String diffToolDied;
+ /***/ public String diffToolPromptToolName;
+ /***/ public String diffToolUnknownToolName;
/***/ public String doesNotExist;
/***/ public String dontOverwriteLocalChanges;
/***/ public String everythingUpToDate;
@@ -126,20 +151,47 @@ public class CLIText extends TranslationBundle {
/***/ public String exporting;
/***/ public String failedToCommitIndex;
/***/ public String failedToLockIndex;
- /***/ public String failedToLockTag;
/***/ public String fatalError;
/***/ public String fatalThisProgramWillDestroyTheRepository;
+ /***/ public String fetchingSubmodule;
/***/ public String fileIsRequired;
/***/ public String ffNotPossibleAborting;
/***/ public String forcedUpdate;
/***/ public String fromURI;
/***/ public String initializedEmptyGitRepositoryIn;
/***/ public String invalidHttpProxyOnlyHttpSupported;
+ /***/ public String invalidRecurseSubmodulesMode;
+ /***/ public String invalidUntrackedFilesMode;
/***/ public String jgitVersion;
+ /***/ public String lfsNoAccessKey;
+ /***/ public String lfsNoSecretKey;
+ /***/ public String lfsProtocolUrl;
+ /***/ public String lfsStoreDirectory;
+ /***/ public String lfsStoreUrl;
+ /***/ public String lfsUnknownStoreType;
/***/ public String lineFormat;
/***/ public String listeningOn;
+ /***/ public String logNoSignatureVerifier;
/***/ public String mergeCheckoutConflict;
/***/ public String mergeConflict;
+ /***/ public String mergeToolHelpSetToFollowing;
+ /***/ public String mergeToolLaunch;
+ /***/ public String mergeToolDied;
+ /***/ public String mergeToolNoFiles;
+ /***/ public String mergeToolMerging;
+ /***/ public String mergeToolUnknownConflict;
+ /***/ public String mergeToolNormalConflict;
+ /***/ public String mergeToolMergeFailed;
+ /***/ public String mergeToolExecutionError;
+ /***/ public String mergeToolFileUnchanged;
+ /***/ public String mergeToolDeletedConflict;
+ /***/ public String mergeToolDeletedConflictByUs;
+ /***/ public String mergeToolDeletedConflictByThem;
+ /***/ public String mergeToolContinueUnresolvedPaths;
+ /***/ public String mergeToolWasMergeSuccessfull;
+ /***/ public String mergeToolDeletedMergeDecision;
+ /***/ public String mergeToolPromptToolName;
+ /***/ public String mergeToolUnknownToolName;
/***/ public String mergeFailed;
/***/ public String mergeCheckoutFailed;
/***/ public String mergeMadeBy;
@@ -164,6 +216,8 @@ public class CLIText extends TranslationBundle {
/***/ public String metaVar_filepattern;
/***/ public String metaVar_gitDir;
/***/ public String metaVar_hostName;
+ /***/ public String metaVar_instant;
+ /***/ public String metaVar_lfsStorage;
/***/ public String metaVar_linesOfContext;
/***/ public String metaVar_message;
/***/ public String metaVar_n;
@@ -173,24 +227,31 @@ public class CLIText extends TranslationBundle {
/***/ public String metaVar_pass;
/***/ public String metaVar_path;
/***/ public String metaVar_paths;
+ /***/ public String metaVar_pattern;
/***/ public String metaVar_port;
/***/ public String metaVar_ref;
/***/ public String metaVar_refs;
/***/ public String metaVar_refspec;
/***/ public String metaVar_remoteName;
+ /***/ public String metaVar_s3Bucket;
+ /***/ public String metaVar_s3Region;
+ /***/ public String metaVar_s3StorageClass;
/***/ public String metaVar_seconds;
/***/ public String metaVar_service;
/***/ public String metaVar_treeish;
/***/ public String metaVar_uriish;
/***/ public String metaVar_url;
/***/ public String metaVar_user;
+ /***/ public String metaVar_values;
/***/ public String metaVar_version;
/***/ public String mostCommonlyUsedCommandsAre;
/***/ public String needApprovalToDestroyCurrentRepository;
+ /***/ public String needSingleRevision;
/***/ public String noGitRepositoryConfigured;
/***/ public String noNamesFound;
/***/ public String noSuchFile;
- /***/ public String noSuchRemoteRef;
+ /***/ public String noSuchPathInRef;
+ /***/ public String noSuchRef;
/***/ public String noTREESectionInIndex;
/***/ public String nonFastForward;
/***/ public String noSystemConsoleAvailable;
@@ -201,6 +262,7 @@ public class CLIText extends TranslationBundle {
/***/ public String notARevision;
/***/ public String notATree;
/***/ public String notAValidRefName;
+ /***/ public String notAValidCommitName;
/***/ public String notAnIndexFile;
/***/ public String notAnObject;
/***/ public String notFound;
@@ -210,7 +272,7 @@ public class CLIText extends TranslationBundle {
/***/ public String onBranchToBeBorn;
/***/ public String onBranch;
/***/ public String onlyOneMetaVarExpectedIn;
- /***/ public String onlyOneOfIncludeOnlyAllInteractiveCanBeUsed;
+ /***/ public String onlyOneCommitOptionAllowed;
/***/ public String password;
/***/ public String pathspecDidNotMatch;
/***/ public String pushTo;
@@ -219,7 +281,10 @@ public class CLIText extends TranslationBundle {
/***/ public String remoteMessage;
/***/ public String remoteRefObjectChangedIsNotExpectedOne;
/***/ public String remoteSideDoesNotSupportDeletingRefs;
+ /***/ public String removing;
/***/ public String repaint;
+ /***/ public String resetNoMode;
+ /***/ public String s3InvalidBucket;
/***/ public String serviceNotSupported;
/***/ public String skippingObject;
/***/ public String statusFileListFormat;
@@ -235,16 +300,20 @@ public class CLIText extends TranslationBundle {
/***/ public String statusDeletedByUs;
/***/ public String statusBothAdded;
/***/ public String statusBothModified;
+ /***/ public String submoduleRegistered;
/***/ public String switchedToNewBranch;
/***/ public String switchedToBranch;
/***/ public String tagAlreadyExists;
/***/ public String tagLabel;
+ /***/ public String tagNotFound;
/***/ public String taggerInfo;
/***/ public String timeInMilliSeconds;
/***/ public String tooManyRefsGiven;
/***/ public String treeIsRequired;
/***/ public char[] unknownIoErrorStdout;
+ /***/ public String unknownExtraArgument;
/***/ public String unknownMergeStrategy;
+ /***/ public String unknownSubcommand;
/***/ public String unmergedPaths;
/***/ public String unsupportedOperation;
/***/ public String untrackedFiles;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/SshDriver.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/SshDriver.java
new file mode 100644
index 0000000000..4b7cba4729
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/SshDriver.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.pgm.internal;
+
+/**
+ * Simple enumeration for the available built-in ssh clients.
+ */
+public enum SshDriver {
+
+ /** Default client: use JSch. */
+ JSCH,
+
+ /** Use the Apache MINA sshd client from org.eclipse.jgit.ssh.apache. */
+ APACHE;
+
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/VerificationUtils.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/VerificationUtils.java
new file mode 100644
index 0000000000..64ee602620
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/VerificationUtils.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.pgm.internal;
+
+import java.io.IOException;
+
+import org.eclipse.jgit.lib.SignatureVerifier.SignatureVerification;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.util.GitDateFormatter;
+import org.eclipse.jgit.util.SignatureUtils;
+import org.eclipse.jgit.util.io.ThrowingPrintWriter;
+
+/**
+ * Utilities for signature verification.
+ */
+public final class VerificationUtils {
+
+ private VerificationUtils() {
+ // No instantiation
+ }
+
+ /**
+ * Writes information about a signature verification to the given writer.
+ *
+ * @param out
+ * to write to
+ * @param verification
+ * to show
+ * @param name
+ * of the verifier used
+ * @param creator
+ * of the object verified; used for time zone information
+ * @throws IOException
+ * if writing fails
+ */
+ public static void writeVerification(ThrowingPrintWriter out,
+ SignatureVerification verification, String name,
+ PersonIdent creator) throws IOException {
+ String[] text = SignatureUtils
+ .toString(verification, creator,
+ new GitDateFormatter(GitDateFormatter.Format.LOCALE))
+ .split("\n"); //$NON-NLS-1$
+ for (String line : text) {
+ out.print(name);
+ out.print(": "); //$NON-NLS-1$
+ out.println(line);
+ }
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java
index 229fb67b0c..cea2309f7f 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java
@@ -1,45 +1,12 @@
/*
* Copyright (C) 2008-2009, Google Inc.
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.opt;
@@ -48,12 +15,6 @@ import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-import org.kohsuke.args4j.OptionDef;
-import org.kohsuke.args4j.spi.OptionHandler;
-import org.kohsuke.args4j.spi.Parameters;
-import org.kohsuke.args4j.spi.Setter;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheIterator;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
@@ -66,9 +27,16 @@ import org.eclipse.jgit.treewalk.CanonicalTreeParser;
import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.eclipse.jgit.treewalk.WorkingTreeOptions;
import org.eclipse.jgit.util.FS;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.OptionDef;
+import org.kohsuke.args4j.spi.OptionHandler;
+import org.kohsuke.args4j.spi.Parameters;
+import org.kohsuke.args4j.spi.Setter;
/**
- * Custom argument handler {@link AbstractTreeIterator} from string values.
+ * Custom argument handler
+ * {@link org.eclipse.jgit.treewalk.AbstractTreeIterator} from string values.
* <p>
* Assumes the parser has been initialized with a Repository.
*/
@@ -82,8 +50,11 @@ public class AbstractTreeIteratorHandler extends
* This constructor is used only by args4j.
*
* @param parser
+ * a {@link org.kohsuke.args4j.CmdLineParser} object.
* @param option
+ * a {@link org.kohsuke.args4j.OptionDef} object.
* @param setter
+ * a {@link org.kohsuke.args4j.spi.Setter} object.
*/
public AbstractTreeIteratorHandler(final CmdLineParser parser,
final OptionDef option,
@@ -93,7 +64,7 @@ public class AbstractTreeIteratorHandler extends
}
@Override
- public int parseArguments(final Parameters params) throws CmdLineException {
+ public int parseArguments(Parameters params) throws CmdLineException {
final String name = params.getParameter(0);
if (new File(name).isDirectory()) {
@@ -109,7 +80,7 @@ public class AbstractTreeIteratorHandler extends
try {
dirc = DirCache.read(new File(name), FS.DETECTED);
} catch (IOException e) {
- throw new CmdLineException(MessageFormat.format(CLIText.get().notAnIndexFile, name), e);
+ throw new CmdLineException(clp, MessageFormat.format(CLIText.get().notAnIndexFile, name), e);
}
setter.addValue(new DirCacheIterator(dirc));
return 1;
@@ -119,20 +90,24 @@ public class AbstractTreeIteratorHandler extends
try {
id = clp.getRepository().resolve(name);
} catch (IOException e) {
- throw new CmdLineException(e.getMessage());
+ throw new CmdLineException(clp, CLIText.format(e.getMessage()));
}
if (id == null)
- throw new CmdLineException(MessageFormat.format(CLIText.get().notATree, name));
+ throw new CmdLineException(clp,
+ CLIText.format(CLIText.get().notATree), name);
final CanonicalTreeParser p = new CanonicalTreeParser();
try (ObjectReader curs = clp.getRepository().newObjectReader()) {
p.reset(curs, clp.getRevWalk().parseTree(id));
- } catch (MissingObjectException e) {
- throw new CmdLineException(MessageFormat.format(CLIText.get().notATree, name));
- } catch (IncorrectObjectTypeException e) {
- throw new CmdLineException(MessageFormat.format(CLIText.get().notATree, name));
+ } catch (MissingObjectException | IncorrectObjectTypeException e) {
+ CmdLineException cle = new CmdLineException(clp,
+ CLIText.format(CLIText.get().notATree), name);
+ cle.initCause(e);
+ throw cle;
} catch (IOException e) {
- throw new CmdLineException(MessageFormat.format(CLIText.get().cannotReadBecause, name, e.getMessage()));
+ throw new CmdLineException(clp,
+ CLIText.format(CLIText.get().cannotReadBecause), name,
+ e.getMessage());
}
setter.addValue(p);
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java
index 3f77aa6687..463213dc4f 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/CmdLineParser.java
@@ -1,61 +1,27 @@
/*
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.opt;
+import java.io.IOException;
+import java.io.Writer;
import java.lang.reflect.Field;
+import java.time.Instant;
import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ResourceBundle;
-import org.kohsuke.args4j.Argument;
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.IllegalAnnotationError;
-import org.kohsuke.args4j.NamedOptionDef;
-import org.kohsuke.args4j.Option;
-import org.kohsuke.args4j.OptionDef;
-import org.kohsuke.args4j.spi.OptionHandler;
-import org.kohsuke.args4j.spi.Setter;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.pgm.Die;
import org.eclipse.jgit.pgm.TextBuiltin;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.revwalk.RevCommit;
@@ -63,6 +29,14 @@ import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.IllegalAnnotationError;
+import org.kohsuke.args4j.NamedOptionDef;
+import org.kohsuke.args4j.OptionDef;
+import org.kohsuke.args4j.OptionHandlerRegistry;
+import org.kohsuke.args4j.spi.OptionHandler;
+import org.kohsuke.args4j.spi.RestOfArgumentsHandler;
+import org.kohsuke.args4j.spi.Setter;
/**
* Extended command line parser which handles --foo=value arguments.
@@ -74,31 +48,39 @@ import org.eclipse.jgit.treewalk.AbstractTreeIterator;
*/
public class CmdLineParser extends org.kohsuke.args4j.CmdLineParser {
static {
- registerHandler(AbstractTreeIterator.class,
+ OptionHandlerRegistry registry = OptionHandlerRegistry.getRegistry();
+ registry.registerHandler(AbstractTreeIterator.class,
AbstractTreeIteratorHandler.class);
- registerHandler(ObjectId.class, ObjectIdHandler.class);
- registerHandler(RefSpec.class, RefSpecHandler.class);
- registerHandler(RevCommit.class, RevCommitHandler.class);
- registerHandler(RevTree.class, RevTreeHandler.class);
+ registry.registerHandler(ObjectId.class, ObjectIdHandler.class);
+ registry.registerHandler(RefSpec.class, RefSpecHandler.class);
+ registry.registerHandler(RevCommit.class, RevCommitHandler.class);
+ registry.registerHandler(RevTree.class, RevTreeHandler.class);
+ registry.registerHandler(List.class, OptionWithValuesListHandler.class);
+ registry.registerHandler(Instant.class, InstantHandler.class);
}
private final Repository db;
private RevWalk walk;
+ private boolean seenHelp;
+
+ private TextBuiltin cmd;
+
/**
* Creates a new command line owner that parses arguments/options and set
* them into the given object.
*
* @param bean
- * instance of a class annotated by {@link Option} and
- * {@link Argument}. this object will receive values.
- *
+ * instance of a class annotated by
+ * {@link org.kohsuke.args4j.Option} and
+ * {@link org.kohsuke.args4j.Argument}. this object will receive
+ * values.
* @throws IllegalAnnotationError
* if the option bean class is using args4j annotations
* incorrectly.
*/
- public CmdLineParser(final Object bean) {
+ public CmdLineParser(Object bean) {
this(bean, null);
}
@@ -107,24 +89,30 @@ public class CmdLineParser extends org.kohsuke.args4j.CmdLineParser {
* them into the given object.
*
* @param bean
- * instance of a class annotated by {@link Option} and
- * {@link Argument}. this object will receive values.
+ * instance of a class annotated by
+ * {@link org.kohsuke.args4j.Option} and
+ * {@link org.kohsuke.args4j.Argument}. this object will receive
+ * values.
* @param repo
* repository this parser can translate options through.
* @throws IllegalAnnotationError
* if the option bean class is using args4j annotations
* incorrectly.
*/
- public CmdLineParser(final Object bean, Repository repo) {
+ public CmdLineParser(Object bean, Repository repo) {
super(bean);
- if (repo == null && bean instanceof TextBuiltin)
- repo = ((TextBuiltin) bean).getRepository();
+ if (bean instanceof TextBuiltin) {
+ cmd = (TextBuiltin) bean;
+ }
+ if (repo == null && cmd != null) {
+ repo = cmd.getRepository();
+ }
this.db = repo;
}
@Override
- public void parseArgument(final String... args) throws CmdLineException {
- final ArrayList<String> tmp = new ArrayList<String>(args.length);
+ public void parseArgument(String... args) throws CmdLineException {
+ final ArrayList<String> tmp = new ArrayList<>(args.length);
for (int argi = 0; argi < args.length; argi++) {
final String str = args[argi];
if (str.equals("--")) { //$NON-NLS-1$
@@ -143,9 +131,77 @@ public class CmdLineParser extends org.kohsuke.args4j.CmdLineParser {
}
tmp.add(str);
+
+ if (containsHelp(args)) {
+ // suppress exceptions on required parameters if help is present
+ seenHelp = true;
+ // stop argument parsing here
+ break;
+ }
+ }
+ List<OptionHandler> backup = null;
+ if (seenHelp) {
+ backup = unsetRequiredOptions();
}
- super.parseArgument(tmp.toArray(new String[tmp.size()]));
+ try {
+ super.parseArgument(tmp.toArray(new String[0]));
+ } catch (Die e) {
+ if (!seenHelp) {
+ throw e;
+ }
+ printToErrorWriter(CLIText.fatalError(e.getMessage()));
+ } finally {
+ // reset "required" options to defaults for correct command printout
+ if (backup != null && !backup.isEmpty()) {
+ restoreRequiredOptions(backup);
+ }
+ seenHelp = false;
+ }
+ }
+
+ private void printToErrorWriter(String error) {
+ if (cmd == null) {
+ System.err.println(error);
+ } else {
+ try {
+ cmd.getErrorWriter().println(error);
+ } catch (IOException e1) {
+ System.err.println(error);
+ }
+ }
+ }
+
+ private List<OptionHandler> unsetRequiredOptions() {
+ List<OptionHandler> options = getOptions();
+ List<OptionHandler> backup = new ArrayList<>(options);
+ for (Iterator<OptionHandler> iterator = options.iterator(); iterator
+ .hasNext();) {
+ OptionHandler handler = iterator.next();
+ if (handler.option instanceof NamedOptionDef
+ && handler.option.required()) {
+ iterator.remove();
+ }
+ }
+ return backup;
+ }
+
+ private void restoreRequiredOptions(List<OptionHandler> backup) {
+ List<OptionHandler> options = getOptions();
+ options.clear();
+ options.addAll(backup);
+ }
+
+ /**
+ * Check if array contains help option
+ *
+ * @param args
+ * non null
+ * @return true if the given array contains help option
+ * @since 4.2
+ */
+ protected boolean containsHelp(String... args) {
+ return TextBuiltin.containsHelp(args);
}
/**
@@ -181,11 +237,11 @@ public class CmdLineParser extends org.kohsuke.args4j.CmdLineParser {
return walk;
}
- static class MyOptionDef extends OptionDef {
+ class MyOptionDef extends OptionDef {
public MyOptionDef(OptionDef o) {
- super(o.usage(), o.metaVar(), o.required(), o.handler(), o
- .isMultiValued());
+ super(o.usage(), o.metaVar(), o.required(), o.help(), o.hidden(),
+ o.handler(), o.isMultiValued());
}
@Override
@@ -201,14 +257,52 @@ public class CmdLineParser extends org.kohsuke.args4j.CmdLineParser {
return metaVar();
}
}
+
+ @Override
+ public boolean required() {
+ return seenHelp ? false : super.required();
+ }
}
@Override
protected OptionHandler createOptionHandler(OptionDef o, Setter setter) {
- if (o instanceof NamedOptionDef)
+ if (o instanceof NamedOptionDef) {
return super.createOptionHandler(o, setter);
- else
- return super.createOptionHandler(new MyOptionDef(o), setter);
+ }
+ return super.createOptionHandler(new MyOptionDef(o), setter);
+
+ }
+
+ @Override
+ public void printSingleLineUsage(Writer w, ResourceBundle rb) {
+ List<OptionHandler> options = getOptions();
+ if (options.isEmpty()) {
+ super.printSingleLineUsage(w, rb);
+ return;
+ }
+ List<OptionHandler> backup = new ArrayList<>(options);
+ boolean changed = sortRestOfArgumentsHandlerToTheEnd(options);
+ try {
+ super.printSingleLineUsage(w, rb);
+ } finally {
+ if (changed) {
+ options.clear();
+ options.addAll(backup);
+ }
+ }
+ }
+ private boolean sortRestOfArgumentsHandlerToTheEnd(
+ List<OptionHandler> options) {
+ for (int i = 0; i < options.size(); i++) {
+ OptionHandler handler = options.get(i);
+ if (handler instanceof RestOfArgumentsHandler
+ || handler instanceof PathTreeFilterHandler) {
+ options.remove(i);
+ options.add(handler);
+ return true;
+ }
+ }
+ return false;
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/GpgSignHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/GpgSignHandler.java
new file mode 100644
index 0000000000..56423ada41
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/GpgSignHandler.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2018, Salesforce. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.pgm.opt;
+
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.OptionDef;
+import org.kohsuke.args4j.spi.Parameters;
+import org.kohsuke.args4j.spi.Setter;
+import org.kohsuke.args4j.spi.StringOptionHandler;
+
+/**
+ * Special handler for the <code>--gpg-sign</code> option of the
+ * <code>commit</code> command.
+ *
+ * The following rules apply:
+ * <ul>
+ * <li>If no key is given, i.e. just <code>--gpg-sign</code> is passed, then it
+ * is the same as <code>--gpg-sign=default</code></li>
+ * </ul>
+ *
+ * @since 5.3
+ */
+public class GpgSignHandler extends StringOptionHandler {
+
+ /**
+ * The value "default" which will be used when just the option is specified
+ * without any argument
+ */
+ public static final String DEFAULT = "default"; //$NON-NLS-1$
+
+ /**
+ * <p>
+ * Constructor for GpgSignHandler.
+ * </p>
+ *
+ * @param parser
+ * The parser to which this handler belongs.
+ * @param option
+ * The annotation.
+ * @param setter
+ * Object to be used for setting value.
+ */
+ public GpgSignHandler(CmdLineParser parser, OptionDef option,
+ Setter<? super String> setter) {
+ super(parser, option, setter);
+ }
+
+ @Override
+ public int parseArguments(Parameters params) throws CmdLineException {
+ String alias = params.getParameter(-1);
+ if ("--gpg-sign".equals(alias) || "-S".equals(alias)) { //$NON-NLS-1$ //$NON-NLS-2$
+ try {
+ String key = params.getParameter(0);
+ if (key == null || key.startsWith("-")) { //$NON-NLS-1$
+ // ignore invalid values and assume default
+ setter.addValue(DEFAULT);
+ return 0;
+ }
+
+ // use what we have
+ setter.addValue(key);
+ return 1;
+ } catch (CmdLineException e) {
+ // no additional value, assume default
+ setter.addValue(DEFAULT);
+ return 0;
+ }
+ }
+ return 0;
+ }
+
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/InstantHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/InstantHandler.java
new file mode 100644
index 0000000000..9c54169888
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/InstantHandler.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2022, Harald Weiner and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.pgm.opt;
+
+import java.time.Instant;
+
+import org.eclipse.jgit.pgm.internal.CLIText;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.OptionDef;
+import org.kohsuke.args4j.spi.OptionHandler;
+import org.kohsuke.args4j.spi.Parameters;
+import org.kohsuke.args4j.spi.Setter;
+
+/**
+ * Custom argument handler {@link java.time.Instant} from string values.
+ * <p>
+ * Assumes the parser has been initialized with a Repository.
+ *
+ * @since 6.5
+ */
+public class InstantHandler extends OptionHandler<Instant> {
+ /**
+ * Create a new handler for the command name.
+ * <p>
+ * This constructor is used only by args4j.
+ *
+ * @param parser
+ * a {@link org.kohsuke.args4j.CmdLineParser} object.
+ * @param option
+ * a {@link org.kohsuke.args4j.OptionDef} object.
+ * @param setter
+ * a {@link org.kohsuke.args4j.spi.Setter} object.
+ */
+ public InstantHandler(CmdLineParser parser, OptionDef option,
+ Setter<? super Instant> setter) {
+ super(parser, option, setter);
+ }
+
+ @Override
+ public int parseArguments(Parameters params) throws CmdLineException {
+ Instant instant = Instant.parse(params.getParameter(0));
+ setter.addValue(instant);
+ return 1;
+ }
+
+ @Override
+ public String getDefaultMetaVariable() {
+ return CLIText.get().metaVar_instant;
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/ObjectIdHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/ObjectIdHandler.java
index fa24d4b02f..b50df90788 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/ObjectIdHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/ObjectIdHandler.java
@@ -1,63 +1,30 @@
/*
* Copyright (C) 2009, Google Inc.
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.opt;
import java.io.IOException;
-import java.text.MessageFormat;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.pgm.internal.CLIText;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.OptionDef;
import org.kohsuke.args4j.spi.OptionHandler;
import org.kohsuke.args4j.spi.Parameters;
import org.kohsuke.args4j.spi.Setter;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.pgm.internal.CLIText;
/**
- * Custom argument handler {@link ObjectId} from string values.
+ * Custom argument handler {@link org.eclipse.jgit.lib.ObjectId} from string
+ * values.
* <p>
* Assumes the parser has been initialized with a Repository.
*/
@@ -70,8 +37,11 @@ public class ObjectIdHandler extends OptionHandler<ObjectId> {
* This constructor is used only by args4j.
*
* @param parser
+ * a {@link org.kohsuke.args4j.CmdLineParser} object.
* @param option
+ * a {@link org.kohsuke.args4j.OptionDef} object.
* @param setter
+ * a {@link org.kohsuke.args4j.spi.Setter} object.
*/
public ObjectIdHandler(final CmdLineParser parser, final OptionDef option,
final Setter<? super ObjectId> setter) {
@@ -80,20 +50,21 @@ public class ObjectIdHandler extends OptionHandler<ObjectId> {
}
@Override
- public int parseArguments(final Parameters params) throws CmdLineException {
+ public int parseArguments(Parameters params) throws CmdLineException {
final String name = params.getParameter(0);
final ObjectId id;
try {
id = clp.getRepository().resolve(name);
} catch (IOException e) {
- throw new CmdLineException(e.getMessage());
+ throw new CmdLineException(clp, CLIText.format(e.getMessage()));
}
if (id != null) {
setter.addValue(id);
return 1;
}
- throw new CmdLineException(MessageFormat.format(CLIText.get().notAnObject, name));
+ throw new CmdLineException(clp,
+ CLIText.format(CLIText.get().notAnObject), name);
}
@Override
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/OptionWithValuesListHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/OptionWithValuesListHandler.java
new file mode 100644
index 0000000000..7bb2766fe0
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/OptionWithValuesListHandler.java
@@ -0,0 +1,57 @@
+package org.eclipse.jgit.pgm.opt;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jgit.pgm.internal.CLIText;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.OptionDef;
+import org.kohsuke.args4j.spi.OptionHandler;
+import org.kohsuke.args4j.spi.Parameters;
+import org.kohsuke.args4j.spi.Setter;
+
+/**
+ * Handler which allows to parse option with few values
+ *
+ * @since 4.2
+ */
+public class OptionWithValuesListHandler extends OptionHandler<List<?>> {
+
+ /**
+ * Constructor for OptionWithValuesListHandler.
+ *
+ * @param parser
+ * a {@link org.kohsuke.args4j.CmdLineParser} object.
+ * @param option
+ * a {@link org.kohsuke.args4j.OptionDef} object.
+ * @param setter
+ * a {@link org.kohsuke.args4j.spi.Setter} object.
+ */
+ public OptionWithValuesListHandler(CmdLineParser parser,
+ OptionDef option, Setter<List<?>> setter) {
+ super(parser, option, setter);
+ }
+
+ @Override
+ public int parseArguments(Parameters params) throws CmdLineException {
+ final List<String> list = new ArrayList<>();
+ for (int idx = 0; idx < params.size(); idx++) {
+ final String p;
+ try {
+ p = params.getParameter(idx);
+ } catch (CmdLineException cle) {
+ break;
+ }
+ list.add(p);
+ }
+ setter.addValue(list);
+ return list.size();
+ }
+
+ @Override
+ public String getDefaultMetaVariable() {
+ return CLIText.get().metaVar_values;
+ }
+
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java
index 122cce7dea..f215040499 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/PathTreeFilterHandler.java
@@ -1,44 +1,11 @@
/*
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.opt;
@@ -46,23 +13,23 @@ package org.eclipse.jgit.pgm.opt;
import java.util.ArrayList;
import java.util.List;
+import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.treewalk.filter.PathFilter;
+import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
-import org.kohsuke.args4j.Option;
import org.kohsuke.args4j.OptionDef;
import org.kohsuke.args4j.spi.OptionHandler;
import org.kohsuke.args4j.spi.Parameters;
import org.kohsuke.args4j.spi.Setter;
-import org.eclipse.jgit.pgm.internal.CLIText;
-import org.eclipse.jgit.treewalk.filter.PathFilter;
-import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
-import org.eclipse.jgit.treewalk.filter.TreeFilter;
/**
- * Create a {@link TreeFilter} to patch math names.
+ * Create a {@link org.eclipse.jgit.treewalk.filter.TreeFilter} to match path
+ * names.
* <p>
* This handler consumes all arguments to the end of the command line, and is
- * meant to be used on an {@link Option} of name "--".
+ * meant to be used on an {@link org.kohsuke.args4j.Option} of name "--".
*/
public class PathTreeFilterHandler extends OptionHandler<TreeFilter> {
/**
@@ -71,8 +38,11 @@ public class PathTreeFilterHandler extends OptionHandler<TreeFilter> {
* This constructor is used only by args4j.
*
* @param parser
+ * a {@link org.kohsuke.args4j.CmdLineParser} object.
* @param option
+ * a {@link org.kohsuke.args4j.OptionDef} object.
* @param setter
+ * a {@link org.kohsuke.args4j.spi.Setter} object.
*/
public PathTreeFilterHandler(final CmdLineParser parser,
final OptionDef option, final Setter<? super TreeFilter> setter) {
@@ -80,8 +50,8 @@ public class PathTreeFilterHandler extends OptionHandler<TreeFilter> {
}
@Override
- public int parseArguments(final Parameters params) throws CmdLineException {
- final List<PathFilter> filters = new ArrayList<PathFilter>();
+ public int parseArguments(Parameters params) throws CmdLineException {
+ final List<PathFilter> filters = new ArrayList<>();
for (int idx = 0;; idx++) {
final String path;
try {
@@ -92,7 +62,7 @@ public class PathTreeFilterHandler extends OptionHandler<TreeFilter> {
filters.add(PathFilter.create(path));
}
- if (filters.size() == 0)
+ if (filters.isEmpty())
return 0;
if (filters.size() == 1) {
setter.addValue(filters.get(0));
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RefSpecHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RefSpecHandler.java
index dae0c47642..0491445879 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RefSpecHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RefSpecHandler.java
@@ -1,59 +1,27 @@
/*
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.opt;
+import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.transport.RefSpec;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.OptionDef;
import org.kohsuke.args4j.spi.OptionHandler;
import org.kohsuke.args4j.spi.Parameters;
import org.kohsuke.args4j.spi.Setter;
-import org.eclipse.jgit.pgm.internal.CLIText;
-import org.eclipse.jgit.transport.RefSpec;
/**
- * Custom argument handler {@link RefSpec} from string values.
+ * Custom argument handler {@link org.eclipse.jgit.transport.RefSpec} from
+ * string values.
* <p>
* Assumes the parser has been initialized with a Repository.
*/
@@ -64,8 +32,11 @@ public class RefSpecHandler extends OptionHandler<RefSpec> {
* This constructor is used only by args4j.
*
* @param parser
+ * a {@link org.kohsuke.args4j.CmdLineParser} object.
* @param option
+ * a {@link org.kohsuke.args4j.OptionDef} object.
* @param setter
+ * a {@link org.kohsuke.args4j.spi.Setter} object.
*/
public RefSpecHandler(final CmdLineParser parser, final OptionDef option,
final Setter<? super RefSpec> setter) {
@@ -73,7 +44,7 @@ public class RefSpecHandler extends OptionHandler<RefSpec> {
}
@Override
- public int parseArguments(final Parameters params) throws CmdLineException {
+ public int parseArguments(Parameters params) throws CmdLineException {
setter.addValue(new RefSpec(params.getParameter(0)));
return 1;
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java
index b1be128db1..a095a28af8 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java
@@ -1,67 +1,34 @@
/*
* Copyright (C) 2009, Google Inc.
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.opt;
import java.io.IOException;
-import java.text.MessageFormat;
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-import org.kohsuke.args4j.OptionDef;
-import org.kohsuke.args4j.spi.OptionHandler;
-import org.kohsuke.args4j.spi.Parameters;
-import org.kohsuke.args4j.spi.Setter;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevFlag;
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.OptionDef;
+import org.kohsuke.args4j.spi.OptionHandler;
+import org.kohsuke.args4j.spi.Parameters;
+import org.kohsuke.args4j.spi.Setter;
/**
- * Custom argument handler {@link RevCommit} from string values.
+ * Custom argument handler {@link org.eclipse.jgit.revwalk.RevCommit} from
+ * string values.
* <p>
* Assumes the parser has been initialized with a Repository.
*/
@@ -74,8 +41,11 @@ public class RevCommitHandler extends OptionHandler<RevCommit> {
* This constructor is used only by args4j.
*
* @param parser
+ * a {@link org.kohsuke.args4j.CmdLineParser} object.
* @param option
+ * a {@link org.kohsuke.args4j.OptionDef} object.
* @param setter
+ * a {@link org.kohsuke.args4j.spi.Setter} object.
*/
public RevCommitHandler(final CmdLineParser parser, final OptionDef option,
final Setter<? super RevCommit> setter) {
@@ -84,7 +54,7 @@ public class RevCommitHandler extends OptionHandler<RevCommit> {
}
@Override
- public int parseArguments(final Parameters params) throws CmdLineException {
+ public int parseArguments(Parameters params) throws CmdLineException {
String name = params.getParameter(0);
boolean interesting = true;
@@ -96,8 +66,9 @@ public class RevCommitHandler extends OptionHandler<RevCommit> {
final int dot2 = name.indexOf(".."); //$NON-NLS-1$
if (dot2 != -1) {
if (!option.isMultiValued())
- throw new CmdLineException(MessageFormat.format(CLIText.get().onlyOneMetaVarExpectedIn
- , option.metaVar(), name));
+ throw new CmdLineException(clp,
+ CLIText.format(CLIText.get().onlyOneMetaVarExpectedIn),
+ option.metaVar(), name);
final String left = name.substring(0, dot2);
final String right = name.substring(dot2 + 2);
@@ -110,26 +81,30 @@ public class RevCommitHandler extends OptionHandler<RevCommit> {
return 1;
}
- private void addOne(final String name, final boolean interesting)
+ private void addOne(String name, boolean interesting)
throws CmdLineException {
final ObjectId id;
try {
id = clp.getRepository().resolve(name);
} catch (IOException e) {
- throw new CmdLineException(e.getMessage());
+ throw new CmdLineException(clp, CLIText.format(e.getMessage()));
}
if (id == null)
- throw new CmdLineException(MessageFormat.format(CLIText.get().notACommit, name));
+ throw new CmdLineException(clp,
+ CLIText.format(CLIText.get().notACommit), name);
final RevCommit c;
try {
c = clp.getRevWalk().parseCommit(id);
- } catch (MissingObjectException e) {
- throw new CmdLineException(MessageFormat.format(CLIText.get().notACommit, name));
- } catch (IncorrectObjectTypeException e) {
- throw new CmdLineException(MessageFormat.format(CLIText.get().notACommit, name));
+ } catch (MissingObjectException | IncorrectObjectTypeException e) {
+ CmdLineException cle = new CmdLineException(clp,
+ CLIText.format(CLIText.get().notACommit), name);
+ cle.initCause(e);
+ throw cle;
} catch (IOException e) {
- throw new CmdLineException(MessageFormat.format(CLIText.get().cannotReadBecause, name, e.getMessage()));
+ throw new CmdLineException(clp,
+ CLIText.format(CLIText.get().cannotReadBecause), name,
+ e.getMessage());
}
if (interesting)
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java
index eb155af9f4..08f1d28392 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java
@@ -1,66 +1,33 @@
/*
* Copyright (C) 2009, Google Inc.
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.opt;
import java.io.IOException;
-import java.text.MessageFormat;
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.revwalk.RevTree;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.OptionDef;
import org.kohsuke.args4j.spi.OptionHandler;
import org.kohsuke.args4j.spi.Parameters;
import org.kohsuke.args4j.spi.Setter;
-import org.eclipse.jgit.errors.IncorrectObjectTypeException;
-import org.eclipse.jgit.errors.MissingObjectException;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.pgm.internal.CLIText;
-import org.eclipse.jgit.revwalk.RevTree;
/**
- * Custom argument handler {@link RevTree} from string values.
+ * Custom argument handler {@link org.eclipse.jgit.revwalk.RevTree} from string
+ * values.
* <p>
* Assumes the parser has been initialized with a Repository.
*/
@@ -73,8 +40,11 @@ public class RevTreeHandler extends OptionHandler<RevTree> {
* This constructor is used only by args4j.
*
* @param parser
+ * a {@link org.kohsuke.args4j.CmdLineParser} object.
* @param option
+ * a {@link org.kohsuke.args4j.OptionDef} object.
* @param setter
+ * a {@link org.kohsuke.args4j.spi.Setter} object.
*/
public RevTreeHandler(final CmdLineParser parser, final OptionDef option,
final Setter<? super RevTree> setter) {
@@ -83,26 +53,30 @@ public class RevTreeHandler extends OptionHandler<RevTree> {
}
@Override
- public int parseArguments(final Parameters params) throws CmdLineException {
+ public int parseArguments(Parameters params) throws CmdLineException {
final String name = params.getParameter(0);
final ObjectId id;
try {
id = clp.getRepository().resolve(name);
} catch (IOException e) {
- throw new CmdLineException(e.getMessage());
+ throw new CmdLineException(clp, CLIText.format(e.getMessage()));
}
if (id == null)
- throw new CmdLineException(MessageFormat.format(CLIText.get().notATree, name));
+ throw new CmdLineException(clp,
+ CLIText.format(CLIText.get().notATree), name);
final RevTree c;
try {
c = clp.getRevWalk().parseTree(id);
- } catch (MissingObjectException e) {
- throw new CmdLineException(MessageFormat.format(CLIText.get().notATree, name));
- } catch (IncorrectObjectTypeException e) {
- throw new CmdLineException(MessageFormat.format(CLIText.get().notATree, name));
+ } catch (MissingObjectException | IncorrectObjectTypeException e) {
+ CmdLineException cle = new CmdLineException(clp,
+ CLIText.format(CLIText.get().notATree), name);
+ cle.initCause(e);
+ throw cle;
} catch (IOException e) {
- throw new CmdLineException(MessageFormat.format(CLIText.get().cannotReadBecause, name, e.getMessage()));
+ throw new CmdLineException(clp,
+ CLIText.format(CLIText.get().cannotReadBecause), name,
+ e.getMessage());
}
setter.addValue(c);
return 1;
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/SubcommandHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/SubcommandHandler.java
index c62ef0d2b8..e71ba90e4b 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/SubcommandHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/SubcommandHandler.java
@@ -1,89 +1,61 @@
/*
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.opt;
-import java.text.MessageFormat;
-
+import org.eclipse.jgit.pgm.CommandCatalog;
+import org.eclipse.jgit.pgm.CommandRef;
+import org.eclipse.jgit.pgm.TextBuiltin;
+import org.eclipse.jgit.pgm.internal.CLIText;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.OptionDef;
import org.kohsuke.args4j.spi.OptionHandler;
import org.kohsuke.args4j.spi.Parameters;
import org.kohsuke.args4j.spi.Setter;
-import org.eclipse.jgit.pgm.CommandCatalog;
-import org.eclipse.jgit.pgm.CommandRef;
-import org.eclipse.jgit.pgm.TextBuiltin;
-import org.eclipse.jgit.pgm.internal.CLIText;
/**
* Custom Argument handler for jgit command selection.
* <p>
- * Translates a single argument string to a {@link TextBuiltin} instance which
- * we can execute at runtime with the remaining arguments of the parser.
+ * Translates a single argument string to a
+ * {@link org.eclipse.jgit.pgm.TextBuiltin} instance which we can execute at
+ * runtime with the remaining arguments of the parser.
*/
public class SubcommandHandler extends OptionHandler<TextBuiltin> {
+ private final org.eclipse.jgit.pgm.opt.CmdLineParser clp;
+
/**
* Create a new handler for the command name.
* <p>
* This constructor is used only by args4j.
*
* @param parser
+ * a {@link org.kohsuke.args4j.CmdLineParser} object.
* @param option
+ * a {@link org.kohsuke.args4j.OptionDef} object.
* @param setter
+ * a {@link org.kohsuke.args4j.spi.Setter} object.
*/
public SubcommandHandler(final CmdLineParser parser,
final OptionDef option, final Setter<? super TextBuiltin> setter) {
super(parser, option, setter);
+ clp = (org.eclipse.jgit.pgm.opt.CmdLineParser) parser;
}
@Override
- public int parseArguments(final Parameters params) throws CmdLineException {
+ public int parseArguments(Parameters params) throws CmdLineException {
final String name = params.getParameter(0);
final CommandRef cr = CommandCatalog.get(name);
if (cr == null)
- throw new CmdLineException(MessageFormat.format(
- CLIText.get().notAJgitCommand, name));
+ throw new CmdLineException(clp,
+ CLIText.format(CLIText.get().notAJgitCommand), name);
// Force option parsing to stop. Everything after us should
// be arguments known only to this command and must not be
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/UntrackedFilesHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/UntrackedFilesHandler.java
index c4e8b05378..2f99cff768 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/UntrackedFilesHandler.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/UntrackedFilesHandler.java
@@ -1,47 +1,15 @@
/*
- * Copyright (C) 2015 Zend Technologies Ltd. and others
- * and other copyright owners as documented in the project's IP log.
+ * Copyright (C) 2015 Zend Technologies Ltd. and others and others
*
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
*
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.opt;
+import org.eclipse.jgit.pgm.internal.CLIText;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.OptionDef;
@@ -70,6 +38,8 @@ import org.kohsuke.args4j.spi.StringOptionHandler;
public class UntrackedFilesHandler extends StringOptionHandler {
/**
+ * <p>Constructor for UntrackedFilesHandler.</p>
+ *
* @param parser
* The parser to which this handler belongs to.
* @param option
@@ -102,8 +72,9 @@ public class UntrackedFilesHandler extends StringOptionHandler {
if ("no".equals(mode) || "all".equals(mode)) { //$NON-NLS-1$ //$NON-NLS-2$
setter.addValue(mode);
} else {
- throw new CmdLineException(owner, String.format(
- "Invalid untracked files mode '%s'", mode)); //$NON-NLS-1$
+ throw new CmdLineException(owner,
+ CLIText.format(CLIText.get().invalidUntrackedFilesMode),
+ mode);
}
return 1;
} else {
@@ -111,4 +82,4 @@ public class UntrackedFilesHandler extends StringOptionHandler {
}
}
-} \ No newline at end of file
+}