The short version of 'git status' and the close but different '--porcelain' mode

2 min read

This post is part of my Today I learned series in which I share all my learnings regarding web development.

A while back I came across a tweet by Ben Lesh and he mentioned a CLI flag for the git status command I didn't know – --porcelain.

When you execute git status with this flag the result looks as follows:

> git status --porcelain
 M nuxt.config.js
 M package-lock.json
 M package.json
?? untracked.file

This is pretty nice. I use git for quite a while now and I usually go with the "normal" git status command whose output is a little bit more verbose.

> git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

    modified:   nuxt.config.js
    modified:   package-lock.json
    modified:   package.json

Untracked files:
  (use "git add ..." to include in what will be committed)


no changes added to commit (use "git add" and/or "git commit -a")

The problem with this is that it shows a lot of help and information I'm actually not interested in. I think I'll go with the compact version from now.

But what is this porcelain flag about?

I started reading the docs and found out that there is also the -s or --short flag.

> git status -s                                                                                                                                                                                  
 M nuxt.config.js
 M package-lock.json
 M package.json
?? untracked.file

On the first look, these seem to be very similar, but there is one difference that is only visible in my terminal.

Git status -s vs git status --porcelain

git status -s highlights the characters that give information on the status of a certain file so that it's easier to read. This is missing when using --porcelain.

So why's that? It turns out that --porcelain is used to get output that is easily parseable by a script. Imagine you run some automation that has to check the status of a git repository first. What you don't want to have is help text and terminal colors included in the output then.

And what you also don't want is that the output changes or differs from git version to git version. --porcelain also guarantees that there won't be backwards incompatible changes to the output so that your scripts won't break with a git update. That's really cool!

The last thing I learned is also that --porcelain comes with different included versions (remember the backwards compability promise). Without a defined version --porcelain uses the v1 format which you see above. There is also a v2 available which looks like that:

> git status --porcelain=v2
1 .M N... 100644 100644 100644 9f49fa176b56de04416172603c0f8e623706cf7a 9f49fa176b56de04416172603c0f8e623706cf7a nuxt.config.js
1 .M N... 100644 100644 100644 7042578104220c9fa983a749e8f87d488a7a9e80 7042578104220c9fa983a749e8f87d488a7a9e80 package-lock.json
1 .M N... 100644 100644 100644 823ac73a97a0f9c9c73e9bd775bd3421d7a2940c 823ac73a97a0f9c9c73e9bd775bd3421d7a2940c package.json
? untracked.file

v2 includes more additional information.

For advanced automation using git, --porcelain definitely can be very useful. The flag is also available e.g. for commands like push or blame.

Really cool! 🎉


Load time