4

I am writing a script which will do this:

#!/bin/bash
mysqldump -u user -p database > db_file
git add db_file
git commit -m 'db_file updated by script'

However, what if the index is dirty when I run this script? That is, what if I already git added files that I want to not have automatically committed when this script runs? I could do this:

#!/bin/bash
mysqldump -u user -p database > db_file
git stash
git add db_file
git commit -m 'db_file updated by script'
git stash apply

But now the problem is that if the index and working tree is not dirty, then git stash doesn't add anything to the stash list, but git stash apply will incorrectly apply whatever is on top of the stash and discard the history of that stash.

How can I make a bash conditional based on if the index is dirty?

Alexander Bird
  • 38,679
  • 42
  • 124
  • 159

2 Answers2

1

git diff --cached --quiet

Previous answer:

git diff --cached will show exactly what I want to know. The only problem is that the return value is true no matter what, so it's hard to make a conditional off of that. If there is not better answer, then I can dump the output to a file and make a condition on if the file is empty or not. But that sounds painfully hack-ish. Surely there is a better way.

Alexander Bird
  • 38,679
  • 42
  • 124
  • 159
  • 5
    `git diff --cached --quiet`? – Armand Jun 12 '13 at 12:43
  • `--quiet`: Disable all output of the program. Implies `--exit-code`. That is, it exits with 1 if there were differences and 0 means no differences. [Docs](https://git-scm.com/docs/git-diff) – luckydonald Jul 25 '17 at 20:28
0

You could parse the output of git status -s.

if git status -s | grep -q '^.M'
then
    # ...
fi
Roberto Bonvallet
  • 31,943
  • 5
  • 40
  • 57
  • 4
    For anyone else looking at this question later, I think http://stackoverflow.com/questions/2657935/checking-for-a-dirty-index-or-untracked-files-with-git has a more robust solution. – Alexander Bird Feb 07 '12 at 02:40
  • This is horribly hackish. Git provides [low-level "plumbing" commands](http://schacon.github.com/git/git.html#_low_level_commands_plumbing) for this sort of thing exactly so you *don't* do something like this. – Andrew Marshall Feb 07 '12 at 02:49
  • 2
    @AndrewMarshall: A constructive comment would recommend an alternative. Which plumbing command would you suggest? – Greg Hewgill Feb 07 '12 at 03:32
  • @Greg funnily enough, a "plumbing-like" command (ie able to be parsed in a script) would be... `git status -z --porcelain` (!), as I mentioned in http://stackoverflow.com/a/6978402/6309 – VonC Feb 07 '12 at 08:36
  • 1
    @VonC: ...and people say Git's command set is inconsistent. I can't imagine why! I wonder whether a patch to introduce `git status --plumbing` meaning the same as `--porcelain` (and deprecating `--porcelain` but not removing it) would be worthwhile. – Greg Hewgill Feb 07 '12 at 09:06
  • @Greg: do you have any reference for this so-called "consistency" advocated by people? Because I have many references pointing out to the contrary. Including a recent one: http://www.saintsjd.com/2012/01/a-better-ui-for-git/ (first result of a google search on 'git commands consistent'...) – VonC Feb 07 '12 at 09:17
  • @VonC: I'm afraid my sarcasm may have not come across in my comment. Of course the Git command set is *inconsistent*, I don't think anybody would disagree with that. – Greg Hewgill Feb 07 '12 at 09:21
  • @Greg: sorry, I shouldn't post comment in the middle of my other daily tasks ;) sarcasm acknowledged. – VonC Feb 07 '12 at 09:24
  • @GregHewgill I think the [question](http://stackoverflow.com/questions/2657935/checking-for-a-dirty-index-or-untracked-files-with-git) that I had already suggested this question was a duplicate of provides a [good, in-depth solution](http://stackoverflow.com/a/2659808/211563). The OP also linked to that question as the first comment on this answer. My comment was to be taken in the context of this entire question. – Andrew Marshall Feb 07 '12 at 22:31
  • I wasted about an hour trying to figure out how to figure out whether there are any changes. This is the best option I've seen, so this is what I'm going with until someone comes up with something better... This should not be so hard -.- – Joshua Cheek Jan 27 '15 at 13:35
  • Okay, I'm actually doing it like this: `test -z "$(git status --porcelain)"` – Joshua Cheek Jan 27 '15 at 13:43