SourceTree

Custom actions – more power to you

By on February 8, 2012

SourceTree 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

  • Mike Jennings
    Posted March 27, 2012 at 7:27 pm | Permalink

    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?

    • Posted July 2, 2012 at 10:40 am | Permalink

      Did you ever get a response?

    • Anonymous
      Posted July 6, 2012 at 1:27 am | Permalink

      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).

  • cc
    Posted May 8, 2012 at 10:20 pm | Permalink

    How about a custom action for IntelliJ

  • Kashifhisam
    Posted July 4, 2012 at 8:39 am | Permalink

    What will be the custom action to open project in Xcode?

    • Anonymous
      Posted July 6, 2012 at 1:35 am | Permalink

      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.

  • Posted August 8, 2012 at 7:02 am | Permalink

    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:-(

    • Anonymous
      Posted August 8, 2012 at 9:10 am | Permalink

      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 

  • Marco
    Posted August 28, 2012 at 9:45 am | Permalink

    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

  • Laurens Holst
    Posted September 4, 2012 at 3:23 am | Permalink

    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.

    • Laurens Holst
      Posted September 4, 2012 at 4:06 am | Permalink

      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).

      • Laurens Holst
        Posted September 4, 2012 at 7:18 am | Permalink

        The first two lines should be:

        email=$(git log -1 –format=”%an ” $1)
        subject=$(git log -1 –format=”Re: %s” $1)

  • Posted September 23, 2012 at 3:34 am | Permalink

    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

    • Mauro
      Posted January 18, 2014 at 9:48 pm | Permalink

      Is there a way to pass it the relative sublime-project file?

  • Anonymous
    Posted May 22, 2013 at 10:52 am | Permalink

    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

    • Gabe Shackle
      Posted May 5, 2014 at 1:27 pm | Permalink

      This would be very useful!

    • Tonni Tielens
      Posted July 10, 2014 at 2:45 am | Permalink

      Very useful indeed!

    • Pat Sissons
      Posted November 30, 2015 at 10:26 am | Permalink

      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.

    • Robson Filho Colodeti
      Posted December 17, 2015 at 3:06 am | Permalink

      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.

  • Robin Wilson
    Posted June 21, 2013 at 7:33 am | Permalink

    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

  • Petruza
    Posted August 14, 2013 at 7:11 am | Permalink

    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.

  • Rafa Carmona
    Posted November 6, 2013 at 1:02 am | Permalink

    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!

    • Anonymous
      Posted November 6, 2013 at 4:06 am | Permalink

      $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.

      • Rafa Carmona
        Posted November 6, 2013 at 7:07 am | Permalink

        Hi. thank you!
        Solution , diff.bat, only line;
        git difftool %1 %3

  • Ralph Callaway
    Posted November 15, 2013 at 12:49 pm | Permalink

    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]’

    • Anonymous
      Posted November 18, 2013 at 5:56 am | Permalink

      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.

      • Ralph Callaway
        Posted November 18, 2013 at 4:59 pm | Permalink

        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!

  • Jon
    Posted December 6, 2013 at 2:51 pm | Permalink

    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.

  • Mauro
    Posted January 18, 2014 at 9:14 pm | Permalink

    typo

  • Daniel
    Posted February 3, 2014 at 10:32 am | Permalink

    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!

    • Anonymous
      Posted February 4, 2014 at 1:58 am | Permalink

      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?

  • ghands1
    Posted March 20, 2014 at 2:52 pm | Permalink

    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++

    • Anonymous
      Posted March 21, 2014 at 3:42 am | Permalink

      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.

      • ghands1
        Posted March 21, 2014 at 6:43 am | Permalink

        Thanks so much Steve. That works perfectly!

        • Richard Sewell
          Posted February 25, 2015 at 11:05 pm | Permalink

          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)

  • A
    Posted June 5, 2014 at 6:34 am | Permalink

    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. 🙂

    • Anonymous
      Posted June 5, 2014 at 8:02 am | Permalink

      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.

  • Herman Near
    Posted August 1, 2014 at 6:46 pm | Permalink

    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?

    • Anonymous
      Posted August 4, 2014 at 1:48 am | Permalink

      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.

      • Herman Near
        Posted August 8, 2014 at 11:00 pm | Permalink

        I’ll try it again, read up on more things, hopefully this should do it.

  • Github Training
    Posted May 10, 2015 at 2:38 am | Permalink

    I added an example post of how to add git clean using custom actions
    http://githubtraining.com/custom-actions-in-sourcetree-example-setup/

  • Lord Worfin
    Posted February 29, 2016 at 4:34 pm | Permalink

    More power to you, Buckaroo Banzai!

  • Jinzoe
    Posted August 2, 2016 at 4:01 am | Permalink

    What is the script extension type?

  • Alex Fung
    Posted August 29, 2016 at 8:37 pm | Permalink

    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