gip-remote 1.2.5 → 1.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +35 -4
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -210,9 +210,26 @@ class Remote extends ReadyResource {
|
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
// 4b. Insert file records
|
|
214
|
-
//
|
|
213
|
+
// 4b. Insert/update file records — but ONLY for paths whose blob or mode
|
|
214
|
+
// actually changed. Earlier versions blindly upserted every file in
|
|
215
|
+
// the new tree on every push, which overwrote the commit metadata of
|
|
216
|
+
// untouched files with HEAD's author/message/timestamp. The visible
|
|
217
|
+
// symptom: a tree view shows every file as "last modified by the
|
|
218
|
+
// latest commit", so per-file timestamps become useless.
|
|
219
|
+
//
|
|
220
|
+
// Skipping unchanged rows preserves the metadata of the commit that
|
|
221
|
+
// last *actually* modified the file. New paths and modified paths
|
|
222
|
+
// still take the current commit's metadata as before.
|
|
215
223
|
for (const file of files) {
|
|
224
|
+
const existing = await this._db.get('@gip/files', {
|
|
225
|
+
branch: refName,
|
|
226
|
+
path: file.path
|
|
227
|
+
})
|
|
228
|
+
if (existing && existing.oid === file.oid && existing.mode === file.mode) {
|
|
229
|
+
// Same blob, same mode → file is unchanged in this commit. Leave
|
|
230
|
+
// the existing row untouched so its commit metadata stays accurate.
|
|
231
|
+
continue
|
|
232
|
+
}
|
|
216
233
|
await this._db.insert('@gip/files', {
|
|
217
234
|
branch: refName,
|
|
218
235
|
path: file.path,
|
|
@@ -241,7 +258,21 @@ class Remote extends ReadyResource {
|
|
|
241
258
|
objects: [...objects.keys()]
|
|
242
259
|
})
|
|
243
260
|
} else {
|
|
244
|
-
// 5b. Insert branch record
|
|
261
|
+
// 5b. Insert/update branch record.
|
|
262
|
+
//
|
|
263
|
+
// `objects` is the denormalized "everything reachable from this branch"
|
|
264
|
+
// set used by getRefObjects() at fetch time. CRITICAL: we must MERGE
|
|
265
|
+
// with the prior record's objects, not overwrite. A real git client
|
|
266
|
+
// sends a thin pack on follow-up pushes (only the new objects), so
|
|
267
|
+
// `objects.keys()` here would be e.g. just {commit B, new tree} —
|
|
268
|
+
// commit A and its tree from the previous push would be dropped from
|
|
269
|
+
// the list, and a fresh clone calling getRefObjects(headOfB) would be
|
|
270
|
+
// missing every parent commit. That's the "I cloned and lost a
|
|
271
|
+
// commit" symptom.
|
|
272
|
+
const prev = await this._db.get('@gip/branches', { name: refName })
|
|
273
|
+
const merged = new Set(prev ? prev.objects : [])
|
|
274
|
+
for (const k of objects.keys()) merged.add(k)
|
|
275
|
+
|
|
245
276
|
await this._db.insert('@gip/branches', {
|
|
246
277
|
name: refName,
|
|
247
278
|
commitOid: oid,
|
|
@@ -249,7 +280,7 @@ class Remote extends ReadyResource {
|
|
|
249
280
|
author: commit.author,
|
|
250
281
|
message: commit.message,
|
|
251
282
|
timestamp: commit.timestamp,
|
|
252
|
-
objects: [...
|
|
283
|
+
objects: [...merged]
|
|
253
284
|
})
|
|
254
285
|
|
|
255
286
|
// 6. Set HEAD to first branch pushed (like git init)
|