Skip to content

Commit ebe158c

Browse files
authored
Merge pull request #681 from aciidb0mb3r/git-remote
[GitRepository] Add methods to get and set remotes
2 parents 3160cfe + d2ef900 commit ebe158c

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-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+
/// Removes a remote from 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: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,12 +303,55 @@ class GitRepositoryTests: XCTestCase {
303303
}
304304
}
305305

306+
func testRemotes() {
307+
mktmpdir { path in
308+
// Create a repo.
309+
let testRepoPath = path.appending(component: "test-repo")
310+
try makeDirectories(testRepoPath)
311+
initGitRepo(testRepoPath)
312+
let repo = GitRepository(path: testRepoPath)
313+
314+
// There should be no remotes currently.
315+
XCTAssert(try repo.remotes().isEmpty)
316+
317+
// Add a remote via git cli.
318+
try systemQuietly([Git.tool, "-C", testRepoPath.asString, "remote", "add", "origin", "../foo"])
319+
// Test if it was added.
320+
XCTAssertEqual(Dictionary(items: try repo.remotes().map { ($0, $1) }), ["origin": "../foo"])
321+
322+
// Remove the remote via cli.
323+
try systemQuietly([Git.tool, "-C", testRepoPath.asString, "remote", "remove", "origin"])
324+
// Test if it was removed.
325+
XCTAssert(try repo.remotes().isEmpty)
326+
327+
// Add a remote.
328+
try repo.add(remote: "origin", url: "../foo")
329+
// Check it was added.
330+
let remote = Dictionary(items: try repo.remotes().map { ($0, $1) })
331+
XCTAssertEqual(remote, ["origin": "../foo"])
332+
333+
// Add another remote.
334+
try repo.add(remote: "origin2", url: "../bar")
335+
// Check that there are two remotes now.
336+
let remotes = Dictionary(items: try repo.remotes().map { ($0, $1)})
337+
XCTAssertEqual(remotes, ["origin": "../foo", "origin2": "../bar"])
338+
339+
// Remove the remotes.
340+
try repo.remove(remote: "origin")
341+
try repo.remove(remote: "origin2")
342+
343+
// All remotes should be removed now.
344+
XCTAssert(try repo.remotes().isEmpty)
345+
}
346+
}
347+
306348
static var allTests = [
307349
("testFetch", testFetch),
308350
("testRepositorySpecifier", testRepositorySpecifier),
309351
("testProvider", testProvider),
310352
("testGitRepositoryHash", testGitRepositoryHash),
311353
("testRawRepository", testRawRepository),
354+
("testRemotes", testRemotes),
312355
("testGitFileView", testGitFileView),
313356
("testCheckouts", testCheckouts),
314357
("testHasUnpushedCommits", testHasUnpushedCommits),

0 commit comments

Comments
 (0)