Skip to content

Commit

Permalink
feat: ✨ add shallowClone method to GitClient
Browse files Browse the repository at this point in the history
  • Loading branch information
pelikhan committed Jan 6, 2025
1 parent 297e848 commit 74f94b5
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 2 deletions.
55 changes: 53 additions & 2 deletions packages/core/src/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import { GIT_DIFF_MAX_TOKENS, GIT_IGNORE_GENAI } from "./constants"
import { llmifyDiff } from "./diff"
import { resolveFileContents } from "./file"
import { readText } from "./fs"
import { runtimeHost } from "./host"
import { host, runtimeHost } from "./host"
import { shellParse } from "./shell"
import { arrayify } from "./util"
import { arrayify, dotGenaiscriptPath } from "./util"
import { estimateTokens, truncateTextToTokens } from "./tokens"
import { resolveTokenEncoder } from "./encoders"
import { underscore } from "inflection"
import { existsSync } from "node:fs"

/**
* GitClient class provides an interface to interact with Git.
Expand Down Expand Up @@ -93,6 +95,7 @@ export class GitClient implements Git {
Array.isArray(args) ? args : shellParse(args),
opts
)
if (res.exitCode !== 0) throw new Error(res.stderr)
return res.stdout
}

Expand Down Expand Up @@ -328,6 +331,54 @@ ${await this.diff({ ...options, nameOnly: true })}
return res
}

/**
* Create a shallow git clone
* @param repository URL of the remote repository
* @param options various clone options
*/
async shallowClone(
repository: string,
options?: {
/**
* Brnach to clone
*/
branch?: string
}
): Promise<string> {
let { branch, ...rest } = options || {}

// normalize short github url
if (/^\w+\/\w+$/.test(repository)) {
repository = `https://github.com/${repository}`
}
const url = new URL(repository)
const sha = (
await this.exec(["ls-remote", repository, branch || "HEAD"])
).split(/\s+/)[0]
let directory = dotGenaiscriptPath(
"git",
url.pathname
.split(/\//g)
.filter((s) => !!s)
.join("-"),
branch || `HEAD`,
sha
)
if (branch) directory = host.path.join(directory, branch)
if (existsSync(directory)) return directory

const args = ["clone", "--depth=1"]
if (branch) args.push("--branch", branch)
Object.entries(rest).forEach(([k, v]) =>
args.push(
v === true ? `--${underscore(k)}` : `--${underscore(k)}=${v}`
)
)
args.push(repository, directory)
await this.exec(args)
return directory
}

client(cwd: string) {
return new GitClient(cwd)
}
Expand Down
16 changes: 16 additions & 0 deletions packages/core/src/types/prompt_template.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1841,6 +1841,22 @@ interface Git {
excludedPaths?: ElementOrArray<string>
}): Promise<GitCommit[]>

/**
* Create a shallow git clone
* @param repository URL of the remote repository
* @param options various clone options
* @returns the path to the cloned repository
*/
async shallowClone(
repository: string,
options?: {
/**
* Brnach to clone
*/
branch?: string
}
): Promise<string>

/**
* Open a git client on a different directory
* @param cwd working directory
Expand Down
5 changes: 5 additions & 0 deletions packages/sample/genaisrc/git.genai.mts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,8 @@ for (const commit of log.slice(0, 10)) {

const client = git.client(".")
console.log({ log: await client.log() })

const clone = await git.shallowClone("microsoft/genaiscript")
const cachedClone = await git.shallowClone("microsoft/genaiscript")
console.log({ clone, cachedClone })
if (clone !== cachedClone) throw new Error("Clones should be cached")

0 comments on commit 74f94b5

Please sign in to comment.