You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Tag.java 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com>
  3. * Copyright (C) 2009, Google Inc.
  4. * Copyright (C) 2008, Charles O'Farrell <charleso@charleso.org>
  5. * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg.lists@dewire.com>
  6. * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
  7. * Copyright (C) 2008, 2021 Shawn O. Pearce <spearce@spearce.org> and others
  8. *
  9. * This program and the accompanying materials are made available under the
  10. * terms of the Eclipse Distribution License v. 1.0 which is available at
  11. * https://www.eclipse.org/org/documents/edl-v10.php.
  12. *
  13. * SPDX-License-Identifier: BSD-3-Clause
  14. */
  15. package org.eclipse.jgit.pgm;
  16. import java.io.IOException;
  17. import java.text.MessageFormat;
  18. import java.util.List;
  19. import org.eclipse.jgit.api.Git;
  20. import org.eclipse.jgit.api.ListTagCommand;
  21. import org.eclipse.jgit.api.TagCommand;
  22. import org.eclipse.jgit.api.VerificationResult;
  23. import org.eclipse.jgit.api.VerifySignatureCommand;
  24. import org.eclipse.jgit.api.errors.GitAPIException;
  25. import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
  26. import org.eclipse.jgit.lib.Constants;
  27. import org.eclipse.jgit.lib.GpgSignatureVerifier.SignatureVerification;
  28. import org.eclipse.jgit.lib.ObjectId;
  29. import org.eclipse.jgit.lib.Ref;
  30. import org.eclipse.jgit.lib.Repository;
  31. import org.eclipse.jgit.pgm.internal.CLIText;
  32. import org.eclipse.jgit.pgm.internal.VerificationUtils;
  33. import org.eclipse.jgit.revwalk.RevTag;
  34. import org.eclipse.jgit.revwalk.RevWalk;
  35. import org.kohsuke.args4j.Argument;
  36. import org.kohsuke.args4j.Option;
  37. @Command(common = true, usage = "usage_CreateATag")
  38. class Tag extends TextBuiltin {
  39. @Option(name = "--force", aliases = { "-f" }, forbids = { "--delete",
  40. "--verify" }, usage = "usage_forceReplacingAnExistingTag")
  41. private boolean force;
  42. @Option(name = "--delete", aliases = { "-d" }, forbids = {
  43. "--verify" }, usage = "usage_tagDelete")
  44. private boolean delete;
  45. @Option(name = "--annotate", aliases = {
  46. "-a" }, forbids = { "--delete",
  47. "--verify" }, usage = "usage_tagAnnotated")
  48. private boolean annotated;
  49. @Option(name = "-m", forbids = { "--delete",
  50. "--verify" }, metaVar = "metaVar_message", usage = "usage_tagMessage")
  51. private String message;
  52. @Option(name = "--sign", aliases = { "-s" }, forbids = {
  53. "--no-sign", "--delete", "--verify" }, usage = "usage_tagSign")
  54. private boolean sign;
  55. @Option(name = "--no-sign", usage = "usage_tagNoSign", forbids = {
  56. "--sign", "--delete", "--verify" })
  57. private boolean noSign;
  58. @Option(name = "--local-user", aliases = {
  59. "-u" }, forbids = { "--delete",
  60. "--verify" }, metaVar = "metaVar_tagLocalUser", usage = "usage_tagLocalUser")
  61. private String gpgKeyId;
  62. @Option(name = "--verify", aliases = { "-v" }, forbids = { "--delete",
  63. "--force", "--annotate", "-m", "--sign", "--no-sign",
  64. "--local-user" }, usage = "usage_tagVerify")
  65. private boolean verify;
  66. @Argument(index = 0, metaVar = "metaVar_name")
  67. private String tagName;
  68. @Argument(index = 1, metaVar = "metaVar_object")
  69. private ObjectId object;
  70. /** {@inheritDoc} */
  71. @Override
  72. protected void run() {
  73. try (Git git = new Git(db)) {
  74. if (tagName != null) {
  75. if (verify) {
  76. VerifySignatureCommand verifySig = git.verifySignature()
  77. .setMode(VerifySignatureCommand.VerifyMode.TAGS)
  78. .addName(tagName);
  79. VerificationResult verification = verifySig.call()
  80. .get(tagName);
  81. if (verification == null) {
  82. showUnsigned(git, tagName);
  83. } else {
  84. Throwable error = verification.getException();
  85. if (error != null) {
  86. throw die(error.getMessage(), error);
  87. }
  88. writeVerification(verifySig.getVerifier().getName(),
  89. (RevTag) verification.getObject(),
  90. verification.getVerification());
  91. }
  92. } else if (delete) {
  93. List<String> deletedTags = git.tagDelete().setTags(tagName)
  94. .call();
  95. if (deletedTags.isEmpty()) {
  96. throw die(MessageFormat
  97. .format(CLIText.get().tagNotFound, tagName));
  98. }
  99. } else {
  100. TagCommand command = git.tag().setForceUpdate(force)
  101. .setMessage(message).setName(tagName);
  102. if (object != null) {
  103. try (RevWalk walk = new RevWalk(db)) {
  104. command.setObjectId(walk.parseAny(object));
  105. }
  106. }
  107. if (noSign) {
  108. command.setSigned(false);
  109. } else if (sign) {
  110. command.setSigned(true);
  111. }
  112. if (annotated) {
  113. command.setAnnotated(true);
  114. } else if (message == null && !sign && gpgKeyId == null) {
  115. // None of -a, -m, -s, -u given
  116. command.setAnnotated(false);
  117. }
  118. command.setSigningKey(gpgKeyId);
  119. try {
  120. command.call();
  121. } catch (RefAlreadyExistsException e) {
  122. throw die(MessageFormat.format(
  123. CLIText.get().tagAlreadyExists, tagName), e);
  124. }
  125. }
  126. } else {
  127. ListTagCommand command = git.tagList();
  128. List<Ref> list = command.call();
  129. for (Ref ref : list) {
  130. outw.println(Repository.shortenRefName(ref.getName()));
  131. }
  132. }
  133. } catch (GitAPIException | IOException e) {
  134. throw die(e.getMessage(), e);
  135. }
  136. }
  137. private void showUnsigned(Git git, String wantedTag) throws IOException {
  138. ObjectId id = git.getRepository().resolve(wantedTag);
  139. if (id != null && !ObjectId.zeroId().equals(id)) {
  140. try (RevWalk walk = new RevWalk(git.getRepository())) {
  141. showTag(walk.parseTag(id));
  142. }
  143. } else {
  144. throw die(
  145. MessageFormat.format(CLIText.get().tagNotFound, wantedTag));
  146. }
  147. }
  148. private void showTag(RevTag tag) throws IOException {
  149. outw.println("object " + tag.getObject().name()); //$NON-NLS-1$
  150. outw.println("type " + Constants.typeString(tag.getObject().getType())); //$NON-NLS-1$
  151. outw.println("tag " + tag.getTagName()); //$NON-NLS-1$
  152. outw.println("tagger " + tag.getTaggerIdent().toExternalString()); //$NON-NLS-1$
  153. outw.println();
  154. outw.print(tag.getFullMessage());
  155. }
  156. private void writeVerification(String name, RevTag tag,
  157. SignatureVerification verification) throws IOException {
  158. showTag(tag);
  159. if (verification == null) {
  160. outw.println();
  161. return;
  162. }
  163. VerificationUtils.writeVerification(outw, verification, name,
  164. tag.getTaggerIdent());
  165. }
  166. }