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.

RefTreeUpdate.java 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * Copyright (C) 2016, Google Inc. and others
  3. *
  4. * This program and the accompanying materials are made available under the
  5. * terms of the Eclipse Distribution License v. 1.0 which is available at
  6. * https://www.eclipse.org/org/documents/edl-v10.php.
  7. *
  8. * SPDX-License-Identifier: BSD-3-Clause
  9. */
  10. package org.eclipse.jgit.internal.storage.reftree;
  11. import static org.eclipse.jgit.lib.Ref.Storage.LOOSE;
  12. import static org.eclipse.jgit.lib.Ref.Storage.NEW;
  13. import java.io.IOException;
  14. import java.util.Collections;
  15. import org.eclipse.jgit.annotations.Nullable;
  16. import org.eclipse.jgit.errors.MissingObjectException;
  17. import org.eclipse.jgit.lib.ObjectId;
  18. import org.eclipse.jgit.lib.ObjectIdRef;
  19. import org.eclipse.jgit.lib.Ref;
  20. import org.eclipse.jgit.lib.RefDatabase;
  21. import org.eclipse.jgit.lib.RefUpdate;
  22. import org.eclipse.jgit.lib.Repository;
  23. import org.eclipse.jgit.lib.SymbolicRef;
  24. import org.eclipse.jgit.revwalk.RevObject;
  25. import org.eclipse.jgit.revwalk.RevTag;
  26. import org.eclipse.jgit.revwalk.RevWalk;
  27. import org.eclipse.jgit.transport.ReceiveCommand;
  28. /** Single reference update to {@link RefTreeDatabase}. */
  29. class RefTreeUpdate extends RefUpdate {
  30. private final RefTreeDatabase refdb;
  31. private RevWalk rw;
  32. private RefTreeBatch batch;
  33. private Ref oldRef;
  34. RefTreeUpdate(RefTreeDatabase refdb, Ref ref) {
  35. super(ref);
  36. this.refdb = refdb;
  37. setCheckConflicting(false); // Done automatically by doUpdate.
  38. }
  39. /** {@inheritDoc} */
  40. @Override
  41. protected RefDatabase getRefDatabase() {
  42. return refdb;
  43. }
  44. /** {@inheritDoc} */
  45. @Override
  46. protected Repository getRepository() {
  47. return refdb.getRepository();
  48. }
  49. /** {@inheritDoc} */
  50. @Override
  51. protected boolean tryLock(boolean deref) throws IOException {
  52. rw = new RevWalk(getRepository());
  53. batch = new RefTreeBatch(refdb);
  54. batch.init(rw);
  55. oldRef = batch.exactRef(rw.getObjectReader(), getName());
  56. if (oldRef != null && oldRef.getObjectId() != null) {
  57. setOldObjectId(oldRef.getObjectId());
  58. } else if (oldRef == null && getExpectedOldObjectId() != null) {
  59. setOldObjectId(ObjectId.zeroId());
  60. }
  61. return true;
  62. }
  63. /** {@inheritDoc} */
  64. @Override
  65. protected void unlock() {
  66. batch = null;
  67. if (rw != null) {
  68. rw.close();
  69. rw = null;
  70. }
  71. }
  72. /** {@inheritDoc} */
  73. @Override
  74. protected Result doUpdate(Result desiredResult) throws IOException {
  75. return run(newRef(getName(), getNewObjectId()), desiredResult);
  76. }
  77. private Ref newRef(String name, ObjectId id)
  78. throws MissingObjectException, IOException {
  79. RevObject o = rw.parseAny(id);
  80. if (o instanceof RevTag) {
  81. RevObject p = rw.peel(o);
  82. return new ObjectIdRef.PeeledTag(LOOSE, name, id, p.copy());
  83. }
  84. return new ObjectIdRef.PeeledNonTag(LOOSE, name, id);
  85. }
  86. /** {@inheritDoc} */
  87. @Override
  88. protected Result doDelete(Result desiredResult) throws IOException {
  89. return run(null, desiredResult);
  90. }
  91. /** {@inheritDoc} */
  92. @Override
  93. protected Result doLink(String target) throws IOException {
  94. Ref dst = new ObjectIdRef.Unpeeled(NEW, target, null);
  95. SymbolicRef n = new SymbolicRef(getName(), dst);
  96. Result desiredResult = getRef().getStorage() == NEW
  97. ? Result.NEW
  98. : Result.FORCED;
  99. return run(n, desiredResult);
  100. }
  101. private Result run(@Nullable Ref newRef, Result desiredResult)
  102. throws IOException {
  103. Command c = new Command(oldRef, newRef);
  104. batch.setRefLogIdent(getRefLogIdent());
  105. batch.setRefLogMessage(getRefLogMessage(), isRefLogIncludingResult());
  106. batch.execute(rw, Collections.singletonList(c));
  107. return translate(c.getResult(), desiredResult);
  108. }
  109. static Result translate(ReceiveCommand.Result r, Result desiredResult) {
  110. switch (r) {
  111. case OK:
  112. return desiredResult;
  113. case LOCK_FAILURE:
  114. return Result.LOCK_FAILURE;
  115. case NOT_ATTEMPTED:
  116. return Result.NOT_ATTEMPTED;
  117. case REJECTED_MISSING_OBJECT:
  118. return Result.IO_FAILURE;
  119. case REJECTED_CURRENT_BRANCH:
  120. return Result.REJECTED_CURRENT_BRANCH;
  121. case REJECTED_OTHER_REASON:
  122. case REJECTED_NOCREATE:
  123. case REJECTED_NODELETE:
  124. case REJECTED_NONFASTFORWARD:
  125. default:
  126. return Result.REJECTED;
  127. }
  128. }
  129. }