[swift-build-dev] Proposal: Git Branch and ref support for dependencies in Swift Package Manager

Max Howell max.howell at apple.com
Thu Mar 3 14:07:59 CST 2016

Hi everyone,

I’d like to move this forward, I have the following points for discussion:


I would like to suspend this proposal’s submission pending update support which is due to be implemented after xcodeproj lands (which is done).

My rationale is: it impacts this proposal


I would like to suggest that the lockfile be placed as so:


For me this fulfills the best of both worlds: it no longer seems to be a UNIX-style lockfile for the Package.swift file *and* it more clearly shows what precisely is being locked while continuing the perhaps unwise tradition of naming the file a “lockfile”


I would like to propose that initially the method that is used for altering branches, origins and pinning versions is not given an explicit CLI UI and instead the user must use explicit git commands in their Packages directory to set the “locks”.

The benefit here is that the process we are using is transparent, which allows developers more power over this feature and enables greater understanding over what happens.

Once the modifications are made the lock file can be regenerated by executing a command (TBD). Trying to run swift-build with modifications without first generating the lock results in a prominent warning, or perhaps even an error (TBD).


I would like the propose that any local changes to cloned packages that are NOT pinned to a commit are diff’d and the diff be embedded in the lockfile. This ensures that we:

1) Encourage users to edit, fix and improve their packages
2) Their changes get checked in and thus other people using the Package absolutely will get these changes without them having to explicitly publish their changes somewhere accessible to their whole team.

> On Dec 14, 2015, at 10:43 AM, Ankit Agarwal <ankit at ankit.im> wrote:
> Hi,
> Here is a proposal of the adding git branch support feature in SPM
> Introduction
> Pointing to branch or a commit ref for dependencies in Package.swift as opposed to only a tagged release.
> Motivation
> * Try a package which is almost stable or useable but not yet ready for a release/pre-release so not tagged (eg: new feature being introduced by a library)
> * While developing packages, one would want to point a package that uses the package to a develop branch (eg: Developing Foo package, Bar uses Foo and wants to point Foo dep to develop branch)
> * One would want to point to his own fork but not create a release while developing/testing (eg: Fork a library not compatible with SPM to make it compatible)
> * One wants to point to some commit but doesn't have a branch/tag created for that
> Proposed solution
> Allow refs and branch in Package.swift
> let package = Package(
>     name: "Hello",
>     dependencies: [
>         .Package(url: "ssh://git@example.com/Greeter.git <http://git@example.com/Greeter.git>", branch: "develop", shouldFastForward: true),
>         .Package(url: "ssh://git@example.com/FooBar.git <http://git@example.com/FooBar.git>", commit: "d8ec7ca398a3ac3990477028117384d05ca7734e"),
>     ]
> )
> Detailed design
> * Only the root Package.swift would be able to use branch/ref feature to avoid dependency hell, any other dependency fetched in current Package should not compile if that dependency contains another dependency pointing to a branch/ref
> * This feature should strictly be used for testing/developing purpose and should not be deployed to production environments
> SPM could have the following behavior when running `swift build` :
> * If pointed to a branch, there might be two use cases 
> Since there is a high probability that user wants to point a branch due to active development of that dep and wants latest ref available in that branch
> If a dependency is not cloned, clone it and checkout that branch
> If shouldFastForward is on -> Always try to be on the latest ref, disregard any local changes made to the checked out package
> If shouldFastForward is false -> Always try to be on the latest ref unless any local changes made to the checked out package
> * If pointed to a ref : 
> If that dependency is not cloned, clone it and checkout that ref.
> Consecutive `swift build` will not affect the cloned package
> If changes are made in the cloned repo, rebuild that package with those changes
> Impact on existing code
> None as this will be a new functionality
> Alternatives considered
> One option is to only allow a commit ref and not a branch so SPM will not have to worry about fast forwarding but this is a desired feature.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-build-dev/attachments/20160303/eb86ac54/attachment.html>

More information about the swift-build-dev mailing list