Update 22 Feb 2012: Apple have now extended the deadline to June 1st. Hopefully they’re realising the difficulties they’re creating for developers and will address some of the remaining concerns in this time.
In Mac OS you can also use the finder to go to the Applications directory. When you right-click the 'SourceTree' App and select 'Open' MAC OS will ask you if you want to open the app anyway. This only works when you right click the App directly! 同类热门 Postman Mac版V8.0.8 Sublime Text 3 Bulid for macV4.0 Navicat Premium for macV15.0.26 Xcode 7 Mac版V12.4 Xscope for macV4.5.0 SourceTree Mac版V4.0.2 PHP Mac版V7.4.8 软件评论 第 346 楼 湖南长沙联通 客人 发表于: 2020/12/17 10:29:14.
On March 1st, Apple will change the rules of the Mac App Store to require all applications to run inside of a ‘sandbox’. Unfortunately, this will disallow important SourceTree functionality that was previously acceptable under store rules. Complying with the sandboxing rules would force us to change SourceTree in ways that would remove features, damage the usability of the app, and hurt our users; therefore, we will no longer submit SourceTree updates to the Mac App Store after March 1st, 2012. New updates will be available, for free, directly from sourcetreeapp.com (and via the in-app update). We will continue to monitor the situation in case Apple improve their sandboxing implementation or revise their rules. Note that we will still be signing SourceTree with our Apple developer certificate so SourceTree should work fine with the default settings of Mac OS X 10.8 Mountain Lion when it’s released.
For the full story of what forced us to take this disappointing decision, keep reading.
From 1st March 2012, the Mac App Store will require all submitted applications to have application sandboxing enabled. Sandboxing runs the application in a controlled VM with little or no access to file, network or other resources unless they are specifically granted by the OS, which may be done by request of the application (if that’s provided), or via a privileged action dynamically granting permission, such as the Open File system dialog. The main aspects which impact SourceTree are as follows:
Sandboxed applications…
Sandboxing has a significant effect on SourceTree – the sandbox was designed mainly with a simple ‘document editing’ model in mind – ie that access to files would be granted by users explicitly opening them (thus granting explicit access via a user interaction, with the open file dialog being a privileged system component which cannot be altered by the application), and that the functional process is self-contained. However, not all applications work this way, SourceTree included.
Apple have notionally asked for developer feedback on this, and I and other developers have been raising ‘Radar’ issues on this for months. However, of the many issues I’ve raised since mid-2011, only a couple have been actually addressed (see the ‘Good News’ section below). The others sat in the queue for many months before finally receiving a dismissive ‘boilerplate’ response simply said ‘this is a known issue and we’re tracking it internally, please keep an eye on the release notes of future releases of OS X’. Obviously, this is not ideal. We’ve been hoping that this situation would be resolved before the deadline, but this is looking increasingly unlikely, and as such we feel it’s a good time to let you know what the position is for SourceTree.
Firstly, let’s talk about what the sandbox prevents us from doing in future.
Users can’t type paths anymore
The only way that access can be granted to files & folders now is if the user browses to them, or drag/drops them. SourceTree currently offers the ability to type or copy/paste paths directly into text boxes, and also has the ability to derive sensible defaults which make the users life far easier.
For example, in the current direct-download version of SourceTree, if you drag/drop, paste or type a URL into SourceTree, it automatically derives a default clone destination for you (and bookmark name), based on the default project folder you’ve selected in your Preferences and the trailing part of the clone URL. This is really convenient and is often what you want – all you have to do is press ‘OK’.
Under the sandbox, you’re not allowed to default these values, nor can you allow the user to type a destination path into the text box. The user is forced to use the File Open panel, even if they would have been quite happy with a default, or have a path or prefix in their clipboard that they wanted to use. I know from experience that many users prefer this approach, but Apple’s sandbox says we have to take it away. In practice, this means redesigning the dialog because it feels very forced to do it this way. This is a total backwards step in UX in my opinion, but required by the model.
Losing File Access on Restart
Edit: literally just after this post was released, Apple officially added documentation for a new API to restore access to previously bookmarked file resources. They’re sure cutting it fine, less than 2 weeks before the sandbox becomes mandatory! This doesn’t change our decision yet, but if they continue to improve things we may be able to revisit this.
Under the sandbox, the file access an application was previously granted based on user behaviour is reset every time it starts up. Only documents that were open in document windows, and which are restored by Lion, are available automatically.
A key function of SourceTree is to keep track of all your repositories in one place, and to instantly show you what the status is. This works fine with the sandbox when you first add the repositories, but when you restart the application all that access is lost, unless the repositories were open in full document windows (on Lion). Clearly, because SourceTree allows users to bookmark an unlimited number of repositories, which the user doesn’t want to have permanently open in full document windows, this is not acceptable – chances are we’ll be denied access to 90% of repositories in the bookmarks at restart, making the bookmarks view – a major differentiating feature of SourceTree – completely useless.
Many other developers do this sort of thing in their applications, and this has been acknowledged by Apple in response to bug reports raised by myself and others, but has now disappeared into the impenetrable blackness of their internal tracking system. The consensus right now is that apps should claim the temporary exception to the file access rule, effectively asking for full permission to any file. I’ll talk about the implications of using temporary exceptions later on.
Shared tool configuration will stop working
Currently when you use SourceTree, your SSH keys and agent configuration are automatically picked up, so access to remotes over SSH ‘just works’.
However, under the sandbox, the user home directory is ‘jailed’ inside the container, meaning that the standard SSH configuration is not available. All SSH access will fail unless the configuration is duplicated inside the container, and the SSH key loaded into the agent separately. Since the user home directory inside the container is only ever accessible when running SourceTree, none of the command-line tutorials for configuring SSH will work with SourceTree anymore, it will need its own, separate SSH configuration tool – another case of an unnecessary step being forced on the user.
You can’t even automate the initial process, say for example trying to copy the users existing setup (even though it would get out of sync if they changed it). This is because although a ‘migration’ option is made available for the sandbox, its only option is to move files into the container, it cannot copy them. So when I tried to use this for example, SSH configuration would work properly in SourceTree but it had deleted the original files in the real user home directory, something that would be extremely unpopular (understatement!).
The only real option is to force the user to import their keys. Helping them out with this is a bit tricky in itself, since all the standard Cocoa calls like NSHomeDirectory() point at the container, so we don’t know from there what their real home directory is, although some lower-level system calls seem to (currently) still expose this – I suspect this may be an oversight that will be corrected later.
The same issues exist with Mercurial, Git and Subversion. Configuration that the user has already performed won’t be automatically brought across, we’d have to prompt the user to configure everything manually, regardless of whether they’ve already configured the command line.
The short of it is that we can work around this, but the experience for the user is clunkier because they need to get involved more directly, and if they change their central configuration later they have to sync it up manually. The bottom line is that competing products that aren’t in the Mac App Store will give a better experience – if a user asks ‘how come <insert other DVCS client not on the Mac App Store> just picks up my configuration automatically but SourceTree doesn’t?’ – and I have no good answer to that other than ‘Apple made me do it’.
Integration with Terminal etc prohibited
Sandboxed applications aren’t allowed to send Apple Events – this is because by doing so they could perform actions that they themselves are not permitted to do. However since Apple Events are the primary way to provide application integration – it’s how SourceTree launches Terminal / iTerm and navigates to the project folder for example – disallowing it removes some very useful functionality.
Right now, you can ask for a temporary exception for specified applications so there is a workaround. However, see the section later on regarding the implications of using temporary exceptions.
I have raised a bug with Apple to ask them to consider prompting the user to give permission for sending Apple Events between apps, in the same way that access to the Keychain is granted. Again, this has been closed as ‘yeah we know’, with no indication of whether it will actually be resolved or not.
‘Open With’ is no longer allowed
When editing some files, such as the git/hg config files, SourceTree explicitly opens them with TextEdit rather than allowing the users file association. This is because I discovered that many users had weird associations on these files (presumably because they have no extension), so they might be opened in a Terminal instead for example.
Under the sandbox, you cannot ‘Open With’ anymore, it’s disallowed. You can only open files with their associated editor. This has other implications over and above the config files, it also means I can’t implement an explicit ‘Open With’ feature on the file list, which has been requested by users in the past.
Transfer of settings / licenses between App Store & Direct versions will fail
Currently if you downloaded SourceTree from the App Store, the license applies to the direct version and your settings are automatically kept in sync between the two, meaning it’s seamless to go back and forth between them. This is very useful if an App Store user wants to try out a beta version, or in the case where a hotfix is required.
Sandboxing does not allow this because access to the settings outside the container is prohibited. If a user tried to switch between the two systems, the settings/bookmarks would have to be recreated and they’d need to apply for a license separately. Not a major issue but it just feels a little shoddy.
First run of sandboxed application deletes previous configuration
The first time a user runs the sandboxed version from the app store, all the preferences are moved into the container and deleted from their original locations. This means the user can never go back to a previous build. Probably not serious, but worth noting.
Some of the above issues can be temporarily avoided by using exceptions that Apple make available – these are declarative entries in the applications property list which open up the sandbox more than the default. While this overcomes some issues in the short term, it has the following issues:
Therefore, even if we can ‘get by’ with the exceptions, having made all the sacrifices in usability terms as well, we may still find ourselves having difficulty getting updates through the App Store, and the landscape will continue to evolve.
Despite most of the issues I’ve raised with the sandboxing being closed without any satisfactory resolution, I did have one issue resolved that was a major problem for me – previously the sandbox would block termination of processes, even those that you’d launched from your application. This was a major problem for people clicking ‘Cancel’ in a clone window, because you couldn’t interrupt the clone task and it would continue running forever. Luckily, this has been fixed in 10.7.3.
Fundamentally, sandboxing is a good idea. Asking applications to be specific about what they need to do, and exposing that to the system and users for validation is a good idea for security.
The trouble is, the sandboxing implementation currently in place on Mac OS X Lion doesn’t allow for all the behaviours that real Mac applications do right now, behaviours which are not at all contentious, are approved in the Mac App Store already, and indeed are very much appreciated by users. Applications designed a certain way (mainly, those which edit documents on demand and don’t do much else) won’t have a problem since their behaviours are adequately catered for in the rights that can be applied for, but tools which perform more complex behaviour, particularly when that involves integrating with other apps and tools, do many things that simply aren’t catalogued in the sandbox. Also, forcing users to use a browse dialog for absolutely every file path is extremely clunky outside of the simplistic single document editing use case – it might provide a nice way for the sandbox to grant file permission, but from a UX perspective it’s incredibly constraining.
Being on the Mac App Store has always required a bit of extra effort and some inconvenience for developers, but it’s been worth it – the Mac App Store is a great distribution platform which users love, and any difficulty and inconvenience with the platform has been limited to us, the developers, barring making people wait a bit longer for updates. To comply with the sandbox as it’s currently specified, however, requires making SourceTree a worse experience for users – there are some temporary exceptions which mitigate this to a degree, but they’re still incomplete and liable to be taken away, with no indication of what the replacement might be (if anything).
We’ve agonised over this decision for months, but the bottom line is that the current sandboxing implementation is simply not compatible with a version of SourceTree that we’d be happy to release. We care a great deal about the experience our users have, and being forced to release what would be, in our view, a downgrade of the app is just not something we want to do. For this reason, we are not currently planning on submitting any more updates to the Mac App Store after 1st March. Our understanding is that the latest version at that time will remain in the Mac App Store for people who still wish to use it, but beyond that updates will be made only through direct download from the website, at least until something changes.
Our sincere hope is that Apple will address the shortcomings of the sandboxing implementation in the future, and allow us to request the kind of behaviours we need to maintain the features that SourceTree users know & love. Above all, we’d love Apple to talk to developers more openly about this, and give clearer guidance on how these issues are going to be dealt with. Judging by talk in the community, we’re far from the only developers wrestling with these kinds of problems.
Related reading:
A headline feature of SourceTree 1.3 is the support for submodules (in Git) and subrepositories (in Mercurial). The terms may be different, but they refer to the same concept; that of nesting other repositories within the folder structure of your own repository. The most common reason for wanting to do this is that your project has dependencies on other code bases (libraries for example), and you want to track those from their original sources rather than duplicating the files within your own repository.
For the sake of brevity from here on I’ll use the term ‘submodule’ to mean ‘subrepository’ as well, unless I’m talking about a Mercurial-specific feature.
Adding a new submodule to your project is simple, just right-click on a blank area of the sidebar and select ‘New Submodule’ (or select it from the Repository menu).
You’ll then be prompted to provide a source URL to clone the contents from, and the path within the current repository that this submodule will reside. Once the submodule has cloned, you’ll see it appear in the sidebar like this:
This tells you that your submodule is located in dependencies/sub1 and is currently on the ‘master’ branch. If you wanted to see more detail about the submodule, just double-click on it to open it in its own repository window, from which you can, if you like, make changes to it just like any other repository. Submodule entries can also have annotations to let you know if there are uncommitted changes in the submodule (ellipsis annotation, i.e. ‘…’), or incoming / outgoing changes (up/down arrow).
In this case you’ve just added the submodule, but it’s not actually committed yet. You’ll see in the file status view that a couple of entries have been staged:
In Mercurial, there will be a “.hgsub” file instead but the principle is the same. These uncommitted changes represent the addition of the submodule to your repository, and you must commit & push them as you would do with any other change. Once you’ve done this, anyone cloning the repository will also get the submodule, at the same commit.
Submodules are likely to be more static than your own main repository, but there are still several tasks related to them that you may want to do:
Change the submodule commit which your repository is tracking
Submodules are pinned at a given commit, so that you always get the expected version of the submodule contents. If there are new changes in the submodule which you want to use in your repository, all you have to do is open the submodule (double-click) and checkout/update to a different commit, either via pull, merge or just manually checking a commit out – just as you would do normally with any other repository. Once you have done this, return to the parent repository and you will see an uncommitted change on the submodule, which will show in the diff the change in tracked commit:
Again, you commit & push this change just like any other, after which point the submodule contents will be pinned at this new commit.
Commit / push changes to a submodule together with parent repository
If you have write access to the upstream submodule source (and if not, maybe you might fork it and change the submodule source, see below), you may sometimes update files in the submodule, and want to commit / push those changes at the same time as you commit / push changes to your parent repository.
Mercurial actually requires this, by default it automatically commits subrepository changes when you commit the parent, using the same commit message. However, that’s often not what you want – there’s a good chance you’ll want a different commit message for the submodule change. Luckily, SourceTree makes that really easy – when you try to commit the parent, if there are uncommitted changes in submodules you’ll get a prompt telling you so, like this:
From this dialog you can click the ‘Commit’ button next to the submodule and commit those changes with a message of your choosing, separate to the parent repo commit message. In Git, the ‘Skip’ button at the bottom is enabled so you can just leave the changes uncommitted if you like, but Mercurial doesn’t allow this.
Change the source URL for a submodule
A submodule definition includes the URL which people cloning the parent repository will retrieve the submodule content from. Sometimes, you might want to change this – a common example is if you were using a 3rd party library which you had only read-access to, but later decided to fork it and make your own changes. In this case, you’ll want to change the source URL to your fork for all future clones / updates. In SourceTree this is easy, just right-click on the submodule and select “Change Source URL”. You’ll need to commit and push the change as normal, but after that your fork will be the source for the submodule.
This has been a quick introduction to the submodule and subrepository support in SourceTree 1.3. It’s designed to make your life easier when managing projects with their dependencies and other project groupings, we hope you like it!