@@ -15,7 +15,9 @@ import {
1515 setTree ,
1616 type TreeEntry ,
1717} from "../cache/tree"
18+ import CacheItem , { CacheType } from "../cache/item"
1819import { join } from "node:path"
20+ import { captureException } from "@sentry/node"
1921
2022/**
2123 * Convert to URL compatible path
@@ -271,6 +273,37 @@ async function cacheWorkerTrees(
271273 return result
272274}
273275
276+ /**
277+ * Resolve a git reference (branch, tag, or short commit hash) to a full commit hash.
278+ * @param datasetId The dataset ID.
279+ * @param treeish The git reference to resolve.
280+ * @returns The full commit hash.
281+ */
282+ export const resolveGitRef = async (
283+ datasetId : string ,
284+ treeish : string ,
285+ ) : Promise < string > => {
286+ const cache = new CacheItem ( redis , CacheType . gitRef , [ datasetId , treeish ] )
287+ return cache . get ( async ( ) => {
288+ const url = `http://${
289+ getDatasetWorker ( datasetId )
290+ } /datasets/${ datasetId } /refs/${ treeish } `
291+ const response = await fetch ( url )
292+ if ( ! response . ok ) {
293+ throw new Error (
294+ `Failed to resolve git reference ${ treeish } : ${ response . statusText } ` ,
295+ )
296+ }
297+ const data = await response . json ( )
298+ if ( ! data . hash ) {
299+ throw new Error (
300+ `Invalid response from datalad worker for git reference ${ treeish } ` ,
301+ )
302+ }
303+ return data . hash
304+ } )
305+ }
306+
274307/**
275308 * Get files for a specific revision (tree hash or commit hash).
276309 * Uses content-addressed caching keyed by full git hash.
@@ -279,6 +312,17 @@ export const getFiles = async (
279312 datasetId : string ,
280313 treeish : string ,
281314) : Promise < DatasetFile [ ] > => {
315+ // Guard against requests without a full git hash (40 = SHA-1, 64 = SHA-256)
316+ if ( treeish . length !== 40 && treeish . length !== 64 ) {
317+ try {
318+ treeish = await resolveGitRef ( datasetId , treeish )
319+ } catch ( error ) {
320+ captureException ( error , {
321+ tags : { datasetId, treeish, source : "resolveGitRef" } ,
322+ } )
323+ throw new Error ( `Invalid git reference: ${ treeish } ` )
324+ }
325+ }
282326 // Try cache first
283327 const cached = await getTree ( redis , treeish )
284328 if ( cached ) {
0 commit comments