1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.internal.storage.reftree;
12
13 import static org.eclipse.jgit.lib.Ref.Storage.LOOSE;
14 import static org.eclipse.jgit.lib.Ref.Storage.NEW;
15
16 import java.io.IOException;
17 import java.util.Collections;
18
19 import org.eclipse.jgit.annotations.Nullable;
20 import org.eclipse.jgit.errors.MissingObjectException;
21 import org.eclipse.jgit.lib.ObjectId;
22 import org.eclipse.jgit.lib.ObjectIdRef;
23 import org.eclipse.jgit.lib.Ref;
24 import org.eclipse.jgit.lib.RefDatabase;
25 import org.eclipse.jgit.lib.RefUpdate;
26 import org.eclipse.jgit.lib.Repository;
27 import org.eclipse.jgit.lib.SymbolicRef;
28 import org.eclipse.jgit.revwalk.RevObject;
29 import org.eclipse.jgit.revwalk.RevTag;
30 import org.eclipse.jgit.revwalk.RevWalk;
31 import org.eclipse.jgit.transport.ReceiveCommand;
32
33
34 class RefTreeUpdate extends RefUpdate {
35 private final RefTreeDatabase refdb;
36 private RevWalk rw;
37 private RefTreeBatch batch;
38 private Ref oldRef;
39
40 RefTreeUpdate(RefTreeDatabase refdb, Ref ref) {
41 super(ref);
42 this.refdb = refdb;
43 setCheckConflicting(false);
44 }
45
46
47 @Override
48 protected RefDatabase getRefDatabase() {
49 return refdb;
50 }
51
52
53 @Override
54 protected Repository getRepository() {
55 return refdb.getRepository();
56 }
57
58
59 @Override
60 protected boolean tryLock(boolean deref) throws IOException {
61 rw = new RevWalk(getRepository());
62 batch = new RefTreeBatch(refdb);
63 batch.init(rw);
64 oldRef = batch.exactRef(rw.getObjectReader(), getName());
65 if (oldRef != null && oldRef.getObjectId() != null) {
66 setOldObjectId(oldRef.getObjectId());
67 } else if (oldRef == null && getExpectedOldObjectId() != null) {
68 setOldObjectId(ObjectId.zeroId());
69 }
70 return true;
71 }
72
73
74 @Override
75 protected void unlock() {
76 batch = null;
77 if (rw != null) {
78 rw.close();
79 rw = null;
80 }
81 }
82
83
84 @Override
85 protected Result doUpdate(Result desiredResult) throws IOException {
86 return run(newRef(getName(), getNewObjectId()), desiredResult);
87 }
88
89 private Ref newRef(String name, ObjectId id)
90 throws MissingObjectException, IOException {
91 RevObject o = rw.parseAny(id);
92 if (o instanceof RevTag) {
93 RevObject p = rw.peel(o);
94 return new ObjectIdRef.PeeledTag(LOOSE, name, id, p.copy());
95 }
96 return new ObjectIdRef.PeeledNonTag(LOOSE, name, id);
97 }
98
99
100 @Override
101 protected Result doDelete(Result desiredResult) throws IOException {
102 return run(null, desiredResult);
103 }
104
105
106 @Override
107 protected Result doLink(String target) throws IOException {
108 Ref dst = new ObjectIdRef.Unpeeled(NEW, target, null);
109 SymbolicRef n = new SymbolicRef(getName(), dst);
110 Result desiredResult = getRef().getStorage() == NEW
111 ? Result.NEW
112 : Result.FORCED;
113 return run(n, desiredResult);
114 }
115
116 private Result run(@Nullable Ref newRef, Result desiredResult)
117 throws IOException {
118 Command c = new Command(oldRef, newRef);
119 batch.setRefLogIdent(getRefLogIdent());
120 batch.setRefLogMessage(getRefLogMessage(), isRefLogIncludingResult());
121 batch.execute(rw, Collections.singletonList(c));
122 return translate(c.getResult(), desiredResult);
123 }
124
125 static Result translate(ReceiveCommand.Result r, Result desiredResult) {
126 switch (r) {
127 case OK:
128 return desiredResult;
129
130 case LOCK_FAILURE:
131 return Result.LOCK_FAILURE;
132
133 case NOT_ATTEMPTED:
134 return Result.NOT_ATTEMPTED;
135
136 case REJECTED_MISSING_OBJECT:
137 return Result.IO_FAILURE;
138
139 case REJECTED_CURRENT_BRANCH:
140 return Result.REJECTED_CURRENT_BRANCH;
141
142 case REJECTED_OTHER_REASON:
143 case REJECTED_NOCREATE:
144 case REJECTED_NODELETE:
145 case REJECTED_NONFASTFORWARD:
146 default:
147 return Result.REJECTED;
148 }
149 }
150 }