From 6c1922b264fbac9f54b613621b8757434a35cc1b Mon Sep 17 00:00:00 2001 From: Peter Evans <18365890+peter-evans@users.noreply.github.com> Date: Wed, 7 Aug 2024 15:31:21 +0100 Subject: [PATCH] add function to get commit detail --- __test__/entrypoint.sh | 6 ++- __test__/git-command-manager.int.test.ts | 22 +++++++++++ __test__/git-config-helper.int.test.ts | 1 - dist/index.js | 36 ++++++++++++++++++ src/git-command-manager.ts | 48 ++++++++++++++++++++++++ 5 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 __test__/git-command-manager.int.test.ts diff --git a/__test__/entrypoint.sh b/__test__/entrypoint.sh index fa08b9064d..62180bf2db 100755 --- a/__test__/entrypoint.sh +++ b/__test__/entrypoint.sh @@ -13,7 +13,7 @@ git daemon --verbose --enable=receive-pack --base-path=/git/remote --export-all # Give the daemon time to start sleep 2 -# Create a local clone and make an initial commit +# Create a local clone and make initial commits mkdir -p /git/local/repos git clone git://127.0.0.1/repos/test-base.git /git/local/repos/test-base cd /git/local/repos/test-base @@ -22,6 +22,10 @@ git config --global user.name "Your Name" echo "#test-base" > README.md git add . git commit -m "initial commit" +echo "#test-base :sparkles:" > README.md +git add . +git commit -m "add sparkles" -m "Change description: +- updates README.md to add sparkles to the title" git push -u git log -1 --pretty=oneline git config --global --unset user.email diff --git a/__test__/git-command-manager.int.test.ts b/__test__/git-command-manager.int.test.ts new file mode 100644 index 0000000000..49791feef5 --- /dev/null +++ b/__test__/git-command-manager.int.test.ts @@ -0,0 +1,22 @@ +import {GitCommandManager, Commit} from '../lib/git-command-manager' + +const REPO_PATH = '/git/local/repos/test-base' + +describe('git-command-manager integration tests', () => { + let git: GitCommandManager + + beforeAll(async () => { + git = await GitCommandManager.create(REPO_PATH) + await git.checkout('main') + }) + + it('tests getCommit', async () => { + const parent = await git.getCommit('HEAD^') + const commit = await git.getCommit('HEAD') + expect(parent.subject).toEqual('initial commit') + expect(parent.changes).toEqual([{"mode": "100644", "status": "A", "path": "README.md"}]) + expect(commit.subject).toEqual('add sparkles') + expect(commit.parents[0]).toEqual(parent.sha) + expect(commit.changes).toEqual([{"mode": "100644", "status": "M", "path": "README.md"}]) + }) +}) diff --git a/__test__/git-config-helper.int.test.ts b/__test__/git-config-helper.int.test.ts index 040a080b39..dbb2513baa 100644 --- a/__test__/git-config-helper.int.test.ts +++ b/__test__/git-config-helper.int.test.ts @@ -7,7 +7,6 @@ const extraheaderConfigKey = 'http.https://127.0.0.1/.extraheader' describe('git-config-helper integration tests', () => { let git: GitCommandManager - let gitConfigHelper: GitConfigHelper beforeAll(async () => { git = await GitCommandManager.create(REPO_PATH) diff --git a/dist/index.js b/dist/index.js index b213f40cef..5c6fe0c04c 100644 --- a/dist/index.js +++ b/dist/index.js @@ -684,6 +684,42 @@ class GitCommandManager { yield this.exec(args); }); } + getCommit(ref) { + return __awaiter(this, void 0, void 0, function* () { + const endOfBody = '###EOB###'; + const output = yield this.exec([ + 'show', + '--raw', + '--cc', + '--diff-filter=AMD', + `--format=%H%n%T%n%P%n%s%n%b%n${endOfBody}`, + ref + ]); + const lines = output.stdout.split('\n'); + const endOfBodyIndex = lines.lastIndexOf(endOfBody); + const detailLines = lines.slice(0, endOfBodyIndex); + return { + sha: detailLines[0], + tree: detailLines[1], + parents: detailLines[2].split(' '), + subject: detailLines[3], + body: detailLines.slice(4, endOfBodyIndex).join('\n'), + changes: lines.slice(endOfBodyIndex + 2, -1).map(line => { + const change = line.match(/^:\d{6} (\d{6}) \w{7} \w{7} ([AMD])\s+(.*)$/); + if (change) { + return { + mode: change[1], + status: change[2], + path: change[3] + }; + } + else { + throw new Error(`Unexpected line format: ${line}`); + } + }) + }; + }); + } getConfigValue(configKey_1) { return __awaiter(this, arguments, void 0, function* (configKey, configValue = '.') { const output = yield this.exec([ diff --git a/src/git-command-manager.ts b/src/git-command-manager.ts index 36380a316d..07b5e4620f 100644 --- a/src/git-command-manager.ts +++ b/src/git-command-manager.ts @@ -5,6 +5,19 @@ import * as path from 'path' const tagsRefSpec = '+refs/tags/*:refs/tags/*' +export type Commit = { + sha: string + tree: string + parents: string[] + subject: string + body: string + changes: { + mode: string + status: 'A' | 'M' | 'D' + path: string + }[] +} + export class GitCommandManager { private gitPath: string private workingDirectory: string @@ -138,6 +151,41 @@ export class GitCommandManager { await this.exec(args) } + async getCommit(ref: string): Promise { + const endOfBody = '###EOB###' + const output = await this.exec([ + 'show', + '--raw', + '--cc', + '--diff-filter=AMD', + `--format=%H%n%T%n%P%n%s%n%b%n${endOfBody}`, + ref + ]) + const lines = output.stdout.split('\n') + const endOfBodyIndex = lines.lastIndexOf(endOfBody) + const detailLines = lines.slice(0, endOfBodyIndex) + + return { + sha: detailLines[0], + tree: detailLines[1], + parents: detailLines[2].split(' '), + subject: detailLines[3], + body: detailLines.slice(4, endOfBodyIndex).join('\n'), + changes: lines.slice(endOfBodyIndex + 2, -1).map(line => { + const change = line.match(/^:\d{6} (\d{6}) \w{7} \w{7} ([AMD])\s+(.*)$/) + if (change) { + return { + mode: change[1], + status: change[2], + path: change[3] + } + } else { + throw new Error(`Unexpected line format: ${line}`) + } + }) + } + } + async getConfigValue(configKey: string, configValue = '.'): Promise { const output = await this.exec([ 'config',