Skip to content

Commit 65b87b1

Browse files
committed
[GitRepository] Add methods to get and set remotes
This is needed because we want to reset the remote of the editable clone.
1 parent efc0e50 commit 65b87b1

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

Sources/SourceControl/GitRepository.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,40 @@ public class GitRepository: Repository, WorkingCheckout {
211211
self.path = path
212212
}
213213

214+
/// Adds a remote to the git repository.
215+
///
216+
/// - parameters:
217+
/// - remote: The name of the remote. It shouldn't already be present.
218+
/// - url: The url of the remote.
219+
func add(remote: String, url: String) throws {
220+
try runCommandQuietly([Git.tool, "-C", path.asString, "remote", "add", remote, url])
221+
}
222+
223+
/// Adds a remote to the git repository.
224+
///
225+
/// - parameters:
226+
/// - remote: The name of the remote to be removed. It should already be present.
227+
/// - url: the url of the remote.
228+
func remove(remote: String) throws {
229+
try runCommandQuietly([Git.tool, "-C", path.asString, "remote", "remove", remote])
230+
}
231+
232+
/// Gets the current list of remotes of the repository.
233+
///
234+
/// - Returns: An array of tuple containing name and url of the remote.
235+
func remotes() throws -> [(name: String, url: String)] {
236+
return try queue.sync {
237+
// Get the remote names.
238+
let remoteNamesOutput = try Git.runPopen([Git.tool, "-C", path.asString, "remote"]).chomp()
239+
let remoteNames = remoteNamesOutput.characters.split(separator: "\n").map(String.init)
240+
return try remoteNames.map { name in
241+
// For each remote get the url.
242+
let url = try Git.runPopen([Git.tool, "-C", path.asString, "remote", "get-url", name]).chomp()
243+
return (name, url)
244+
}
245+
}
246+
}
247+
214248
// MARK: Repository Interface
215249

216250
/// Returns the tags present in repository.

Tests/SourceControlTests/GitRepositoryTests.swift

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

274+
func testRemotes() {
275+
mktmpdir { path in
276+
// Create a repo.
277+
let testRepoPath = path.appending(component: "test-repo")
278+
try makeDirectories(testRepoPath)
279+
initGitRepo(testRepoPath)
280+
let repo = GitRepository(path: testRepoPath)
281+
282+
// There should be no remotes currently.
283+
XCTAssert(try repo.remotes().isEmpty)
284+
285+
// Add a remote.
286+
try repo.add(remote: "origin", url: "../foo")
287+
// Check it was added.
288+
let remote = Dictionary(items: try repo.remotes().map { ($0, $1) })
289+
XCTAssertEqual(remote, ["origin": "../foo"])
290+
291+
// Add another remote.
292+
try repo.add(remote: "origin2", url: "../bar")
293+
// Check that there are two remotes now.
294+
let remotes = Dictionary(items: try repo.remotes().map { ($0, $1)})
295+
XCTAssertEqual(remotes, ["origin": "../foo", "origin2": "../bar"])
296+
297+
// Remove the remotes.
298+
try repo.remove(remote: "origin")
299+
try repo.remove(remote: "origin2")
300+
301+
// All remotes should be removed now.
302+
XCTAssert(try repo.remotes().isEmpty)
303+
}
304+
}
305+
274306
static var allTests = [
275307
("testFetch", testFetch),
276308
("testRepositorySpecifier", testRepositorySpecifier),
277309
("testProvider", testProvider),
278310
("testGitRepositoryHash", testGitRepositoryHash),
279311
("testRawRepository", testRawRepository),
312+
("testRemotes", testRemotes),
280313
("testGitFileView", testGitFileView),
281314
("testCheckouts", testCheckouts),
282315
]

0 commit comments

Comments
 (0)