Search code examples
bashgitmatlabansi-escapexterm

Can I Prevent Git from Using XTerm Escape Sequences?


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[?1h\x1B=\x13mytag\x1B[m\x13\x10\x13\x1B[K\x1B[?1l\x1B>'

or

'<ESC>[?1h<ESC>=\rmytag<ESC>[m\r\n\r<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?


Solution

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