@@ -5,7 +5,7 @@ import { Connection, PrismaClient, Repo, RepoToConnection, RepoIndexingStatus, S
55import { GithubConnectionConfig , GitlabConnectionConfig , GiteaConnectionConfig , BitbucketConnectionConfig } from '@sourcebot/schemas/v3/connection.type' ;
66import { AppContext , Settings , repoMetadataSchema } from "./types.js" ;
77import { getRepoPath , getTokenFromConfig , measure , getShardPrefix } from "./utils.js" ;
8- import { cloneRepository , fetchRepository , upsertGitConfig } from "./git.js" ;
8+ import { cloneRepository , fetchRepository , unsetGitConfig , upsertGitConfig } from "./git.js" ;
99import { existsSync , readdirSync , promises } from 'fs' ;
1010import { indexGitRepository } from "./zoekt.js" ;
1111import { PromClient } from './promClient.js' ;
@@ -237,12 +237,39 @@ export class RepoManager implements IRepoManager {
237237 await promises . rm ( repoPath , { recursive : true , force : true } ) ;
238238 }
239239
240+ const credentials = await this . getCloneCredentialsForRepo ( repo , this . db ) ;
241+ const remoteUrl = new URL ( repo . cloneUrl ) ;
242+ if ( credentials ) {
243+ // @note : URL has a weird behavior where if you set the password but
244+ // _not_ the username, the ":" delimiter will still be present in the
245+ // URL (e.g., https://:password@example.com). To get around this, if
246+ // we only have a password, we set the username to the password.
247+ // @see : https://www.typescriptlang.org/play/?#code/MYewdgzgLgBArgJwDYwLwzAUwO4wKoBKAMgBQBEAFlFAA4QBcA9I5gB4CGAtjUpgHShOZADQBKANwAoREj412ECNhAIAJmhhl5i5WrJTQkELz5IQAcxIy+UEAGUoCAJZhLo0UA
248+ if ( ! credentials . username ) {
249+ remoteUrl . username = credentials . password ;
250+ } else {
251+ remoteUrl . username = credentials . username ;
252+ remoteUrl . password = credentials . password ;
253+ }
254+ }
255+
240256 if ( existsSync ( repoPath ) && ! isReadOnly ) {
241- logger . info ( `Fetching ${ repo . displayName } ...` ) ;
257+ // @NOTE : in #483, we changed the cloning method s.t., we _no longer_
258+ // write the clone URL (which could contain a auth token) to the
259+ // `remote.origin.url` entry. For the upgrade scenario, we want
260+ // to unset this key since it is no longer needed, hence this line.
261+ // This will no-op if the key is already unset.
262+ // @see : https://github.com/sourcebot-dev/sourcebot/pull/483
263+ await unsetGitConfig ( repoPath , [ "remote.origin.url" ] ) ;
242264
243- const { durationMs } = await measure ( ( ) => fetchRepository ( repoPath , ( { method, stage, progress } ) => {
244- logger . debug ( `git.${ method } ${ stage } stage ${ progress } % complete for ${ repo . displayName } ` )
245- } ) ) ;
265+ logger . info ( `Fetching ${ repo . displayName } ...` ) ;
266+ const { durationMs } = await measure ( ( ) => fetchRepository (
267+ remoteUrl ,
268+ repoPath ,
269+ ( { method, stage, progress } ) => {
270+ logger . debug ( `git.${ method } ${ stage } stage ${ progress } % complete for ${ repo . displayName } ` )
271+ }
272+ ) ) ;
246273 const fetchDuration_s = durationMs / 1000 ;
247274
248275 process . stdout . write ( '\n' ) ;
@@ -251,25 +278,13 @@ export class RepoManager implements IRepoManager {
251278 } else if ( ! isReadOnly ) {
252279 logger . info ( `Cloning ${ repo . displayName } ...` ) ;
253280
254- const auth = await this . getCloneCredentialsForRepo ( repo , this . db ) ;
255- const cloneUrl = new URL ( repo . cloneUrl ) ;
256- if ( auth ) {
257- // @note : URL has a weird behavior where if you set the password but
258- // _not_ the username, the ":" delimiter will still be present in the
259- // URL (e.g., https://:password@example.com). To get around this, if
260- // we only have a password, we set the username to the password.
261- // @see : https://www.typescriptlang.org/play/?#code/MYewdgzgLgBArgJwDYwLwzAUwO4wKoBKAMgBQBEAFlFAA4QBcA9I5gB4CGAtjUpgHShOZADQBKANwAoREj412ECNhAIAJmhhl5i5WrJTQkELz5IQAcxIy+UEAGUoCAJZhLo0UA
262- if ( ! auth . username ) {
263- cloneUrl . username = auth . password ;
264- } else {
265- cloneUrl . username = auth . username ;
266- cloneUrl . password = auth . password ;
281+ const { durationMs } = await measure ( ( ) => cloneRepository (
282+ remoteUrl ,
283+ repoPath ,
284+ ( { method, stage, progress } ) => {
285+ logger . debug ( `git.${ method } ${ stage } stage ${ progress } % complete for ${ repo . displayName } ` )
267286 }
268- }
269-
270- const { durationMs } = await measure ( ( ) => cloneRepository ( cloneUrl . toString ( ) , repoPath , ( { method, stage, progress } ) => {
271- logger . debug ( `git.${ method } ${ stage } stage ${ progress } % complete for ${ repo . displayName } ` )
272- } ) ) ;
287+ ) ) ;
273288 const cloneDuration_s = durationMs / 1000 ;
274289
275290 process . stdout . write ( '\n' ) ;
@@ -540,7 +555,7 @@ export class RepoManager implements IRepoManager {
540555
541556 public async validateIndexedReposHaveShards ( ) {
542557 logger . info ( 'Validating indexed repos have shards...' ) ;
543-
558+
544559 const indexedRepos = await this . db . repo . findMany ( {
545560 where : {
546561 repoIndexingStatus : RepoIndexingStatus . INDEXED
@@ -556,7 +571,7 @@ export class RepoManager implements IRepoManager {
556571 const reposToReindex : number [ ] = [ ] ;
557572 for ( const repo of indexedRepos ) {
558573 const shardPrefix = getShardPrefix ( repo . orgId , repo . id ) ;
559-
574+
560575 // TODO: this doesn't take into account if a repo has multiple shards and only some of them are missing. To support that, this logic
561576 // would need to know how many total shards are expected for this repo
562577 let hasShards = false ;
0 commit comments