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