Sublime Forum

Git p4 / custom menu entries

#1

I’d like to use a handful of commands like git p4 submit or git p4 rebase from within Sublime Merge. Here’s what I’ve tried: Preferences->Browse Packages… then in the User directory I added a file gitp4.sublime-menu:

[
    {
        "id": "repository",
        "children":
        [
            { "command": "git p4 sync", "caption": "git p4 sync" },
        ]
    }
]

I would expect a new entry to appear in the Repository menu, but there is nothing. What’s wrong? Is there a console or log or anything to debug this?

0 Likes

#2

There isn’t currently a console in Merge; if you’re on Linux you can run it with the --debug command line argument to open it and have it dump it’s console to the terminal though. In any case there are a couple of reasons why this isn’t working for you.

The first is that arbitrarily named sublime-menu files aren’t allowed (or more specifically, are just completely ignored). Each of the menus in the application have specifically named files; the menu that pops up when you open the context menu on a commit is Commit.sublime-menu, the one for branches is Branch.sublime-menu and so on. There is a list of all of them on this page of the documentation.

The Repository menu is under the main menu, so your file needs to be named Main.sublime-menu in this case.

Once you do that, if you happen to be on Linux and use the command above, you see the following in the console every time you try to open the menu:

:0         Unable to parse command: git p4 sync
:0         Unable to parse command: git p4 sync
:0         Unable to parse command: git p4 sync

This is an indication that the command entry in the menu item is broken. The command entry in the menu has to be the name of an internal command, but in your example it’s a command line. Based on the message I would guess that the reason it can’t parse the command is that it contains spaces, which is not allowed.

To execute an arbitrary git command you use the git command with an argv that tells it what to execute. In the case of your command above, that would look something like this:

[
  {
    "id": "repository",
    "children":
    [
      {
        "caption": "-",
      },
      {
        "caption": "git p4 sync",
        "command": "git", "args": {
          "argv": ["p4", "sync"]
        }
      }
    ]
  }
]

Here the command is git and the args for the command contains the argv argument that specifies what command line should be passed to git when it executes.

The items that this adds are tacked onto the end of the default menu items:

Because of this, the example above also includes an additional item with just a caption of - which adds a separator prior to this command when it appears in the menu to give it a little visual separation from the prior items, which is purely optional and up to you.

1 Like

#3

Oh wow, thank you so much! That got me closer. I can now see menu entries, that’s great!

In the preferences I have changed the git binary to system, so that I can use the git p4 alias that I have already set up.

alias.p4=!'C:\Python27\python.exe' 'c:\program files\Git\mingw64\libexec\git-core\git-p4'

Unfortunately I get an error when I run it:

Traceback (most recent call last):
  File "c:\program files\Git\mingw64\libexec\git-core\git-p4", line 4163, in <module>
    main()
  File "c:\program files\Git\mingw64\libexec\git-core\git-p4", line 4113, in main
    cmd = klass()
  File "c:\program files\Git\mingw64\libexec\git-core\git-p4", line 2592, in __init__
    if gitConfig('git-p4.largeFileSystem'):
  File "c:\program files\Git\mingw64\libexec\git-core\git-p4", line 793, in gitConfig
    s = read_pipe(cmd, ignore_error=True)
  File "c:\program files\Git\mingw64\libexec\git-core\git-p4", line 206, in read_pipe
    (retcode, out, err) = read_pipe_full(c)
  File "c:\program files\Git\mingw64\libexec\git-core\git-p4", line 197, in read_pipe_full
    p = subprocess.Popen(c, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=expand)
  File "C:\Python27\lib\subprocess.py", line 386, in __init__
    errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr)
  File "C:\Python27\lib\subprocess.py", line 509, in _get_handles
    p2cread = _subprocess.GetStdHandle(_subprocess.STD_INPUT_HANDLE)
WindowsError: [Error 6] The handle is invalid

Any ideas?

0 Likes

#4

After finding this, I added stdin=subprocess.PIPE, to every subprocess.Popen in the git-p4 Python source, and now it works both from the console as well as from within SM.

1 Like