Skip to content

Commit 516fbc3

Browse files
committed
[Repository] Add hadUnpushedCommits()
This will help detect if there are any commits made by users which are not pushed somewhere. This is needed for unedit feature.
1 parent efc0e50 commit 516fbc3

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

Sources/SourceControl/GitRepository.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,11 @@ public class GitRepository: Repository, WorkingCheckout {
251251

252252
// MARK: Working Checkout Interface
253253

254+
public func hasUnpushedCommits() throws -> Bool {
255+
let hasOutput = try runPopen([Git.tool, "-C", path.asString, "log", "--branches", "--not", "--remotes"]).chomp().isEmpty
256+
return !hasOutput
257+
}
258+
254259
public func getCurrentRevision() throws -> Revision {
255260
return Revision(identifier: try runPopen([Git.tool, "-C", path.asString, "rev-parse", "--verify", "HEAD"]).chomp())
256261
}

Sources/SourceControl/Repository.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ public protocol WorkingCheckout {
143143
/// - Throws: If an error occurs while performing the fetch operation.
144144
func fetch() throws
145145

146+
/// Query whether the checkout has any commits which are not pushed to its remote.
147+
func hasUnpushedCommits() throws -> Bool
148+
146149
/// Check out the given tag.
147150
func checkout(tag: String) throws
148151

Tests/SourceControlTests/GitRepositoryTests.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,38 @@ class GitRepositoryTests: XCTestCase {
271271
}
272272
}
273273

274+
func testHasUnpushedCommits() throws {
275+
mktmpdir { path in
276+
// Create a repo.
277+
let testRepoPath = path.appending(component: "test-repo")
278+
try makeDirectories(testRepoPath)
279+
initGitRepo(testRepoPath)
280+
281+
// Clone it somewhere.
282+
let testClonePath = path.appending(component: "clone")
283+
let provider = GitRepositoryProvider()
284+
let repoSpec = RepositorySpecifier(url: testRepoPath.asString)
285+
try provider.fetch(repository: repoSpec, to: testClonePath)
286+
287+
// Clone off a checkout.
288+
let checkoutPath = path.appending(component: "checkout")
289+
try provider.cloneCheckout(repository: repoSpec, at: testClonePath, to: checkoutPath)
290+
let checkoutRepo = try provider.openCheckout(at: checkoutPath)
291+
292+
XCTAssertFalse(try checkoutRepo.hasUnpushedCommits())
293+
// Add a new file to checkout.
294+
try localFileSystem.writeFileContents(checkoutPath.appending(component: "test.txt"), bytes: "Hi")
295+
try systemQuietly([Git.tool, "-C", checkoutPath.asString, "add", "test.txt"])
296+
try systemQuietly([Git.tool, "-C", checkoutPath.asString, "commit", "-m", "Add some files."])
297+
298+
// We should have commits which are not pushed.
299+
XCTAssert(try checkoutRepo.hasUnpushedCommits())
300+
// Push the changes and check again.
301+
try systemQuietly([Git.tool, "-C", checkoutPath.asString, "push"])
302+
XCTAssertFalse(try checkoutRepo.hasUnpushedCommits())
303+
}
304+
}
305+
274306
static var allTests = [
275307
("testFetch", testFetch),
276308
("testRepositorySpecifier", testRepositorySpecifier),
@@ -279,5 +311,6 @@ class GitRepositoryTests: XCTestCase {
279311
("testRawRepository", testRawRepository),
280312
("testGitFileView", testGitFileView),
281313
("testCheckouts", testCheckouts),
314+
("testHasUnpushedCommits", testHasUnpushedCommits),
282315
]
283316
}

0 commit comments

Comments
 (0)