skip to Main Content

I am writing some code where MATLAB queries Git tags:

[status, cmdout] = system("TERM=xterm; git tag -l")

On my Windows 11 partition, where I wrote the code in the first place, this works fine, I get a newline-separated list of tags. On my Ubuntu partition, however, the command output is

'[?1h=
     mytag[m
     
     [K[?1l>'

(mytag is the only tag present. On W11, the output was just mytag)
which, decoded, is apparently

'x1B[?1hx1B=x13mytagx1B[mx13x10x13x1B[Kx1B[?1lx1B>'

or

'<ESC>[?1h<ESC>=rmytag<ESC>[mrnr<ESC>[K<ESC>[?1l<ESC>>'

I’ve found out that these <ESC>[... sequences are escape sequences for formatting and text color. Most of them are ANSI escape sequences, however it seems that <ESC>= and <ESC>> are XTerm-specific.

I thought at first that it was a difference in how bash and cmd return their output to MATLAB*, but I tested this by making my own program that prints "hello, world" with colored writing and calling it from MATLAB in both OSes, and the ANSI sequences show up literally on Windows, too. So it looks like it’s Git that is behaving differently, although it could be something else.

I’ve started working on a Regex to just strip all of these out, but all those carriage returns that Git inserted break a bunch of my code (it uses numerous Git commands. Don’t ask why), and I think I’ll end up creating some very brittle and ugly code unless I figure out how to make Git just print out the same plain output as it does on Windows.
If I don’t prefix my Git command with TERM=xterm, the default terminal mode is dumb, which you’d think is exactly what I want. However, if you do this, Git prints out a warning

WARNING: terminal is not fully functional
Press RETURN to continue

and it doesn’t look like the MATLAB system command can be used to answer this prompt, also the prompt only occurs on some commands, and finally Git still includes one ANSI sequence (and those damned line breaks) in the git tag -l output even when I use dumb mode, so it’s useless anyway.

So – is it possible to prevent Git from printing out anything except plain text, but without requiring manual confirmation on some commands? Why did all of this work so easily on Windows – is Git even at fault?
Any explanation on why I even get the different behavior between Ubuntu and Windows at all, better approaches to solve this, or whatever might help, are very welcome.

* that is how it works, right? system starts a bash/cmd process, feeds it the command string, and then collects its output?

2

Answers


  1. I would use the --no-color option as it’s the portable, shell-independent, way to turn off coloring. You can combine that with setting environment variables, like TERM, in the MATLAB system command.

    [status, cmdout] = system("git tag -l --no-color", "TERM", "dumb")
    

    Or set the prompt to something without escape sequences if it’s the prompt that causes the problems. This will only affect shells like that uses PS1 for the prompt:

    [status, cmdout] = system("git tag -l --no-color", "PS1", "mytag",
                                                       "PROMPT_COMMAND","")
    

    Other options for git:

    1. Turn off the specific coloring you don’t want. Here are a few:
      git -c color.ui -c color.branch 
          -c color.diff -c color.interactive -c color.status git-command
      

      E.g., color.ui here means the same as color.ui=false, but with less typing.

    2. Turn off coloring globally by changing your ~/.gitconfig. This will however affect your normal interactive shells too. Here are all options as of git v2.43.0:
      [color]
          advice = false
          branch = false
          diff = false
          grep = false
          interactive = false
          pager = false
          push = false
          remote = false
          status = false
          transport = false
          ui = false
      
    Login or Signup to reply.
  2. If MATLAB is setting up commands to run on a pty, you can make Git not talk to a pty with git tag -l | cat. Then you don’t have to care about the terminal type.

    You could also eliminate the human-convenience transform by using a core command, not a convenience one: git for-each-ref --format='%(refname:short)' refs/tags, core commands are built for scriptable and reliable output.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search