338

In a Makefile, I'd like to perform certain actions if there are uncommitted changes (either in the working tree or the index). What's the cleanest and most efficient way to do that? A command that exits with a return value of zero in one case and non-zero in the other would suit my purposes.

I can run git status and pipe the output through grep, but I feel like there must be a better way.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Daniel Stutzbach
  • 74,198
  • 17
  • 88
  • 77
  • 6
    possible duplicate of [Checking for a dirty index or untracked files with Git](http://stackoverflow.com/questions/2657935/checking-for-a-dirty-index-or-untracked-files-with-git) – jb. May 30 '14 at 20:57
  • There's a great answer here: [Unix & Llinux: Determine if Git working directory is clean from a script](https://unix.stackexchange.com/a/155077/114401) – Gabriel Staples Aug 08 '22 at 20:48

11 Answers11

373

UPDATE: the OP Daniel Stutzbach points out in the comments that this simple command git diff-index worked for him:

git update-index --refresh 
git diff-index --quiet HEAD --

A more precise option would be to test git status --porcelain=v1 2>/dev/null | wc -l, using the porcelain option.
See Myridium's answer.

(nornagon mentions in the comments that, if there are files that have been touched, but whose contents are the same as in the index, you'll need to run git update-index --refresh before git diff-index, otherwise diff-index will incorrectly report that the tree is dirty)

You can then see "How to check if a command succeeded?" if you are using it in a bash script:

git diff-index --quiet HEAD -- || echo "untracked"; // do something about it

Note: as commented by Anthony Sottile

git diff-index HEAD ... will fail on a branch which has no commits (such as a newly initialized repository).
One workaround I've found is git diff-index $(git write-tree) ...

And haridsv points out in the comments that git diff-files on a new file doesn't detect it as a diff.
The safer approach seems to be to run git add on the file spec first and then use git diff-index to see if anything got added to index before running git commit.

git add ${file_args} && \
git diff-index --cached --quiet HEAD || git commit -m '${commit_msg}'

And 6502 reports in the comments:

One problem I bumped in is that git diff-index will tell that there are differences when indeed there is none except for timestamps of the files.
Running git diff once solves the issue (surprisingly enough, git diff does actually change the content of the sandbox, meaning here .git/index)

These timestamp issues can also occur if git is running in docker.


Original answer:

"Programmatically" means never ever rely on porcelain commands.
Always rely on plumbing commands.

See also "Checking for a dirty index or untracked files with Git" for alternatives (like git status --porcelain)

You can take inspiration from the new "require_clean_work_tree function" which is written as we speak ;) (early October 2010)

require_clean_work_tree () {
    # Update the index
    git update-index -q --ignore-submodules --refresh
    err=0

    # Disallow unstaged changes in the working tree
    if ! git diff-files --quiet --ignore-submodules --
    then
        echo >&2 "cannot $1: you have unstaged changes."
        git diff-files --name-status -r --ignore-submodules -- >&2
        err=1
    fi

    # Disallow uncommitted changes in the index
    if ! git diff-index --cached --quiet HEAD --ignore-submodules --
    then
        echo >&2 "cannot $1: your index contains uncommitted changes."
        git diff-index --cached --name-status -r --ignore-submodules HEAD -- >&2
        err=1
    fi

    if [ $err = 1 ]
    then
        echo >&2 "Please commit or stash them."
        exit 1
    fi
}
nstenz
  • 117
  • 1
  • 5
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 12
    The "plumbing vs. porcelain for scripting" principle is a lesson that [Jakub Narębski](http://stackoverflow.com/users/46058/jakub-narebski) repeatedly mentioned to me: " [How to list all the log for current project in git ?](http://stackoverflow.com/questions/2978947/how-to-list-all-the-log-for-current-project-in-git/2979124#2979124) ", " [git: changelog day by day](http://stackoverflow.com/questions/2976665/git-changelog-day-by-day/2976776#2976776) ", ... – VonC Oct 07 '10 at 06:11
  • 19
    After clicking some of the links you suggest, I found what I was looking for: `git diff-index --quiet HEAD`. – Daniel Stutzbach Oct 07 '10 at 14:46
  • 11
    @DanielStutzbach: That might fail if you have a file called `HEAD` in the working directory. Better use `git diff-index --quiet HEAD --`. – David Ongaro May 24 '14 at 17:11
  • 2
    New (untracked) files are not detected by proposed function require_clean_work_tree. I needed to detect any change (even forgotten new files), so I chose Nepthar's answer: `[[ -z $(git status -s) ]]` – 4LegsDrivenCat Jun 08 '15 at 15:58
  • @4LegsDrivenCat OK. Do you have an example which illustrates that issue? On which platform do you see this? What version of Git are you using? – VonC Jun 08 '15 at 16:01
  • git version 1.9.1. Ubuntu 14.04.2 LTS. To reproduce, just create new file. – 4LegsDrivenCat Jun 08 '15 at 16:08
  • @4LegsDrivenCat OK. I just realized I wrote that answer 5 years ago. It was Git 1.7.3 back then. – VonC Jun 08 '15 at 16:11
  • @4LegsDrivenCat Do you have any suggestion to fix the function in order to detect new untracked files? – VonC Jun 08 '15 at 16:12
  • @VonC No. As I said, checking for empty output of "git status --short" worked for me (detects staged, modified and new files), so I didn't dig deeper. – 4LegsDrivenCat Jun 08 '15 at 16:16
  • 8
    And yet the manual at `git status --help` states: **--porcelain** _Give the output in an easy-to-parse format for scripts. This is similar to the short output, but will remain stable across Git versions and regardless of user configuration. See below for details._ – Ed Randall May 24 '16 at 15:13
  • 1
    @EdRandall You're right, the git documentation seems to contradict itself! I guess relying on the output format of `git status --porcelain` in a script isn't so bad after all. – theDmi Jul 04 '16 at 11:33
  • 2
    @theDmi Actually it makes sense: "the meaning of --porcelain here is "produce output suitable for consumption by porcelain scripts". See the end of my answer at http://stackoverflow.com/a/6978402/6309. So yes, `git status --porcelain` is good for scripting. – VonC Jul 04 '16 at 11:35
  • 8
    @VonC that really makes no sense. This way you can twist everything into its reverse. --porcelain gives you the impression it is going to break soon. If it isn't, it should be called plumbing, not porcelain. Using --porcelain causes your script not to break, which renders it NOT a porcelain script ;-). If you wanted your script to break, you shouldn't use --porcelain!!. So it completely incomprehensible this and throws everyone off. – Xennex81 Jul 31 '16 at 22:30
  • @VonC but usually these flags are just called --script or something similar. Because of this I consider --porcelain a flag that could easily change in the future ;-). – Xennex81 Jul 31 '16 at 22:35
  • 1
    @Xennex81 I agree. This is named that way for historical reason (2010) See http://git.661346.n2.nabble.com/git-status-porcelain-is-a-mess-that-needs-fixing-tp4878858p4880785.html (look for "this is my fault") – VonC Aug 01 '16 at 07:01
  • 1
    @VonC actually that seemed to have been only about the command. Or the format. The main criticism is not the name, but that it is not even easy to script with. And hard to understand. I think even --plumbing would be bad nomenclature. Scripting with only plumbing commands is practically impossible as well. That's like having to repeat everything these commands do. What's the point of that. I find it hard to come up with commands that do have a --script option though. They seem to be few out there. – Xennex81 Aug 01 '16 at 17:44
  • @Xennex81 Interesting. If you have an example in mind which is difficult to script, don't hesitate to post a question here on Stack Overflow. That way, other Git specialists will have a chance to comment on it, and others to learn from it. – VonC Aug 01 '16 at 18:04
  • @VonC no no, the post you referenced was full of criticism on the format, saying it was incomprehensible to someone who wasn't its actual developer. There was even talk of a --porcelain=v2, and how incredulous that would be. – Xennex81 Aug 02 '16 at 23:12
  • 1
    Note that `git diff-index HEAD ...` will fail on a branch which has no commits (such as a newly initialized repository). One workaround I've found is `git diff-index $(git write-tree) ...` – anthony sottile Jul 31 '17 at 14:51
  • @AnthonySottile Thank you, very good point. I have included your comment in the answer for more visibility. – VonC Jul 31 '17 at 20:15
  • Well, `git diff-index --quiet HEAD --` doesn't take into account new untracked files. So better to use `git status` but with [`--porcelain`](https://stackoverflow.com/a/6978402/350384) parameter as described [here](https://stackoverflow.com/a/5737794/350384) – Mariusz Pawelski Dec 29 '17 at 21:37
  • I had a `diff-files` based utility function that took a file spec and did a commit conditionally and this didn't work when a new file needed to be committed, as `git diff-files` on a new file doesn't detect it as a diff. The safer approach seems to be to run `git add` on the file spec first and then use `git diff-index` to see if anything got added to index before running `git commit`. – haridsv Jun 20 '19 at 09:10
  • @haridsv Interesting. Do you have a script or an alias using that approach? – VonC Jun 20 '19 at 10:11
  • 1
    @VonC It goes something like this: `git add ${file_args} && git diff-index --cached --quiet HEAD || git commit -m '${commit_msg}'`. – haridsv Jun 20 '19 at 14:30
  • @haridsv Thank you. I have included your comment in the answer for more visibility. – VonC Jun 20 '19 at 21:15
  • I have a totally clean `branch` nothing to commit. This command fails then then, I need to actually `push` first. Usually that worked but now even after a push it fails for me and I do not know why. – redanimalwar Oct 18 '19 at 13:47
  • @redanimalwar Strange. A separate question with a way to reproduce the issue would be ideal here. – VonC Oct 18 '19 at 13:49
  • One problem I bumped in is that `git diff-index` will tell that there are differences when indeed there is none except for timestamps of the files. Running `git diff` once solves the issue (surprisingly enough `git diff` does actually change the content of the sandbox) – 6502 Oct 21 '19 at 07:10
  • @6502 Thank you for this feedback. I have included your comment in the answer for more visibility. What is your OS and Git version? (to understand why a `git diff` would modify timestamp) – VonC Oct 21 '19 at 08:51
  • @VonC: I'm using git version 2.23.0 on arch linux – 6502 Oct 21 '19 at 09:20
  • @6502 OK. May be there a smudge/clean content filter script active, or simply a `git config core.autocrlf` which may attempt to modify the content of the working tree file. – VonC Oct 21 '19 at 09:23
  • @VonC: `git diff` doesn't change the file timestamps, but it changes something inside `.git/index` that makes `git diff-index HEAD` not reporting the file any more. – 6502 Oct 21 '19 at 12:20
  • @6502 OK, got it (I have edited the answer accordingly) – VonC Oct 21 '19 at 12:21
  • if `--quiet` always nothing. usless – Vasilii Suricov Feb 28 '20 at 13:14
  • Note that if there are files that have been touched but whose contents are the same as in the index, you'll need to run `git update-index --refresh` before `git diff-index`, otherwise `diff-index` will incorrectly report that the tree is dirty. – nornagon Apr 07 '20 at 18:41
  • 1
    @nornagon Thank you, good catch. I have included your comment in the answer for more visibility. – VonC Apr 07 '20 at 19:05
  • Answer does not detect untracked files. – Myridium Jul 07 '20 at 05:16
163

While the other solutions are very thorough, if you want something really quick and dirty, try something like this:

[[ -z $(git status -s) ]]

It just checks if there is any output in the status summary.

Marty McVry
  • 2,838
  • 1
  • 17
  • 23
Nepthar
  • 1,663
  • 1
  • 10
  • 4
  • 15
    works for me. use -n for the inverse (you have changes) e.g. ` if [[ -n $(git status -s) ]]; then ... fi` – aaron Oct 06 '12 at 22:35
  • This works, but can you tell what the `[[ ... ]]` syntax is actually doing? I've never seen anything like that before. – GMA May 09 '14 at 14:05
  • [[ is a shell keyword (`$ type [[`) in bash and most shells. It behaves like the `test` command. You'll often see it as part of an if statement: `if [[ -f "$my_file" ]]; then echo "found!"; else echo "not found; fi` – Nepthar May 12 '14 at 18:22
  • `git status` returns exit code 0 for me, whether there are changes or not. git 2.6.3 on Windows. – EM0 Dec 16 '15 at 16:10
  • 2
    @EM the return code of `git status` is actually ignored in this test. It only looks at the output. Check out [this bash related page](http://wiki.bash-hackers.org/commands/classictest#string_tests) for more info on `[`, `[[` and how testing works in bash. – Nepthar Jan 02 '16 at 18:35
  • Oh, yes, of course - thanks! I was trying to replicate this on Windows. – EM0 Jan 04 '16 at 13:18
  • [difference between test, [ and [[](http://mywiki.wooledge.org/BashFAQ/031) – Marcelo Mason Aug 08 '16 at 23:38
  • 3
    This is almost right answer, but for script it's better to use [`--porcelain`](https://stackoverflow.com/a/6978402/350384) parameter as shown [here](https://stackoverflow.com/a/5737794/350384) – Mariusz Pawelski Dec 29 '17 at 21:42
  • 4
    You might want to use `git status -s -uall` to include untracked files. – barfuin Feb 15 '18 at 09:29
  • 2
    @barfuin it looks like `git status` defaults to `all`. From `git status -h`: `-u, --untracked-files[=]` `show untracked files, optional modes: all, normal, no. (Default: all)` – calebwoof Apr 17 '20 at 20:27
  • [ -z "$(git status -s)" ] -- posix & quoted – Kipras Melnikovas Nov 30 '21 at 21:06
78

git diff --exit-code will return nonzero if there are any changes; git diff --quiet is the same with no output. Since you want to check for the working tree and the index, use

git diff --quiet && git diff --cached --quiet

Or

git diff --quiet HEAD

Either one will tell you if there are uncommitted changes that are staged or not.

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
  • 7
    Those are not equivalent. The single command `git diff --quite HEAD` will only tell you whether the working tree is clean, not whether the index is clean. For example, if `file` was changed between HEAD~ and HEAD, then after `git reset HEAD~ -- file`, it will still exit 0 even though there are staged changes present in the index (wt == HEAD, but index != HEAD). – Chris Johnsen Oct 07 '10 at 08:03
  • 2
    Warning, this will not catch files removed from the staging area with git rm, AFAICS. – nmr Apr 02 '13 at 17:33
  • 29
    New (untracked) files are not detected by `git diff --quiet && git diff --cached --quiet` . – 4LegsDrivenCat Jun 08 '15 at 15:37
32

Expanding on @Nepthar's answer:

if [[ -z $(git status -s) ]]
then
  echo "tree is clean"
else
  echo "tree is dirty, please commit changes before running this"
  exit
fi
Josh Correia
  • 3,807
  • 3
  • 33
  • 50
Travis Reeder
  • 38,611
  • 12
  • 87
  • 87
  • 1
    This is good; I use it to autocommit single files by testing `$(git status -s "$file")` and then in the `else` clause `git add "$file"; git commit -m "your autocommit process" "$file"` – toddkaufmann Jan 03 '17 at 14:22
  • 2
    If you make that `git status -s` an `git status --porcelain ; git clean -nd` instead, junk directories will be surfaced here too, which are invisible to `git status`. – ecmanaut May 28 '19 at 23:41
30

Some answers are overcomplicating the matter or not achieving the desired result. E.g. the accepted answer misses untracked files.

You can use git status --porcelain=v1 and parse the output programatically. The output is empty if there is some uncommitted change, otherwise it is not empty.

A POSIX-compliant minimum working example:

[ -z "$(git status --porcelain=v1 2>/dev/null)" ] && echo "No uncommitted changes."

If run outside a git repository, this will still say No uncommitted changes.

Details

  • The option --porcelain gives a machine-parseable output.
  • The option specification --porcelain=v1 fixes the output version of the machine-parseable output, so that your script will never break under a future git update. As of my writing, you can check https://git-scm.com/docs/git-status for information about other version options, like --porcelain=v2. You may be able to do more advanced scripting with versions beyond v1.
  • The 2>/dev/null is there so that git status will fail silently, if at all (i.e., if run outside of a git repository).
  • As of this writing, the command git status ... will return exit code 128 if it is not inside a git repository. You can check explicitly for this exit code if you want a third option besides "uncommitted changes" or "no uncommitted changes".

Extra: counting dirty files

Inspired by this answer. You grep the lines of git status --porcelain=v1 output. The first two characters of each line indicate what the status is of the particular file. After grepping, you count how many have that status by piping the output to wc -l which counts the number of lines.

You may code up some more advanced behaviour this way, or pick and choose what you consider qualifies as "uncommitted changes".

E.g. this script will print some information if run inside a git repository.

#!/bin/sh
GS=$(git status --porcelain=v1 2>/dev/null) # Exit code 128 if not in git directory. Unfortunately this exit code is a bit generic but it should work for most purposes.
if [ $? -ne 128 ]; then
  function _count_git_pattern() {
    echo "$(grep "^$1" <<< $GS | wc -l)" 
  }                                           
  echo "There are $(_count_git_pattern "??") untracked files."                                 
  echo "There are $(_count_git_pattern " M") unstaged, modified files."
  echo "There are $(_count_git_pattern "M ")   staged, modified files."        
fi
Myridium
  • 789
  • 10
  • 20
  • @VonC - indeed, I checked the documentation https://git-scm.com/docs/git-status and noticed the version option. There's a v2 already but it's not default. Also I know other people have already quoted this elsewhere in the comments, but it says of the `--porcelain` option: *"Give the output in an easy-to-parse format for scripts. This is similar to the short output, but will remain stable across Git versions and regardless of user configuration."* – Myridium Jul 07 '20 at 06:06
  • Yes, v2 has been introduced in Git 2.11 (https://github.com/git/git/commit/d9fc746cd77910a7dec53abfec36df5c699b33c2), aug. 2016. – VonC Jul 07 '20 at 06:15
  • I keep getting `zsh: command not found: M` in MacOS terminal? – Chuck Le Butt Dec 06 '22 at 12:22
  • @ChuckLeButt I've tested with `zsh` on MacOS and it works okay for me. What are you putting into the terminal exactly? – Myridium Dec 14 '22 at 11:11
  • This gives me the incorrect number of untracked files! – jtlz2 May 15 '23 at 11:15
  • @jtlz2 - Could you please share the output of `git status --porcelain=v1 2>/dev/null`? You can remove sensitive information. – Myridium May 15 '23 at 21:27
8

I created some handy git aliases to list unstaged and staged files:

git config --global alias.unstaged 'diff --name-only'
git config --global alias.staged 'diff --name-only --cached'

Then you can easily do things like:

[[ -n "$(git unstaged)" ]] && echo unstaged files || echo NO unstaged files
[[ -n "$(git staged)" ]] && echo staged files || echo NO staged files

You can make it more readable by creating a script somewhere on your PATH called git-has:

#!/bin/bash
[[ $(git "$@" | wc -c) -ne 0 ]]

Now the above examples can be simplified to:

git has unstaged && echo unstaged files || echo NO unstaged files
git has staged && echo staged files || echo NO staged files

For completeness here are similar aliases for untracked and ignored files:

git config --global alias.untracked 'ls-files --exclude-standard --others'
git config --global alias.ignored 'ls-files --exclude-standard --others --ignored'
stk
  • 455
  • 5
  • 7
7

The working tree is "clean" if

git ls-files \
  --deleted \
  --modified \
  --others \
  --exclude-standard \
  -- :/

returns nothing.

Explanation

  • --deleted check for files deleted in the working tree
  • --modified check for files modified in the working tree
  • --others check for files added in the working tree
  • --exclude-standard ignore according to the usual .gitignore, .git/info/exclude ... rules
  • -- :/ pathspec for everything, needed if not running in the root of the repository

That output is empty if the working tree is clean

CervEd
  • 3,306
  • 28
  • 25
  • It does not see new directories in the working tree – ESkri Apr 25 '23 at 08:41
  • @ESkri that's because git doesn't track directories, it only ever tracks files. Empty directories do not exist as far as Git is concerned – CervEd Apr 25 '23 at 09:17
  • Yes, there are no empty directories in the repo (for example, it is impossible to add empty directory to the index). But git does know about empty directories in the working tree. For example, git successfully deletes them with `git clean -d`. – ESkri Apr 25 '23 at 10:03
  • The working tree is not clean if `git clean` has something to do in it. Pun intended. – ESkri Apr 25 '23 at 10:10
  • For finding uncommited changes, `git ls-files` does the job. Sure, you could `git clean -dn -- :/ | grep '.' || echo clean` but it's not a plumbing command. – CervEd Apr 25 '23 at 11:46
6

With python and the GitPython package:

import git
git.Repo(path).is_dirty(untracked_files=True)

Returns True if repository is not clean

Błażej Michalik
  • 4,474
  • 40
  • 55
Pablo
  • 481
  • 5
  • 4
  • This avoided some of the "timestamp" issues mentioned in other comments – Jason Nov 27 '19 at 10:53
  • 2
    Note that GitPython is just using the git CLI as well. If you set `LOGLEVEL=DEBUG` you will see all the Popen commands it it using to run `git diff` – Jason Dec 10 '19 at 03:34
  • 1
    Assuming the package is well tested, it is more reliable to let package maintainers keep the functions working properly if/when Git changes. GitPython's docs indicate that it may leak resources and that causes me concern. – Tim Bender Nov 09 '20 at 19:25
4

As pointed in other answer, as simple as such command is sufficient:

git diff-index --quiet HEAD --

If you omit the last two dashes, the command would fail if you have a file named HEAD.

Example:

#!/bin/bash
set -e
echo -n "Checking if there are uncommited changes... "
trap 'echo -e "\033[0;31mFAILED\033[0m"' ERR
git diff-index --quiet HEAD --
trap - ERR
echo -e "\033[0;32mAll set!\033[0m"

# continue as planned...

Word of caution: this command ignores untracked files.

sanmai
  • 29,083
  • 12
  • 64
  • 76
1

Tested in the bash terminal on Linux Ubuntu.

Shell script to programmatically interpret the output of git status

...and tell you if:

  1. it had an error
  2. it shows your working tree is clean (no uncommitted changes), or
  3. it shows your working tree is dirty (you have uncommited changes).

There's a great answer here: Unix & Llinux: Determine if Git working directory is clean from a script. My answer is based on that.

We will use the --porcelain option with git status because it is intended to be parsed by scripts!

From man git status (emphasis added):

--porcelain[=<version>]

Give the output in an easy-to-parse format for scripts. This is similar to the short output, but will remain stable across Git versions and regardless of user configuration. See below for details.

The version parameter is used to specify the format version. This is optional and defaults to the original version v1 format.

So, do this:

Option 1

if output="$(git status --porcelain)" && [ -z "$output" ]; then
    echo "'git status --porcelain' had no errors AND the working directory" \
         "is clean."
else 
    echo "Working directory has UNCOMMITTED CHANGES."
fi

The first part, if output=$(git status --porcelain) will fail and jump to the else clause if the git status --porcelain command has an error. the 2nd part, && [ -z "$output" ], tests to see if the output variable contains an empty (zero-length) string. If it does, then the git status is clean and there are no changes.

Option 2

Generally my preferred usage, however, is to negate the test with -n (nonzero) instead of -z (zero) and do it like this:

if output="$(git status --porcelain)" && [ -n "$output" ]; then
    echo "'git status --porcelain' had no errors AND the working directory" \
         "is dirty (has UNCOMMITTED changes)."
    # Commit the changes here
    git add -A
    git commit -m "AUTOMATICALLY COMMITTING UNCOMMITTED CHANGES"
fi

Option 3

A more-granular way to write the first code block above would be like this:

if ! git_status_output="$(git status --porcelain)"; then
    # `git status` had an error
    error_code="$?"
    echo "'git status' had an error: $error_code" 
    # exit 1  # (optional)
elif [ -z "$git_status_output" ]; then
    # Working directory is clean
    echo "Working directory is clean."
else
    # Working directory has uncommitted changes.
    echo "Working directory has UNCOMMITTED CHANGES."
    # exit 2  # (optional)
fi

I've tested all of the above code by copying and pasting the whole blocks into my terminal in a repo in varying states, and it works fine for all 3 conditions:

  1. your git status command is wrong or misspelled
  2. git status is clean (no uncommitted changes)
  3. git status is dirty (you have uncommitted changes)

To force the 'git status' had an error output, simply misspell the --porcelain option by spelling it as --porcelainn or something, and you'll see this output at the very end:

'git status' had an error: 0
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
-3

Here is the best, cleanest way.

function git_dirty {
    text=$(git status)
    changed_text="Changes to be committed"
    untracked_files="Untracked files"

    dirty=false

    if [[ ${text} = *"$changed_text"* ]];then
        dirty=true
    fi

    if [[ ${text} = *"$untracked_files"* ]];then
        dirty=true
    fi

    echo $dirty
}
codyc4321
  • 9,014
  • 22
  • 92
  • 165
  • 4
    No, this is not the best. `git status` is a 'porcelain' command. Don't use porcelain commands in scripts since they can change between git versions. Instead use 'plumbing' commands. – spuder Jun 21 '17 at 03:37
  • 3
    I think if you updated it to use `git status --porcelain` (which is meant for this purpose--a stable format you can parse in a script), possibly also with -z (null-separated instead of newline?) you could do something useful with this idea. @codyc4321 see https://stackoverflow.com/questions/6976473/what-does-the-term-porcelain-mean-in-git for details – msouth Sep 27 '17 at 03:33