git-er-done 0.1.18 → 0.1.19

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/README.md CHANGED
@@ -22,6 +22,8 @@ const GIT_COMMIT_REF = '9f63b23ec99e36a176d73909fc67a39dc3bd56b7'
22
22
 
23
23
  gitDetails({
24
24
  base: GIT_COMMIT_REF,
25
+ // Optional: specify working directory (defaults to process.cwd())
26
+ // cwd: '/path/to/repo'
25
27
  }).then((git) => {
26
28
  /* git data returns
27
29
  {
@@ -63,6 +65,38 @@ console.log('Created files:', git.createdFiles)
63
65
  console.log('Deleted files:', git.deletedFiles)
64
66
  ```
65
67
 
68
+ ### Running from a Different Directory
69
+
70
+ All functions support a `cwd` option to run git commands in a different directory:
71
+
72
+ ```js
73
+ const { gitDetails, getCurrentBranch, getLastCommit } = require('git-er-done')
74
+
75
+ // Run git commands in a different repo
76
+ const git = await gitDetails({
77
+ base: 'main',
78
+ cwd: '/path/to/other/repo'
79
+ })
80
+
81
+ const branch = await getCurrentBranch({ cwd: '/path/to/other/repo' })
82
+ const lastCommit = await getLastCommit({ cwd: '/path/to/other/repo' })
83
+ ```
84
+
85
+ ### Comparing Against Uncommitted Changes
86
+
87
+ Use `includeWorkingChanges` to compare against uncommitted changes in the working directory:
88
+
89
+ ```js
90
+ const { gitDetails } = require('git-er-done')
91
+
92
+ const git = await gitDetails({
93
+ base: 'main',
94
+ includeWorkingChanges: true
95
+ })
96
+
97
+ console.log('Uncommitted changes:', git.modifiedFiles)
98
+ ```
99
+
66
100
  ### Getting Lines of Code Changed
67
101
 
68
102
  ```js
@@ -210,6 +244,21 @@ const { getGitRoot } = require('git-er-done')
210
244
 
211
245
  const root = await getGitRoot()
212
246
  console.log('Git root:', root) // '/Users/you/your-repo'
247
+
248
+ // With cwd option
249
+ const otherRoot = await getGitRoot('/path/to/other/repo')
250
+ ```
251
+
252
+ ### Getting Current Branch
253
+
254
+ ```js
255
+ const { getCurrentBranch } = require('git-er-done')
256
+
257
+ const branch = await getCurrentBranch()
258
+ console.log('Current branch:', branch) // 'main'
259
+
260
+ // With cwd option
261
+ const otherBranch = await getCurrentBranch({ cwd: '/path/to/other/repo' })
213
262
  ```
214
263
 
215
264
  ### Getting File Contents at a Specific Commit
@@ -260,10 +309,12 @@ const { getFirstCommit } = require('git-er-done/get-first-commit')
260
309
  const { getLastCommit } = require('git-er-done/get-last-commit')
261
310
  const { gitDetails } = require('git-er-done/get-details')
262
311
  const { getGitRoot } = require('git-er-done/get-root')
312
+ const { getCurrentBranch } = require('git-er-done/get-current-branch')
263
313
  const { getGitFiles } = require('git-er-done/get-files')
264
314
  const { getFileAtCommit } = require('git-er-done/get-file-at-commit')
265
315
  const { getFileDates, getFileModifiedTimeStamp, getFileCreatedTimeStamp } = require('git-er-done/get-file-dates')
266
316
  const { getRemotes, getRemote } = require('git-er-done/get-remotes')
317
+ const { getFormattedDiff } = require('git-er-done/get-diff-formatted')
267
318
  ```
268
319
 
269
320
  ## Examples
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-er-done",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "Utility for dealing with modified, created, deleted files since a git commit",
5
5
  "main": "src/index.js",
6
6
  "types": "types/index.d.ts",
@@ -8,6 +8,8 @@ const { gitDetails } = require('../getDetails')
8
8
 
9
9
  /**
10
10
  * Gets all commits in the repository from first to last
11
+ * @param {Object} [options] - Options
12
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
11
13
  * @returns {Promise<CommitInfo[]>} Promise that resolves to array of all commits in chronological order
12
14
  * @example
13
15
  * const commits = await getAllCommits()
@@ -15,16 +17,17 @@ const { gitDetails } = require('../getDetails')
15
17
  * console.log(`${commit.sha}: ${commit.subject}`)
16
18
  * })
17
19
  */
18
- async function getAllCommits() {
19
- const firstCommit = await getFirstCommit()
20
+ async function getAllCommits(options) {
21
+ const firstCommit = await getFirstCommit(options)
20
22
  // console.log('firstCommit', firstCommit)
21
- const lastCommit = await getLastCommit()
23
+ const lastCommit = await getLastCommit(options)
22
24
  // console.log('lastCommit', lastCommit)
23
25
  const data = await gitDetails({
24
26
  // base === now
25
27
  base: lastCommit.sha,
26
28
  // head == start
27
- head: firstCommit.sha
29
+ head: firstCommit.sha,
30
+ cwd: options && options.cwd
28
31
  })
29
32
  // console.log('data.commits', data.commits.reverse())
30
33
  // process.exit(1)
@@ -8,18 +8,21 @@ const { spawn } = require('child_process')
8
8
  /**
9
9
  * Gets the hash of the first commit in the repository
10
10
  * Uses git rev-list to find the initial commit with no parents
11
+ * @param {Object} [options] - Options
12
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
11
13
  * @returns {Promise<string>} Promise that resolves to the SHA hash of the first commit
12
14
  * @throws {Error} Throws if git command fails or if not in a git repository
13
15
  * @example
14
16
  * const hash = await getFirstCommitHash()
15
17
  * // Returns: 'a1b2c3d4e5f6...' (40-character SHA-1 hash)
16
18
  */
17
- function getFirstCommitHash() {
19
+ function getFirstCommitHash(options) {
18
20
  return new Promise((resolve, reject) => {
19
21
  // git rev-list --max-parents=0 HEAD
20
22
  let stdout = ''
21
23
  const args = ['rev-list', '--max-parents=0', 'HEAD', '--reverse']
22
- const child = spawn('git', args, { env: process.env })
24
+ const cwd = (options && options.cwd) || process.cwd()
25
+ const child = spawn('git', args, { env: process.env, cwd })
23
26
  child.stdout.on('data', chunk => {
24
27
  stdout += chunk
25
28
  })
@@ -34,6 +37,8 @@ function getFirstCommitHash() {
34
37
 
35
38
  /**
36
39
  * Gets detailed information about the first commit in the repository
40
+ * @param {Object} [options] - Options
41
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
37
42
  * @returns {Promise<CommitInfo>} Promise that resolves to commit details object containing SHA, author, committer, message, branch, and tags
38
43
  * @throws {Error} Throws if git command fails or if not in a git repository
39
44
  * @example
@@ -42,9 +47,10 @@ function getFirstCommitHash() {
42
47
  * console.log('Author:', firstCommit.author.name)
43
48
  * console.log('SHA:', firstCommit.sha)
44
49
  */
45
- async function getFirstCommit() {
46
- const hash = await getFirstCommitHash()
47
- return getCommit(hash)
50
+ async function getFirstCommit(options) {
51
+ const hash = await getFirstCommitHash(options)
52
+ const opts = options ? { dst: options.cwd } : undefined
53
+ return getCommit(hash, opts)
48
54
  }
49
55
 
50
56
  /*
@@ -8,6 +8,8 @@ const { parse, getPrettyFormat, removeSignedOffBy } = require('./utils/pretty-fo
8
8
 
9
9
  /**
10
10
  * Gets detailed information about the last commit in the repository
11
+ * @param {Object} [options] - Options
12
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
11
13
  * @returns {Promise<CommitInfo>} Promise that resolves to the last commit details including SHA, author, committer, message, branch, and tags
12
14
  * @example
13
15
  * const lastCommit = await getLastCommit()
@@ -15,10 +17,11 @@ const { parse, getPrettyFormat, removeSignedOffBy } = require('./utils/pretty-fo
15
17
  * console.log('Author:', lastCommit.author.name)
16
18
  * console.log('SHA:', lastCommit.sha)
17
19
  */
18
- function getLastCommit() {
20
+ function getLastCommit(options) {
19
21
  const command = `git log -1 --pretty=format:"${getPrettyFormat()}" && git rev-parse --abbrev-ref HEAD && git tag --contains HEAD`
20
22
  return new Promise((resolve, reject) => {
21
- executeCommand(command, (err, res) => {
23
+ const opts = options ? { dst: options.cwd } : undefined
24
+ executeCommand(command, opts, (err, res) => {
22
25
  if (err) return reject(err)
23
26
  resolve(parse(res))
24
27
  })
@@ -27,15 +30,18 @@ function getLastCommit() {
27
30
 
28
31
  /**
29
32
  * Gets the current HEAD revision SHA
33
+ * @param {Object} [options] - Options
34
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
30
35
  * @returns {Promise<{sha: string, shortSha: string}>} Promise that resolves to object with full and short SHA
31
36
  * @example
32
37
  * const revision = await getCurrentRevision()
33
38
  * console.log('Current SHA:', revision.sha)
34
39
  * console.log('Short SHA:', revision.shortSha)
35
40
  */
36
- function getCurrentRevision() {
41
+ function getCurrentRevision(options) {
37
42
  return new Promise((resolve, reject) => {
38
- executeCommand('git rev-parse HEAD', (err, res) => {
43
+ const opts = options ? { dst: options.cwd } : undefined
44
+ executeCommand('git rev-parse HEAD', opts, (err, res) => {
39
45
  if (err) return reject(err)
40
46
  const sha = res.toString().trim()
41
47
  resolve({
@@ -48,14 +54,17 @@ function getCurrentRevision() {
48
54
 
49
55
  /**
50
56
  * Gets the commit message of the current HEAD commit
57
+ * @param {Object} [options] - Options
58
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
51
59
  * @returns {Promise<string>} Promise that resolves to the commit message (with Signed-off-by lines removed)
52
60
  * @example
53
61
  * const message = await getCurrentCommitMessage()
54
62
  * console.log('Current commit message:', message)
55
63
  */
56
- function getCurrentCommitMessage() {
64
+ function getCurrentCommitMessage(options) {
57
65
  return new Promise((resolve, reject) => {
58
- executeCommand('git show -s --format=%B HEAD', (err, res) => {
66
+ const opts = options ? { dst: options.cwd } : undefined
67
+ executeCommand('git show -s --format=%B HEAD', opts, (err, res) => {
59
68
  if (err) return reject(err)
60
69
  resolve(removeSignedOffBy(res.toString()).trim())
61
70
  })
@@ -3,11 +3,14 @@ const { executeCommand } = require('./utils/exec')
3
3
 
4
4
  /**
5
5
  * Gets the current branch name of the git repository
6
+ * @param {Object} [options] - Options
7
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
6
8
  * @returns {Promise<string>} A promise that resolves to the current branch name
7
9
  */
8
- function getCurrentBranch() {
10
+ function getCurrentBranch(options) {
9
11
  return new Promise((resolve, reject) => {
10
- executeCommand('git rev-parse --abbrev-ref HEAD', (err, res) => {
12
+ const opts = options ? { dst: options.cwd } : undefined
13
+ executeCommand('git rev-parse --abbrev-ref HEAD', opts, (err, res) => {
11
14
  if (err) return reject(err)
12
15
  resolve(res.trim())
13
16
  })
@@ -12,6 +12,7 @@ const { LocalGit } = require('../localGit')
12
12
  * @param {string} [opts.from] - Alias for opts.base
13
13
  * @param {string} [opts.to] - Alias for opts.head
14
14
  * @param {boolean} [opts.includeWorkingChanges=false] - If true, compares against uncommitted changes in working directory instead of HEAD
15
+ * @param {string} [opts.cwd] - Working directory for git commands (defaults to process.cwd())
15
16
  * @returns {Promise<GitDetails>} Promise that resolves to git details including modified/created/deleted files, commits, and utility functions
16
17
  * @example
17
18
  * // Compare between commits
@@ -56,6 +56,7 @@ function getLongestLineLength(diff) {
56
56
  * @param {Object} options - Options for getting formatted diff
57
57
  * @param {string} options.filePath - Relative path from git root
58
58
  * @param {string} [options.gitRootDir] - Absolute path to git root directory (defaults to detected git root)
59
+ * @param {string} [options.cwd] - Working directory for git commands (defaults to process.cwd())
59
60
  * @param {string} [options.baseBranch='master'] - Base branch to compare against
60
61
  * @param {boolean} [options.shrinkToLongestLine=false] - Auto-calculate width based on longest line
61
62
  * @param {number} [options.leftMargin=0] - Number of spaces to add to the left of each line
@@ -66,6 +67,7 @@ function getLongestLineLength(diff) {
66
67
  async function getFormattedDiff({
67
68
  filePath,
68
69
  gitRootDir,
70
+ cwd,
69
71
  baseBranch = 'master',
70
72
  shrinkToLongestLine = false,
71
73
  leftMargin = 0,
@@ -76,7 +78,7 @@ async function getFormattedDiff({
76
78
  const { formatDiff } = await import('@davidwells/git-split-diffs')
77
79
 
78
80
  if (!gitRootDir) {
79
- gitRootDir = await getGitRoot()
81
+ gitRootDir = await getGitRoot(cwd)
80
82
  }
81
83
 
82
84
  // Get the diff for this specific file
@@ -1,23 +1,25 @@
1
- const { executeCommand } = require('./utils/exec')
1
+ const { exec } = require('child_process')
2
2
 
3
3
  /** @type {Map<string, string>} */
4
4
  const gitRootCache = new Map()
5
5
 
6
6
  /**
7
7
  * Gets the root directory of the git repository
8
+ * @param {string} [cwd] - Working directory to run git command from (defaults to process.cwd())
8
9
  * @returns {Promise<string>} A promise that resolves to the root directory path of the git repository
9
10
  */
10
- function getGitRoot() {
11
+ function getGitRoot(cwd) {
11
12
  return new Promise((resolve, reject) => {
12
- const cwd = process.cwd()
13
- const cached = gitRootCache.get(cwd)
13
+ const dir = cwd || process.cwd()
14
+ const cached = gitRootCache.get(dir)
14
15
  if (cached) {
15
16
  return resolve(cached)
16
17
  }
17
- executeCommand('git rev-parse --show-toplevel', (err, res) => {
18
+ exec('git rev-parse --show-toplevel', { cwd: dir }, (err, stdout, stderr) => {
18
19
  if (err) return reject(err)
19
- const root = res.trim()
20
- gitRootCache.set(cwd, root)
20
+ if (stderr) return reject(stderr)
21
+ const root = stdout.trim()
22
+ gitRootCache.set(dir, root)
21
23
  resolve(root)
22
24
  })
23
25
  })
@@ -13,7 +13,7 @@ module.exports.gitJSONToGitDSL = (gitJSONRep, config) => {
13
13
  const getFullDiff = config.getStructuredDiffForFile
14
14
  ? null
15
15
  : memoize((base, head) => {
16
- return config.getFullDiff(base, head)
16
+ return config.getFullDiff(base, head, config.cwd)
17
17
  }, (base, head) => `${base}...${head}`)
18
18
  /**
19
19
  * Takes a filename, and pulls from the PR the two versions of a file
@@ -31,12 +31,14 @@ module.exports.gitJSONToGitDSL = (gitJSONRep, config) => {
31
31
  const baseFile = await config.getFileContents(
32
32
  filename,
33
33
  config.repo,
34
- config.baseSHA
34
+ config.baseSHA,
35
+ { cwd: config.cwd }
35
36
  )
36
37
  const headFile = await config.getFileContents(
37
38
  filename,
38
39
  config.repo,
39
- config.headSHA
40
+ config.headSHA,
41
+ { cwd: config.cwd }
40
42
  )
41
43
  // Parse JSON. `fileContents` returns empty string for files that are
42
44
  // missing in one of the refs, ie. when the file is created or deleted.
@@ -110,7 +112,7 @@ module.exports.gitJSONToGitDSL = (gitJSONRep, config) => {
110
112
  const linesOfCode = async () => {
111
113
  // Use optimized numstat if available (single git command vs hundreds)
112
114
  if (config.getNumstat) {
113
- return await config.getNumstat(config.baseSHA, config.headSHA)
115
+ return await config.getNumstat(config.baseSHA, config.headSHA, config.cwd)
114
116
  }
115
117
 
116
118
  // Fallback to original implementation
@@ -190,12 +192,14 @@ module.exports.gitJSONToGitDSL = (gitJSONRep, config) => {
190
192
  before: await config.getFileContents(
191
193
  filename,
192
194
  config.repo,
193
- config.baseSHA
195
+ config.baseSHA,
196
+ { cwd: config.cwd }
194
197
  ),
195
198
  after: await config.getFileContents(
196
199
  filename,
197
200
  config.repo,
198
- config.headSHA
201
+ config.headSHA,
202
+ { cwd: config.cwd }
199
203
  ),
200
204
  diff: allLines.map(getContent).join(os.EOL),
201
205
  added: allLines
@@ -27,11 +27,17 @@ const formatJSON = `{ "sha": "${sha}", "parents": "${parents}", ${author}, ${com
27
27
  committedOn: a[6],
28
28
  */
29
29
 
30
- const localGetCommits = (base, head) => {
30
+ /**
31
+ * Get commits between two refs
32
+ * @param {string} base - Base ref
33
+ * @param {string} head - Head ref
34
+ * @param {string} [cwd] - Working directory (defaults to process.cwd())
35
+ */
36
+ const localGetCommits = (base, head, cwd) => {
31
37
  // @TODO add exclude "subject" and "body" option to ignore parsing issues
32
38
  return new Promise(resolve => {
33
39
  const args = ['log', `${base}...${head}`, `--pretty=format:${formatJSON}`]
34
- const child = spawn('git', args, { env: process.env })
40
+ const child = spawn('git', args, { env: process.env, cwd: cwd || process.cwd() })
35
41
  let stdOut = ''
36
42
  let stdErr = ''
37
43
  let realCommits = []
@@ -3,7 +3,13 @@ const { spawn } = require('child_process')
3
3
 
4
4
  const d = debug('localGetDiff')
5
5
 
6
- const localGetDiff = (base, head) => {
6
+ /**
7
+ * Get git diff between two refs
8
+ * @param {string} base - Base ref
9
+ * @param {string} head - Head ref
10
+ * @param {string} [cwd] - Working directory (defaults to process.cwd())
11
+ */
12
+ const localGetDiff = (base, head, cwd) => {
7
13
  return new Promise((resolve, reject) => {
8
14
  // If head is empty/null/undefined, compare against working directory
9
15
  // Otherwise use three-dot syntax for commit-to-commit comparison
@@ -12,7 +18,7 @@ const localGetDiff = (base, head) => {
12
18
  : ['diff', `${base}...${head}`]
13
19
 
14
20
  let stdout = ''
15
- const child = spawn('git', args, { env: process.env })
21
+ const child = spawn('git', args, { env: process.env, cwd: cwd || process.cwd() })
16
22
  d('> git', args.join(' '))
17
23
  child.stdout.on('data', chunk => {
18
24
  stdout += chunk
@@ -6,12 +6,18 @@ const d = debug('localGetJSONCommits')
6
6
  var format = "'{%n ^^^^commit^^^^: ^^^^%H^^^^,%n ^^^^abbreviated_commit^^^^: ^^^^%h^^^^,%n ^^^^tree^^^^: ^^^^%T^^^^,%n ^^^^abbreviated_tree^^^^: ^^^^%t^^^^,%n ^^^^parent^^^^: ^^^^%P^^^^,%n ^^^^abbreviated_parent^^^^: ^^^^%p^^^^,%n ^^^^refs^^^^: ^^^^%D^^^^,%n ^^^^encoding^^^^: ^^^^%e^^^^,%n ^^^^subject^^^^: ^^^^%s^^^^,%n ^^^^sanitized_subject_line^^^^: ^^^^%f^^^^,%n ^^^^commit_notes^^^^: ^^^^%N^^^^,%n ^^^^verification_flag^^^^: ^^^^%G?^^^^,%n ^^^^signer^^^^: ^^^^%GS^^^^,%n ^^^^signer_key^^^^: ^^^^%GK^^^^,%n ^^^^author^^^^: {%n ^^^^name^^^^: ^^^^%aN^^^^,%n ^^^^email^^^^: ^^^^%aE^^^^,%n ^^^^date^^^^: ^^^^%aD^^^^%n },%n ^^^^commiter^^^^: {%n ^^^^name^^^^: ^^^^%cN^^^^,%n ^^^^email^^^^: ^^^^%cE^^^^,%n ^^^^date^^^^: ^^^^%cD^^^^%n }%n},'"
7
7
 
8
8
  // https://gist.github.com/varemenos/e95c2e098e657c7688fd
9
- function getLogAsJson() {
9
+ /**
10
+ * Get git log as JSON
11
+ * @param {Object} [options] - Options
12
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
13
+ */
14
+ function getLogAsJson(options) {
10
15
  return new Promise((resolve, reject) => {
11
16
  let stdout = ''
12
17
  let result = ''
13
18
  const args = ['log', '--pretty=format:' + format] // eslint-disable-line
14
- const child = spawn('git', args, { env: process.env })
19
+ const cwd = (options && options.cwd) || process.cwd()
20
+ const child = spawn('git', args, { env: process.env, cwd })
15
21
  d('> git', args.join(' '))
16
22
  try {
17
23
  child.stdout.on('data', chunk => {
@@ -9,13 +9,14 @@ const d = debug('localGetNumstat')
9
9
  *
10
10
  * @param {string} base - Base commit SHA
11
11
  * @param {string} head - Head commit SHA
12
+ * @param {string} [cwd] - Working directory (defaults to process.cwd())
12
13
  * @returns {Promise<number>} Total lines of code changed (additions + deletions)
13
14
  */
14
- const localGetNumstat = (base, head) => {
15
+ const localGetNumstat = (base, head, cwd) => {
15
16
  return new Promise((resolve, reject) => {
16
17
  const args = ['diff', `${base}...${head}`, '--numstat']
17
18
  let stdout = ''
18
- const child = spawn('git', args, { env: process.env })
19
+ const child = spawn('git', args, { env: process.env, cwd: cwd || process.cwd() })
19
20
  d('> git', args.join(' '))
20
21
 
21
22
  child.stdout.on('data', chunk => {
@@ -1,14 +1,11 @@
1
- const process = require('child_process')
1
+ const childProcess = require('child_process')
2
2
 
3
3
  function executeCommand(command, opts, cb) {
4
- let dst = __dirname
5
4
  const callback = (typeof opts === 'function') ? opts : cb
6
5
  const options = (typeof opts === 'object') ? opts : null
7
- if (!!options && options.dst) {
8
- dst = options.dst
9
- }
6
+ const dst = (options && options.dst) || process.cwd()
10
7
 
11
- process.exec(command, { cwd: dst }, function(err, stdout, stderr) {
8
+ childProcess.exec(command, { cwd: dst }, function(err, stdout, stderr) {
12
9
  if (err) console.log(err)
13
10
  if (stdout === '') {
14
11
  callback(new Error('this does not look like a git repo'))
package/src/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  const { gitDetails } = require('./git/getDetails')
2
+ const { getGitRoot } = require('./git/getGitRoot')
3
+ const { getCurrentBranch } = require('./git/getCurrentBranch')
2
4
  const { getCommit } = require('./git/commits/getCommit')
5
+ const { getAllCommits } = require('./git/commits/getAllCommits')
3
6
  const { getFirstCommit } = require('./git/commits/getFirstCommit')
4
7
  const { getLastCommit } = require('./git/commits/getLastCommit')
5
- const { getAllCommits } = require('./git/commits/getAllCommits')
6
8
  const { getGitFiles } = require('./git/getGitFiles')
7
- const { getGitRoot } = require('./git/getGitRoot')
8
- const { getCurrentBranch } = require('./git/getCurrentBranch')
9
9
  const { getRemotes, getRemote } = require('./git/remotes/getRemotes')
10
10
  const { getFileAtCommit } = require('./git/getFileAtCommit')
11
11
  const {
package/src/localGit.js CHANGED
@@ -26,9 +26,11 @@ class LocalGit {
26
26
  * @param {string} [options.to] - Alias for head commit/branch
27
27
  * @param {string} [options.head='HEAD'] - The head commit/branch to compare to. Pass empty string '' to compare against working directory
28
28
  * @param {boolean} [options.includeWorkingChanges=false] - If true, compares against uncommitted changes in working directory instead of HEAD
29
+ * @param {string} [options.cwd] - Working directory for git commands (defaults to process.cwd())
29
30
  */
30
31
  constructor(options) {
31
32
  this.options = options
33
+ this.cwd = options.cwd
32
34
  this.getFileContents = path => {
33
35
  // eslint-disable-next-line promise/param-names
34
36
  return new Promise(res => res(readFileSync(path, 'utf8')))
@@ -55,7 +57,7 @@ class LocalGit {
55
57
  if (this.gitDiff) {
56
58
  return this.gitDiff
57
59
  }
58
- this.gitDiff = await localGetDiff(this.base, this.head)
60
+ this.gitDiff = await localGetDiff(this.base, this.head, this.cwd)
59
61
  return this.gitDiff
60
62
  }
61
63
  /**
@@ -80,6 +82,7 @@ class LocalGit {
80
82
  async getPlatformGitRepresentation() {
81
83
  const base = this.base
82
84
  const head = this.head
85
+ const cwd = this.cwd
83
86
 
84
87
  const t0 = DEBUG_TIMING ? Date.now() : 0
85
88
  const diff = await this.getGitDiff()
@@ -87,7 +90,7 @@ class LocalGit {
87
90
  if (DEBUG_TIMING) console.log(` ⏱️ getGitDiff: ${t1 - t0}ms`)
88
91
 
89
92
  // Array of commits
90
- const commits = await localGetCommits(base, head)
93
+ const commits = await localGetCommits(base, head, cwd)
91
94
  const t2 = DEBUG_TIMING ? Date.now() : 0
92
95
  if (DEBUG_TIMING) console.log(` ⏱️ localGetCommits: ${t2 - t1}ms`)
93
96
 
@@ -96,12 +99,13 @@ class LocalGit {
96
99
  const t3 = DEBUG_TIMING ? Date.now() : 0
97
100
  if (DEBUG_TIMING) console.log(` ⏱️ diffToGitJSONDSL: ${t3 - t2}ms (parsing ${diff.split('\n').length} lines of diff)`)
98
101
 
99
- const gitRoot = await getGitRoot()
102
+ const gitRoot = await getGitRoot(cwd)
100
103
 
101
104
  const config = {
102
105
  repo: gitRoot,
103
106
  baseSHA: base,
104
107
  headSHA: head,
108
+ cwd,
105
109
  getFileContents: localGetFileAtSHA,
106
110
  getFullDiff: localGetDiff,
107
111
  getNumstat: localGetNumstat
@@ -4,6 +4,8 @@ export type CommitInfo = import("../../types").CommitInfo;
4
4
  */
5
5
  /**
6
6
  * Gets all commits in the repository from first to last
7
+ * @param {Object} [options] - Options
8
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
7
9
  * @returns {Promise<CommitInfo[]>} Promise that resolves to array of all commits in chronological order
8
10
  * @example
9
11
  * const commits = await getAllCommits()
@@ -11,4 +13,6 @@ export type CommitInfo = import("../../types").CommitInfo;
11
13
  * console.log(`${commit.sha}: ${commit.subject}`)
12
14
  * })
13
15
  */
14
- export function getAllCommits(): Promise<CommitInfo[]>;
16
+ export function getAllCommits(options?: {
17
+ cwd?: string;
18
+ }): Promise<CommitInfo[]>;
@@ -1,6 +1,8 @@
1
1
  export type CommitInfo = import("../../types").CommitInfo;
2
2
  /**
3
3
  * Gets detailed information about the first commit in the repository
4
+ * @param {Object} [options] - Options
5
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
4
6
  * @returns {Promise<CommitInfo>} Promise that resolves to commit details object containing SHA, author, committer, message, branch, and tags
5
7
  * @throws {Error} Throws if git command fails or if not in a git repository
6
8
  * @example
@@ -9,17 +11,23 @@ export type CommitInfo = import("../../types").CommitInfo;
9
11
  * console.log('Author:', firstCommit.author.name)
10
12
  * console.log('SHA:', firstCommit.sha)
11
13
  */
12
- export function getFirstCommit(): Promise<CommitInfo>;
14
+ export function getFirstCommit(options?: {
15
+ cwd?: string;
16
+ }): Promise<CommitInfo>;
13
17
  /**
14
18
  * @typedef {import('../../types').CommitInfo} CommitInfo
15
19
  */
16
20
  /**
17
21
  * Gets the hash of the first commit in the repository
18
22
  * Uses git rev-list to find the initial commit with no parents
23
+ * @param {Object} [options] - Options
24
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
19
25
  * @returns {Promise<string>} Promise that resolves to the SHA hash of the first commit
20
26
  * @throws {Error} Throws if git command fails or if not in a git repository
21
27
  * @example
22
28
  * const hash = await getFirstCommitHash()
23
29
  * // Returns: 'a1b2c3d4e5f6...' (40-character SHA-1 hash)
24
30
  */
25
- export function getFirstCommitHash(): Promise<string>;
31
+ export function getFirstCommitHash(options?: {
32
+ cwd?: string;
33
+ }): Promise<string>;
@@ -4,6 +4,8 @@ export type CommitInfo = import("../../types").CommitInfo;
4
4
  */
5
5
  /**
6
6
  * Gets detailed information about the last commit in the repository
7
+ * @param {Object} [options] - Options
8
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
7
9
  * @returns {Promise<CommitInfo>} Promise that resolves to the last commit details including SHA, author, committer, message, branch, and tags
8
10
  * @example
9
11
  * const lastCommit = await getLastCommit()
@@ -11,24 +13,34 @@ export type CommitInfo = import("../../types").CommitInfo;
11
13
  * console.log('Author:', lastCommit.author.name)
12
14
  * console.log('SHA:', lastCommit.sha)
13
15
  */
14
- export function getLastCommit(): Promise<CommitInfo>;
16
+ export function getLastCommit(options?: {
17
+ cwd?: string;
18
+ }): Promise<CommitInfo>;
15
19
  /**
16
20
  * Gets the current HEAD revision SHA
21
+ * @param {Object} [options] - Options
22
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
17
23
  * @returns {Promise<{sha: string, shortSha: string}>} Promise that resolves to object with full and short SHA
18
24
  * @example
19
25
  * const revision = await getCurrentRevision()
20
26
  * console.log('Current SHA:', revision.sha)
21
27
  * console.log('Short SHA:', revision.shortSha)
22
28
  */
23
- export function getCurrentRevision(): Promise<{
29
+ export function getCurrentRevision(options?: {
30
+ cwd?: string;
31
+ }): Promise<{
24
32
  sha: string;
25
33
  shortSha: string;
26
34
  }>;
27
35
  /**
28
36
  * Gets the commit message of the current HEAD commit
37
+ * @param {Object} [options] - Options
38
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
29
39
  * @returns {Promise<string>} Promise that resolves to the commit message (with Signed-off-by lines removed)
30
40
  * @example
31
41
  * const message = await getCurrentCommitMessage()
32
42
  * console.log('Current commit message:', message)
33
43
  */
34
- export function getCurrentCommitMessage(): Promise<string>;
44
+ export function getCurrentCommitMessage(options?: {
45
+ cwd?: string;
46
+ }): Promise<string>;
@@ -1,5 +1,9 @@
1
1
  /**
2
2
  * Gets the current branch name of the git repository
3
+ * @param {Object} [options] - Options
4
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
3
5
  * @returns {Promise<string>} A promise that resolves to the current branch name
4
6
  */
5
- export function getCurrentBranch(): Promise<string>;
7
+ export function getCurrentBranch(options?: {
8
+ cwd?: string;
9
+ }): Promise<string>;
@@ -10,6 +10,7 @@ export type GitDetails = import("../types").GitDetails;
10
10
  * @param {string} [opts.from] - Alias for opts.base
11
11
  * @param {string} [opts.to] - Alias for opts.head
12
12
  * @param {boolean} [opts.includeWorkingChanges=false] - If true, compares against uncommitted changes in working directory instead of HEAD
13
+ * @param {string} [opts.cwd] - Working directory for git commands (defaults to process.cwd())
13
14
  * @returns {Promise<GitDetails>} Promise that resolves to git details including modified/created/deleted files, commits, and utility functions
14
15
  * @example
15
16
  * // Compare between commits
@@ -37,4 +38,5 @@ export function gitDetails(opts?: {
37
38
  from?: string;
38
39
  to?: string;
39
40
  includeWorkingChanges?: boolean;
41
+ cwd?: string;
40
42
  }): Promise<GitDetails>;
@@ -3,6 +3,7 @@
3
3
  * @param {Object} options - Options for getting formatted diff
4
4
  * @param {string} options.filePath - Relative path from git root
5
5
  * @param {string} [options.gitRootDir] - Absolute path to git root directory (defaults to detected git root)
6
+ * @param {string} [options.cwd] - Working directory for git commands (defaults to process.cwd())
6
7
  * @param {string} [options.baseBranch='master'] - Base branch to compare against
7
8
  * @param {boolean} [options.shrinkToLongestLine=false] - Auto-calculate width based on longest line
8
9
  * @param {number} [options.leftMargin=0] - Number of spaces to add to the left of each line
@@ -10,9 +11,10 @@
10
11
  * @param {boolean} [options.hideHeader=false] - Remove the file path header from the diff
11
12
  * @returns {Promise<string | null>} Formatted diff string or null if no diff
12
13
  */
13
- export function getFormattedDiff({ filePath, gitRootDir, baseBranch, shrinkToLongestLine, leftMargin, width, hideHeader }: {
14
+ export function getFormattedDiff({ filePath, gitRootDir, cwd, baseBranch, shrinkToLongestLine, leftMargin, width, hideHeader }: {
14
15
  filePath: string;
15
16
  gitRootDir?: string;
17
+ cwd?: string;
16
18
  baseBranch?: string;
17
19
  shrinkToLongestLine?: boolean;
18
20
  leftMargin?: number;
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * Gets the root directory of the git repository
3
+ * @param {string} [cwd] - Working directory to run git command from (defaults to process.cwd())
3
4
  * @returns {Promise<string>} A promise that resolves to the root directory path of the git repository
4
5
  */
5
- export function getGitRoot(): Promise<string>;
6
+ export function getGitRoot(cwd?: string): Promise<string>;
@@ -1,3 +1,9 @@
1
1
  export const formatJSON: "{ \"sha\": \"%H\", \"parents\": \"%p\", \"author\": {\"name\": \"%an\", \"email\": \"%ae\" }, \"committer\": {\"name\": \"%cn\", \"email\": \"%ce\" }, \"subject\": \"%s\", \"sanitizedSubject\": \"%f\", \"body\": \"%b\", \"authoredOn\": \"%aI\", \"committedOn\": \"%cI\"},";
2
- export function localGetCommits(base: any, head: any): Promise<any>;
2
+ /**
3
+ * Get commits between two refs
4
+ * @param {string} base - Base ref
5
+ * @param {string} head - Head ref
6
+ * @param {string} [cwd] - Working directory (defaults to process.cwd())
7
+ */
8
+ export function localGetCommits(base: string, head: string, cwd?: string): Promise<any>;
3
9
  export function attemptToFix(jsonLikeValue: any): any;
@@ -1 +1,7 @@
1
- export function localGetDiff(base: any, head: any): Promise<any>;
1
+ /**
2
+ * Get git diff between two refs
3
+ * @param {string} base - Base ref
4
+ * @param {string} head - Head ref
5
+ * @param {string} [cwd] - Working directory (defaults to process.cwd())
6
+ */
7
+ export function localGetDiff(base: string, head: string, cwd?: string): Promise<any>;
@@ -1 +1,8 @@
1
- export function getLogAsJson(): Promise<any>;
1
+ /**
2
+ * Get git log as JSON
3
+ * @param {Object} [options] - Options
4
+ * @param {string} [options.cwd] - Working directory (defaults to process.cwd())
5
+ */
6
+ export function getLogAsJson(options?: {
7
+ cwd?: string;
8
+ }): Promise<any>;
@@ -4,6 +4,7 @@
4
4
  *
5
5
  * @param {string} base - Base commit SHA
6
6
  * @param {string} head - Head commit SHA
7
+ * @param {string} [cwd] - Working directory (defaults to process.cwd())
7
8
  * @returns {Promise<number>} Total lines of code changed (additions + deletions)
8
9
  */
9
- export function localGetNumstat(base: string, head: string): Promise<number>;
10
+ export function localGetNumstat(base: string, head: string, cwd?: string): Promise<number>;
@@ -15,6 +15,7 @@ export class LocalGit {
15
15
  * @param {string} [options.to] - Alias for head commit/branch
16
16
  * @param {string} [options.head='HEAD'] - The head commit/branch to compare to. Pass empty string '' to compare against working directory
17
17
  * @param {boolean} [options.includeWorkingChanges=false] - If true, compares against uncommitted changes in working directory instead of HEAD
18
+ * @param {string} [options.cwd] - Working directory for git commands (defaults to process.cwd())
18
19
  */
19
20
  constructor(options: {
20
21
  from?: string;
@@ -22,6 +23,7 @@ export class LocalGit {
22
23
  to?: string;
23
24
  head?: string;
24
25
  includeWorkingChanges?: boolean;
26
+ cwd?: string;
25
27
  });
26
28
  options: {
27
29
  from?: string;
@@ -29,7 +31,9 @@ export class LocalGit {
29
31
  to?: string;
30
32
  head?: string;
31
33
  includeWorkingChanges?: boolean;
34
+ cwd?: string;
32
35
  };
36
+ cwd: string;
33
37
  getFileContents: (path: any) => Promise<any>;
34
38
  name: string;
35
39
  base: string;