status: offer *not* to lock the index and update it

When a third-party tool periodically runs `git status` in order to keep
track of the state of the working tree, it is a bad idea to lock the
index: it might interfere with interactive commands executed by the
user, e.g. when the user wants to commit files.

Let's introduce the option `--no-lock-index` to prevent such problems.
The idea is that the third-party tool calls `git status` with this
option, preventing it from ever updating the index.

The downside is that the periodic `git status` calls will be a little
bit more wasteful because they may have to refresh the index repeatedly,
only to throw away the updates when it exits. This cannot really be
helped, though, as tools wanting to get a periodic update of the status
have no way to predict when the user may want to lock the index herself.

Note that the regression test added in this commit does not *really*
verify that no index.lock file was written; that test is not possible in
a portable way. Instead, we verify that .git/index is rewritten *only*
when `git status` is run without `--no-lock-index`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
Johannes Schindelin 2016-08-12 10:54:26 +02:00
parent f279472f24
commit 67e5ce7f63
3 changed files with 20 additions and 1 deletions

View file

@ -111,6 +111,11 @@ configuration variable documented in linkgit:git-config[1].
without options are equivalent to 'always' and 'never'
respectively.
--no-lock-index::
--lock-index::
Specifies whether `git status` should try to lock the index and
update it afterwards if any changes were detected. Defaults to
`--lock-index`.
OUTPUT
------

View file

@ -1333,6 +1333,7 @@ static int git_status_config(const char *k, const char *v, void *cb)
int cmd_status(int argc, const char **argv, const char *prefix)
{
static int no_lock_index = 0;
static struct wt_status s;
int fd;
struct object_id oid;
@ -1362,6 +1363,8 @@ int cmd_status(int argc, const char **argv, const char *prefix)
N_("ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"),
PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
OPT_COLUMN(0, "column", &s.colopts, N_("list untracked files in columns")),
OPT_BOOL(0, "no-lock-index", &no_lock_index,
N_("do not lock the index")),
OPT_END(),
};
@ -1385,7 +1388,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
read_cache_preload(&s.pathspec);
refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, &s.pathspec, NULL, NULL);
fd = hold_locked_index(&index_lock, 0);
fd = no_lock_index ? -1 : hold_locked_index(&index_lock, 0);
s.is_initial = get_sha1(s.reference, oid.hash) ? 1 : 0;
if (!s.is_initial)

View file

@ -1670,4 +1670,15 @@ test_expect_success '"Initial commit" should not be noted in commit template' '
test_i18ngrep ! "Initial commit" output
'
test_expect_success '--no-lock-index' '
test_commit some-file &&
test-chmtime =1234567890 .git/index &&
git status --no-lock-index &&
test-chmtime -v +0 .git/index >out &&
grep ^1234567890 out &&
git status &&
test-chmtime -v +0 .git/index >out &&
! grep ^1234567890 out
'
test_done