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 @Override
80 protected RefDatabase getRefDatabase() {
81 return refdb;
82 }
83
84 @Override
85 protected Repository getRepository() {
86 return refdb.getRepository();
87 }
88
89 @Override
90 protected boolean tryLock(boolean deref) throws IOException {
91 rw = new RevWalk(getRepository());
92 batch = new RefTreeBatch(refdb);
93 batch.init(rw);
94 oldRef = batch.exactRef(rw.getObjectReader(), getName());
95 if (oldRef != null && oldRef.getObjectId() != null) {
96 setOldObjectId(oldRef.getObjectId());
97 } else if (oldRef == null && getExpectedOldObjectId() != null) {
98 setOldObjectId(ObjectId.zeroId());
99 }
100 return true;
101 }
102
103 @Override
104 protected void unlock() {
105 batch = null;
106 if (rw != null) {
107 rw.close();
108 rw = null;
109 }
110 }
111
112 @Override
113 protected Result doUpdate(Result desiredResult) throws IOException {
114 return run(newRef(getName(), getNewObjectId()), desiredResult);
115 }
116
117 private Ref newRef(String name, ObjectId id)
118 throws MissingObjectException, IOException {
119 RevObject o = rw.parseAny(id);
120 if (o instanceof RevTag) {
121 RevObject p = rw.peel(o);
122 return new ObjectIdRef.PeeledTag(LOOSE, name, id, p.copy());
123 }
124 return new ObjectIdRef.PeeledNonTag(LOOSE, name, id);
125 }
126
127 @Override
128 protected Result doDelete(Result desiredResult) throws IOException {
129 return run(null, desiredResult);
130 }
131
132 @Override
133 protected Result doLink(String target) throws IOException {
134 Ref dst = new ObjectIdRef.Unpeeled(NEW, target, null);
135 SymbolicRef n = new SymbolicRef(getName(), dst);
136 Result desiredResult = getRef().getStorage() == NEW
137 ? Result.NEW
138 : Result.FORCED;
139 return run(n, desiredResult);
140 }
141
142 private Result run(@Nullable Ref newRef, Result desiredResult)
143 throws IOException {
144 Command c = new Command(oldRef, newRef);
145 batch.setRefLogIdent(getRefLogIdent());
146 batch.setRefLogMessage(getRefLogMessage(), isRefLogIncludingResult());
147 batch.execute(rw, Collections.singletonList(c));
148 return translate(c.getResult(), desiredResult);
149 }
150
151 static Result translate(ReceiveCommand.Result r, Result desiredResult) {
152 switch (r) {
153 case OK:
154 return desiredResult;
155
156 case LOCK_FAILURE:
157 return Result.LOCK_FAILURE;
158
159 case NOT_ATTEMPTED:
160 return Result.NOT_ATTEMPTED;
161
162 case REJECTED_MISSING_OBJECT:
163 return Result.IO_FAILURE;
164
165 case REJECTED_CURRENT_BRANCH:
166 return Result.REJECTED_CURRENT_BRANCH;
167
168 case REJECTED_OTHER_REASON:
169 case REJECTED_NOCREATE:
170 case REJECTED_NODELETE:
171 case REJECTED_NONFASTFORWARD:
172 default:
173 return Result.REJECTED;
174 }
175 }
176 }