@@ -39,11 +39,9 @@ if (typeof window !== 'undefined') {
39
39
*/
40
40
export async function sparseCheckout (
41
41
repoUrl : string ,
42
- fullyQualifiedBranchName : string ,
42
+ commitHash : string ,
43
43
filesPaths : string [ ]
44
44
) {
45
- const refs = await listGitRefs ( repoUrl , fullyQualifiedBranchName ) ;
46
- const commitHash = refs [ fullyQualifiedBranchName ] ;
47
45
const treesIdx = await fetchWithoutBlobs ( repoUrl , commitHash ) ;
48
46
const objects = await resolveObjects ( treesIdx , commitHash , filesPaths ) ;
49
47
@@ -75,24 +73,24 @@ export type FileTreeFolder = {
75
73
} ;
76
74
export type FileTree = FileTreeFile | FileTreeFolder ;
77
75
76
+ export type GitRef = {
77
+ value : string ;
78
+ type ?: 'branch' | 'commit' | 'refname' | 'infer' ;
79
+ } ;
80
+
78
81
/**
79
82
* Lists all files in a git repository.
80
83
*
81
84
* See https://git-scm.com/book/en/v2/Git-Internals-Git-Objects for more information.
82
85
*
83
86
* @param repoUrl The URL of the git repository.
84
- * @param fullyQualifiedBranchName The full name of the branch to fetch from (e.g., 'refs/heads/main') .
87
+ * @param commitHash The commit hash to fetch from.
85
88
* @returns A list of all files in the repository.
86
89
*/
87
90
export async function listGitFiles (
88
91
repoUrl : string ,
89
- fullyQualifiedBranchName : string
92
+ commitHash : string
90
93
) : Promise < FileTree [ ] > {
91
- const refs = await listGitRefs ( repoUrl , fullyQualifiedBranchName ) ;
92
- if ( ! ( fullyQualifiedBranchName in refs ) ) {
93
- throw new Error ( `Branch ${ fullyQualifiedBranchName } not found` ) ;
94
- }
95
- const commitHash = refs [ fullyQualifiedBranchName ] ;
96
94
const treesIdx = await fetchWithoutBlobs ( repoUrl , commitHash ) ;
97
95
const rootTree = await resolveAllObjects ( treesIdx , commitHash ) ;
98
96
if ( ! rootTree ?. object ) {
@@ -102,6 +100,48 @@ export async function listGitFiles(
102
100
return gitTreeToFileTree ( rootTree ) ;
103
101
}
104
102
103
+ /**
104
+ * Resolves a ref description, e.g. a branch name, to a commit hash.
105
+ *
106
+ * @param repoUrl The URL of the git repository.
107
+ * @param ref The branch name or commit hash.
108
+ * @returns The commit hash.
109
+ */
110
+ export async function resolveCommitHash ( repoUrl : string , ref : GitRef ) {
111
+ if ( ref . type === 'infer' || ref . type === undefined ) {
112
+ if ( [ '' , 'HEAD' ] . includes ( ref . value ) ) {
113
+ ref = {
114
+ value : ref . value ,
115
+ type : 'refname' ,
116
+ } ;
117
+ } else if ( typeof ref . value === 'string' && ref . value . length === 40 ) {
118
+ ref = {
119
+ value : ref . value ,
120
+ type : 'commit' ,
121
+ } ;
122
+ }
123
+ }
124
+ if ( ref . type === 'branch' ) {
125
+ ref = {
126
+ value : `refs/heads/${ ref . value } ` ,
127
+ type : 'refname' ,
128
+ } ;
129
+ }
130
+ switch ( ref . type ) {
131
+ case 'commit' :
132
+ return ref . value ;
133
+ case 'refname' : {
134
+ const refs = await listGitRefs ( repoUrl , ref . value ) ;
135
+ if ( ! ( ref . value in refs ) ) {
136
+ throw new Error ( `Branch ${ ref . value } not found` ) ;
137
+ }
138
+ return refs [ ref . value ] ;
139
+ }
140
+ default :
141
+ throw new Error ( `Invalid ref type: ${ ref . type } ` ) ;
142
+ }
143
+ }
144
+
105
145
function gitTreeToFileTree ( tree : GitTree ) : FileTree [ ] {
106
146
return tree . object
107
147
. map ( ( branch ) => {
0 commit comments