Custom actions – more power to you
By Steve on February 8, 2012SourceTree 1.3’s new ‘Custom Actions’ feature lets you extend the range of actions you can perform from within the GUI, effectively adding your own commands. Maybe you have scripts that you’d like to call, or external tools that you’d like to use beyond what SourceTree already allows for – Custom Actions are the way to go.
As a simple example, let’s say you use TextMate for editing files in a project, and you wanted to assign a keyboard shortcut to open the root of the repository in TextMate? SourceTree doesn’t provide an in-built option for that, so let’s add it using Custom Actions.
Firstly, open the Preferences window, and select the ‘Custom Actions’ tab:
Click ‘Add’, and fill in the details as follows (to fill in the keyboard shortcut, just lick on the shortcut area and type a keyboard combination):
Notice how all I had to do was specify the location of the script I wanted to run, and then give it some parameters – in this case ‘$REPO’ which is the path to the repository.
After I click OK, an ‘Open in TextMate’ option will appear on the top-level Actions menu under the Custom Actions section:
Or, I can just press Shift-T to open my repository in TextMate whenever I want.
If you use the $FILE or $SHA parameters, then these will cause the action to appear on context menus associated with files or commits, and will pass that context to the command. So for example you could have a deployment script which took the $SHA parameter, then right-click on a commit and run your deployment script for that specific commit right from within SourceTree.
Custom Actions are a great new way to extend SourceTree to work with your own scripts and tools, and improve your productivity!
48 Comments
I’m a QA guy who browses SourceTree to develop release notes and focus testing. What is the best way to add a Custom Action that exports selected commits (user, date, description, tags) to tab-delimited text?
Did you ever get a response?
Sorry for missing this comment until now. This depends on what VCS you’re using, but generally you want to call ‘git log’ or ‘hg log’, and provide it with the –format (git) or –template (hg) parameter. You can find the exact specifications in the respective man pages. To spool the result to a file, the best way is to wrap this in a script which redirects the output of the command to a file (you can’t do this inside the Custom Action because output redirection is a shell feature, but using an intermediate script lets you do that).
How about a custom action for IntelliJ
What will be the custom action to open project in Xcode?
Here’s one way:
Script to run: /usr/bin/open
Parameters: $REPO/YourProjectName.xcodeproj
If you want to you can get smarter and instead of calling ‘open’ directly you can call an intermediate script which does a glob for any named .xcodeproj. You can’t use wildcards in the parameters here because globs are processed by the shell, but an intermediate script which uses a glob or determines the name of the project another way could do this.
I created a small automator workflow and used its command line interface to set the $REPO as the input variable.
Workflow Steps
1. Set Value of Variable
2. Get Value of Variable
3. Get Folder Contents
4. Filter Finder Items
5. Open Finder Items
Custom Action in Source Tree
Script: automator
Parameters: -D VariableName=$REPO /Path/To/Workflow.workflow
Thanks, I write a blog for this. http://tuchangwei.github.io/2014/10/17/How-to-open-the-xcode-project-directly-when-we-use-SoureTree/
This is an awesome feature! Unfortunately I’ve had a problem… I want to do this:
git diff –name-only SHA1 SHA2
So that when I select two commits, I want to see a list of files that have changed between them. And it seems this sort of works since it contains both SHAs:
git diff –name-only $SHA
But Source Tree seems to output this: (because of the space character?)
git diff –name-only “1d150e8485003d1e32703a45b3698ef09a32fae4 9f033ee4f42138dcaff9feaa183e8702b5424e64” So git complains:
fatal: ambiguous argument ‘1d150e8485003d1e32703a45b3698ef09a32fae4 9f033ee4f42138dcaff9feaa183e8702b5424e64’: unknown revision or path not in the working tree.
Use ‘–‘ to separate paths from revisions:-(
Aha, I suspect this is Cocoa trying to be helpful and automatically quoting the multiple SHAs, I’ll need to make it not do that! Well spotted.
Logged here: https://jira.atlassian.com/browse/SRCTREE-1158
Great feature, but it would be even cooler if there would be a %LINENUMBER Parameter or similar, which would be effective if a Hunk in a file is selected, so I could jump to the specific line in the editor (TextMate e.g. supports this in the mate command with -l ), if multiple files are selected or no hunk, then the Parameter would simply be null / empty
Regards Marco
That’s an interesting one, I hadn’t thought of that. And yes, great idea. Logged here for future hackery: https://jira.atlassian.com/browse/SRCTREE-1180
I made a “Reply by email” action which invokes the following bash script:
open “$(git show –format=”mailto:%ae?subject=Re: %s&body=Comments in-line below.” $1 | sed -E “s/^([^m])/> 1/”)”
This allows you to easily send code reviews.
Better version that doesn’t crap out on & characters:
#!/bin/bash
email=$(git log -1 –format=”%an “)
subject=$(git log -1 –format=”Re: %s”)
body=$(git diff $1^..$1 | sed “s/^([^m])/> 1/” | sed “s/ / /g” | sed “s/ / /g”)
email=”$(perl -MURI::Escape -e ‘print uri_escape($ARGV[0]);’ “$email”)”
subject=”$(perl -MURI::Escape -e ‘print uri_escape($ARGV[0]);’ “$subject”)”
body=”$(perl -MURI::Escape -e ‘print uri_escape($ARGV[0]);’ “$body”)”
open “mailto:$email?subject=$subject&body=$body”
The first body sed prefixes the diff with quote marks (>), the second replaces tab characters with four spaces and the third replaces pairs of spaces with alternating nonbreaking spaces (I don’t know how to use character escapes in sed so I just wrote them literally).
The first two lines should be:
email=$(git log -1 –format=”%an ” $1)
subject=$(git log -1 –format=”Re: %s” $1)
To add a custom action: “Open in Sublime Text 2” type
/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl
in “Script to run”
and type
$FILE
in “Parameters” box.
Source http://www.sublimetext.com/forum/viewtopic.php?f=2&t=5449
Is there a way to pass it the relative sublime-project file?
How about a $BRANCH variable to inject the currently checked out branch into the command? I have a custom action for force-push that I run after doing an interactive rebase of a dev branch from the master/rc branches in my project, but I always have to fetch and update any other remotely-tracked branches before I do it or risk clobbering them with the global forced-push.
Would be great to be able to just have it be this:
git –force push $BRANCH
This would be very useful!
Very useful indeed!
You can simulate $BRANCH by writing $(git symbolic-ref HEAD)
NOTE: this requires that you have git on your local PATH, otherwise you would need to fully qualify the git command above.
I know it has been 3 years, but you can use “git push origin HEAD -f” to push your current branch to origin, so this will automatically push to your tracked remote branch or will create a new branch in the origin.
Is this available in the current Windows version? I can’t see it in any of the menus, but it’d be really handy for me.
Cheers,
Robin
Not yet, we’ll get there! You can watch this item to know when it’s ported. https://jira.atlassian.com/browse/SRCTREEWIN-42
If you hook a shell script here, don’t forget to add the shell specifier, such as #!/bin/bash, or else although it works from the shell it won’t work when called from Sourcetree.
Fantastic!
But, I find create this command; git difftool 3c31223 FILE.TXT
This command i use for modify my actual file from my tool compare. Sourcetree create allways file temp, and not is possible modify from SourceTree.
But if I create Custom $FILE have path and $SHA have 2 two hash.
Is posible have $SHA1 and $FILEONLY ? Or who create this command ? Thanks!
$SHA would only have 2 hashes if you selected 2 commits at the same time. If you do want to select 2 commits but want to only use one of them, you should use a .bat wrapper and use only one of the commit parameters instead.
Hi. thank you!
Solution , diff.bat, only line;
git difftool %1 %3
So cool, but not getting any output if I’m piping the results. Any tricks to work with pipes?
this gives results
$ git ls-files -v
But if I filter for assume unchanged I don’t get any output 🙁 ?
$ git ls-files -v | grep ‘^[a-z]’
This is because piping (and also output redirection if you used it) is a shell function, so if you call git directly you’re not actually doing it via a shell so piping isn’t available. You need to either call ‘cmd’ as the target and pass it the other command via the /c option, or wrap your command in a batch file which you use as a target instead, which should automatically run via cmd.
Thanks for the tip, ended up being able to make this work by creating a git alias and using that.
alias.assumed=!git ls-files -v | grep ^h | cut -c 3-
Then I can the custom action just directly references the alias. Problem solved!
We use this to link out to the web by pointing to a bat script with:
Script to run: openurl-SOMEREPONAME.bat
Paramaters: $SHA#chg-$FILE
openurl-SOMEREPONAME.bat:
start https://bitbucket.org/OURACCOUNTNAME/AHARDCODEDREPONAME/commits/%1
(SOMEREPONAME and AHARDCODEDREPONAME in the example are actual hard-coded names)
That works really well. And SourceTree knowing which context menu to add the custom action item to (at the commit or file level) based on which parameters are used in the custom action parameter list, is cool.
My additional feature request would be a way to add custom parameters (for use in the custom action parameters list) to the repo settings in SourceTree, so we don’t have to create separate batch files (and copies of menu action items) for each repo since the web repo names don’t match our local repo paths.
typo
If I have multiple commits selected I noticed that they get saved in SHA1 SHA2 etc, is there a way to just get the first and last? Also I noticed that if I select 4 commits, then I have SHA1, SHA2, SHA3, SHA4 with values when I run my custom action. If I then select 2 commits, SHA3 and SHA4 have the old values and are not cleared!
If you want to manipulate the parameters then you need to build that into a script (you could use bash, python, whatever) which you call as your custom action. I’m not sure what you mean about SHA3/SHA4 not being ‘cleared’, there is no state in our custom actions, they just call a command with parameters, perhaps you mean the state you’re saving remains?
Can any Windows users suggest what to type in order to open a selected file in Notepad++ as a Custom Action? I tried …Program FilesNotepad++notepad++.exe and it almost worked… It actually does bring up Notepad++ in which I can edit and do what I want, but SourceTree seems to perpetually be processing the request. If I click cancel on the SourceTree window, then it will shut down Notepad++
The reason is that SourceTree waits for the custom action to terminate, this is important if the action was doing something that should then be reflected in SourceTree, but in your case you’re wanting to launch something in parallel. There are several ways to do this but the easiest is probably to use the Windows ‘start’ command line tool, which by default launches programs without waiting for them to terminate. It also has the advantage that it searches for programs for you so you don’t have to specify the full path if it’s in a default location. There’s a slight complication in that you do have to run this via the command shell. So you should change your custom action to ‘cmd’ as the script, and ‘/C start notepad++ $FILE’ for the params.
Thanks so much Steve. That works perfectly!
If you need to specify a path with a space its a bit more complex to get the inverted commas right… this works as of today (Feb 2015)
In 1.5.2.0 version I can’t see any way to specify keyboard shortcut (there’s no shortcut area). By the way, there’s a typo in the instructions (“just lick on the shortcut area and type a keyboard combination”) – I’m affraid that licking doesn’t help. 🙂
This blog post was written for the Mac version before the Windows version existed; unfortunately we haven’t come up with a nice way to do customisable shortcuts on the Windows version yet, sorry.
My custom actions in sourcetree always prepend actions with the git command, I can’t do git-ftp with it.
instead of going git-ftp -u -p
I always see
git git-ftp -u -p
Any solutions?
Are you sure ‘git’ isn’t in the command section & git-ftp isn’t in the args? I can run non-git custom actions here just fine.
I’ll try it again, read up on more things, hopefully this should do it.
I added an example post of how to add git clean using custom actions
http://githubtraining.com/custom-actions-in-sourcetree-example-setup/
More power to you, Buckaroo Banzai!
What is the script extension type?
The (regular) context menu of a file has “Open current Version” and “Open Selected Version. If I choose Open Current Version, SourceTree will really open the file of that commit stored inside the .git tree. It is nice, but only “open” is supported. Edit or Browse would be much more useful (so I can see the whole file instead of just the hunk on the right, and also to copy lines from it, without checking out that commit). How do I get the path name of that file and use it in custom action?
4 Trackbacks
[…] to common functions without having to open the full repository window first. You can even invoke Custom Actions directly from the […]
[…] to common functions without having to open the full repository window first. You can even invoke Custom Actions directly from the […]
[…] window with Action Menus. Click the gear to jump to the repository folder in Finder or launch a Custom Action you’ve […]
[…] using SourceTree (for Mac OSX) to manage my Git repositories, which has a “Custom Action” feature fortunately that can execute shell scripts with some parameters passed in about the […]