Skip to content

Commit 0dd4413

Browse files
authored
Merge branch 'main' into add-checkout-remote-tracking
2 parents 146679c + 0fc931a commit 0dd4413

File tree

4 files changed

+87
-22
lines changed

4 files changed

+87
-22
lines changed

.github/workflows/test.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Test
2+
on:
3+
push:
4+
branches:
5+
- main
6+
7+
pull_request:
8+
paths:
9+
- "Sources/**"
10+
- "Tests/**"
11+
- ".github/workflows/test.yml"
12+
13+
jobs:
14+
test:
15+
name: Run tests
16+
runs-on: macos-15
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
# there are unit tests that rely on the default branch name being `main` but this isn't the case on GitHub Actions runners
21+
- name: Set Git default branch name
22+
run: git config --global init.defaultBranch main
23+
24+
- run: make test

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.PHONY: test
2+
test:
3+
swift test

Sources/GitKit/Git.swift

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ public final class Git: Shell {
1616
case cmd(Command, String? = nil)
1717
case addAll
1818
case status(short: Bool = false)
19-
case commit(message: String, Bool = false)
20-
case config(name: String, value: String)
19+
case commit(message: String, allowEmpty: Bool = false, gpgSigned: Bool = false)
20+
case writeConfig(name: String, value: String)
21+
case readConfig(name: String)
2122
case clone(url: String)
2223

2324
/// - parameter branch the name of the branch to checkout
@@ -37,7 +38,11 @@ public final class Git: Shell {
3738
case submoduleForeach(recursive: Bool = false, command: String)
3839
case renameRemote(oldName: String, newName: String)
3940
case addRemote(name: String, url: String)
40-
case revParse(abbrevRef: String)
41+
42+
/// - parameter abbrevRef whether or not the result should be the abbreviated reference name or the full commit SHA hash
43+
/// - parameter revision the name of the revision to parse. can be symbolic (`@`), human-readable (`origin/HEAD`) or a commit SHA hash
44+
case revParse(abbrevRef: Bool, revision: String)
45+
4146
case revList(branch: String, count: Bool = false, revisions: String? = nil)
4247
case raw(String)
4348
case lsRemote(url: String, limitToHeads: Bool = false)
@@ -57,11 +62,16 @@ public final class Git: Shell {
5762
if short {
5863
params.append("--short")
5964
}
60-
case .commit(let message, let allowEmpty):
65+
case .commit(let message, let allowEmpty, let gpgSigned):
6166
params = [Command.commit.rawValue, "-m", "\"\(message)\""]
6267
if allowEmpty {
6368
params.append("--allow-empty")
6469
}
70+
if gpgSigned {
71+
params.append("--gpg-sign")
72+
} else {
73+
params.append("--no-gpg-sign")
74+
}
6575
case .clone(let url):
6676
params = [Command.clone.rawValue, url]
6777
case .checkout(let branch, let create, let tracking):
@@ -143,10 +153,10 @@ public final class Git: Shell {
143153
params = [Command.remote.rawValue, "add", name, url]
144154
case .raw(let command):
145155
params.append(command)
146-
case .config(name: let name, value: let value):
156+
case .writeConfig(let name, let value):
147157
params = [Command.config.rawValue, "--add", name, value]
148-
case .revParse(abbrevRef: let abbrevRef):
149-
params = [Command.revParse.rawValue, "--abbrev-ref", abbrevRef]
158+
case .readConfig(let name):
159+
params = [Command.config.rawValue, "--get", name]
150160
case .revList(let branch, let count, let revisions):
151161
params = [Command.revList.rawValue]
152162
if count {
@@ -155,6 +165,12 @@ public final class Git: Shell {
155165
if let revisions = revisions {
156166
params.append(revisions)
157167
}
168+
case .revParse(let abbrevRef, let revision):
169+
params = [Command.revParse.rawValue]
170+
if abbrevRef {
171+
params.append("--abbrev-ref")
172+
}
173+
params.append(revision)
158174
case .lsRemote(url: let url, limitToHeads: let limitToHeads):
159175
params = [Command.lsRemote.rawValue]
160176
if limitToHeads {

Tests/GitKitTests/GitKitTests.swift

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ final class GitKitTests: XCTestCase {
2626
("testCommandWithArgs", testCommandWithArgs),
2727
("testClone", testClone),
2828
("testCheckoutRemoteTracking", testCheckoutRemoteTracking),
29+
("testRevParse", testRevParse),
2930
]
3031

3132
// MARK: - helpers
@@ -50,7 +51,7 @@ final class GitKitTests: XCTestCase {
5051
try self.clean(path: path)
5152
let expectedOutput = expectation
5253
let git = Git(path: path)
53-
try git.run(.raw("init && git commit -m 'initial' --allow-empty"))
54+
try git.run(.raw("init && git commit -m 'initial' --allow-empty --no-gpg-sign"))
5455
let output = try git.run(alias)
5556
self.assert(type: "output", result: output, expected: expectedOutput)
5657
try self.clean(path: path)
@@ -74,44 +75,39 @@ final class GitKitTests: XCTestCase {
7475
try self.clean(path: path)
7576
let git = Git(path: path)
7677
try git.run(.cmd(.initialize))
77-
try git.run(.commit(message: expectation, true))
78-
let out = try git.run(.log(1))
78+
try git.run(.commit(message: expectation, allowEmpty: true))
79+
let out = try git.run(.log(numberOfCommits: 1))
7980
try self.clean(path: path)
8081
XCTAssertTrue(out.hasSuffix(expectation), "Commit was not created.")
8182
}
8283

8384
func testCommandWithArgs() throws {
8485
let path = self.currentPath()
8586

86-
try self._test(.cmd(.branch, "-a"), path: path, expectation: "* master")
87+
try self._test(.cmd(.branch, "-a"), path: path, expectation: "* main")
8788
}
8889

8990
func testClone() throws {
9091
let path = self.currentPath()
9192

9293
let expectation = """
93-
On branch master
94-
Your branch is up to date with 'origin/master'.
94+
On branch main
95+
Your branch is up to date with 'origin/main'.
9596
9697
nothing to commit, working tree clean
9798
"""
9899

99100
try self.clean(path: path)
100101
let git = Git(path: path)
101102

102-
try git.run(.clone(url: "git@github.com:binarybirds/shell-kit"))
103+
try git.run(.clone(url: "https://github.com/binarybirds/shell-kit.git"))
103104
let statusOutput = try git.run("cd \(path)/shell-kit && git status")
104105
try self.clean(path: path)
105106
self.assert(type: "output", result: statusOutput, expected: expectation)
106107
}
107108

108109
func testCheckoutRemoteTracking() throws {
109-
let path = self.currentPath()
110-
111-
try self.clean(path: path)
112-
let git = Git(path: path)
113-
114-
try git.run(.clone(url: "https://github.com/binarybirds/shell-kit.git"))
110+
try git.run(.clone(url: "https://github.com/binarybirds/shell-kit.git"))
115111

116112
let repoPath = "\(path)/shell-kit"
117113
let repoGit = Git(path: repoPath)
@@ -124,17 +120,43 @@ final class GitKitTests: XCTestCase {
124120
XCTAssertTrue(branchOutput.contains("origin/main"), "Branch should track origin/main")
125121
}
126122

123+
func testRevParse() throws {
124+
125+
let path = self.currentPath()
126+
127+
try self.clean(path: path)
128+
let git = Git(path: path)
129+
130+
try git.run(.raw("init"))
131+
try git.run(.commit(message: "initial commit", allowEmpty: true))
132+
133+
let abbrevRef = try git.run(.revParse(abbrevRef: true, revision: "HEAD"))
134+
XCTAssertEqual(abbrevRef, "main", "Should return abbreviated reference name")
135+
136+
let fullSHA = try git.run(.revParse(abbrevRef: false, revision: "HEAD"))
137+
XCTAssertTrue(fullSHA.count == 40, "Should return full 40-character SHA")
138+
XCTAssertTrue(fullSHA.allSatisfy { $0.isHexDigit }, "SHA should contain only hex characters")
139+
140+
let symbolicRef = try git.run(.revParse(abbrevRef: false, revision: "@"))
141+
XCTAssertEqual(symbolicRef, fullSHA, "Symbolic '@' should resolve to same SHA as HEAD")
142+
143+
let currentBranch = try git.run(.revParse(abbrevRef: true, revision: "@"))
144+
XCTAssertEqual(currentBranch, "main", "Should return current branch name")
145+
146+
try self.clean(path: path)
147+
}
148+
127149
#if os(macOS)
128150
func testAsyncRun() throws {
129151
let path = self.currentPath()
130152
try self.clean(path: path)
131153
let expectedOutput = """
132-
On branch master
154+
On branch main
133155
nothing to commit, working tree clean
134156
"""
135157

136158
let git = Git(path: path)
137-
try git.run(.raw("init && git commit -m 'initial' --allow-empty"))
159+
try git.run(.raw("init && git commit -m 'initial' --allow-empty --no-gpg-sign"))
138160

139161
let expectation = XCTestExpectation(description: "Shell command finished.")
140162
git.run(.cmd(.status)) { result, error in

0 commit comments

Comments
 (0)