Skip to content

Commit 9799a78

Browse files
authored
only update local checkout if necessary (#6965)
motivation: reduce redundant git operations changes: * before updating a local checkout, confirm the action is nevessary * update test to check for revision and not tag
1 parent f51e400 commit 9799a78

File tree

2 files changed

+33
-11
lines changed

2 files changed

+33
-11
lines changed

Sources/Workspace/Workspace.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3751,10 +3751,14 @@ extension Workspace {
37513751
break fetch
37523752
}
37533753

3754-
// we need do mutable-immutable dance.
3755-
try self.fileSystem.chmod(.userWritable, path: checkoutPath, options: [.recursive, .onlyFiles])
3756-
try workingCopy.fetch()
3757-
try? self.fileSystem.chmod(.userUnWritable, path: checkoutPath, options: [.recursive, .onlyFiles])
3754+
// only update if necessary
3755+
if !workingCopy.exists(revision: revision) {
3756+
// The fetch operation may update contents of the checkout,
3757+
// so we need to do mutable-immutable dance.
3758+
try self.fileSystem.chmod(.userWritable, path: checkoutPath, options: [.recursive, .onlyFiles])
3759+
try workingCopy.fetch()
3760+
try? self.fileSystem.chmod(.userUnWritable, path: checkoutPath, options: [.recursive, .onlyFiles])
3761+
}
37583762

37593763
return checkoutPath
37603764
}

Tests/CommandsTests/PackageToolTests.swift

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -264,17 +264,35 @@ final class PackageToolTests: CommandsTestCase {
264264

265265
// Perform an initial fetch.
266266
_ = try execute(["resolve"], packagePath: packageRoot)
267-
var path = try SwiftPM.packagePath(for: "Foo", packageRoot: packageRoot)
268-
XCTAssertEqual(try GitRepository(path: path).getTags(), ["1.2.3"])
269267

270-
// Retag the dependency, and update.
271-
let repo = GitRepository(path: fixturePath.appending("Foo"))
268+
do {
269+
let checkoutPath = try SwiftPM.packagePath(for: "Foo", packageRoot: packageRoot)
270+
let checkoutRepo = GitRepository(path: checkoutPath)
271+
XCTAssertEqual(try checkoutRepo.getTags(), ["1.2.3"])
272+
_ = try checkoutRepo.revision(forTag: "1.2.3")
273+
}
274+
275+
276+
// update and retag the dependency, and update.
277+
let repoPath = fixturePath.appending("Foo")
278+
let repo = GitRepository(path: repoPath)
279+
try localFileSystem.writeFileContents(repoPath.appending("test"), string: "test")
280+
try repo.stageEverything()
281+
try repo.commit()
272282
try repo.tag(name: "1.2.4")
283+
284+
// we will validate it is there
285+
let revision = try repo.revision(forTag: "1.2.4")
286+
273287
_ = try execute(["update"], packagePath: packageRoot)
274288

275-
// We shouldn't assume package path will be same after an update so ask again for it.
276-
path = try SwiftPM.packagePath(for: "Foo", packageRoot: packageRoot)
277-
XCTAssertEqual(try GitRepository(path: path).getTags(), ["1.2.3", "1.2.4"])
289+
do {
290+
// We shouldn't assume package path will be same after an update so ask again for it.
291+
let checkoutPath = try SwiftPM.packagePath(for: "Foo", packageRoot: packageRoot)
292+
let checkoutRepo = GitRepository(path: checkoutPath)
293+
// tag may not be there, but revision should be after update
294+
XCTAssertTrue(checkoutRepo.exists(revision: .init(identifier: revision)))
295+
}
278296
}
279297
}
280298

0 commit comments

Comments
 (0)