10

Is there a way to force git not to create index.lock for read-only operations like git status?

I'm displaying the status of my working tree in tmux, being updated every couple of seconds. Basically I parse the output of git status --branch --ignored --porcelain and a few other commands. Problem is, that for large repositories git status can take a few seconds to complete. During that time I cannot run any other git commands because the repository is locked.

EDIT:

Here are some pictures of the relevant part of my tmux line. Description for symbols from left to right:

In sync with remote branch | 2 staged changes | 1 unstaged change | 5 ignored files | 1 stash entry: enter image description here

In sync with remote branch | no changes in working tree | 5 ignored files: enter image description here

Ahead remote branch by 1 commit | no changes in working tree | 5 ignored files: enter image description here

Michael Krupp
  • 2,042
  • 3
  • 19
  • 36
  • 1
    Good question; `status` locks the index so it can update the stat cache. I don't see an obvious way to disable that from the documentation, but it's worth knowing what you're giving up: future `status` calls will have to re-compute the work that would have been cached. This may not be optimal in your script. – Edward Thomson Dec 30 '14 at 13:21
  • Losing the cacheing is no problem for me. As I said, it is only used to display the current status of the working tree. I run `git status` every now and then anyway. – Michael Krupp Dec 30 '14 at 13:30
  • *I parse the output of `git status`.* You shouldn't do that, because `git status` is *porcelain* (high-level). You should parse the output of lower-level Git commands, instead. – jub0bs Jan 05 '15 at 17:53
  • Instead of replying "don't do it", could you further explain your comment? What exactly is wrong with parsing `git status --branch --ignored --porcelain`, and what should one use instead? – Michael Krupp Jan 05 '15 at 17:56
  • @keks Fair enough; if you use the `--porcelain` flag, you should be fine. Otherwise, you would rely on processed, higher-level output, which may change in future versions of Git. – jub0bs Jan 05 '15 at 18:08
  • @Jubobs Ok, that was my fault then. In my original question I left out the flags for sake of simplicity. – Michael Krupp Jan 06 '15 at 08:51
  • That's weird. I've tested with my repo, the "status" command locks the index only for a very short period of time. Which version of git are you using? – kan Jan 09 '15 at 18:34
  • Have you considered moving your repository status from tmux to your shell prompt? I can't see any benefits from having that status in the tmux status bar other than seeing 'live' changes due to external influences (which should be limited in most cases). Usually, you'd want to know if a command you ran from the CLI made any changes to the repository, so if you'd recalculate the status after completing your previous command (at which point the new shell prompt is rendered) that would be sufficient for most use cases. I use this strategy with powerline in zsh+tmux, and it does everything i need. – Rem.co Jan 09 '15 at 19:16
  • @Rem.co I've used that in the past. In fact I still use it when my shell does not run in tmux. The cool thing about using the tmux-line is, that (1) it is already there, so less space wasted, (2) i can see status changes from within other applications where I don't see my shell prompt (say vim) as well. – Michael Krupp Jan 10 '15 at 12:49
  • @kan This only is a problem on large repositories. Especially repositories with lots of big files in them. It seems that while git is calculating the changes in the working tree, the index is locked. I'm running git 1.7.10 and 2.1.4 here. – Michael Krupp Mar 13 '15 at 20:02

2 Answers2

9

What is about using "GIT_INDEX_FILE" environment variable to make the git to use another index file?

So, to create a new index file from HEAD use

GIT_INDEX_FILE=.git/other-index git reset

and after it you could just

GIT_INDEX_FILE=.git/other-index git status

to lookup for changes.

The downside of it, you will not see the real status if the main index will be modified by add/rm commands. But at least it will allow you to detect the fact of a change and then probably do some more stuff to find out the real difference.

Could you also describe more of the goal you are trying to achieve? Probably we could come out with some other solutions.

Another idea. Try this:

cp .git/index .git/other-index # or maybe just "ln" once, rather than copying everytime?
GIT_INDEX_FILE=.git/other-index git status

Not sure how reliable this... in case if cp command will happen while you are doing git add/rm, you could have "damaged" index file, and apparently get a failure, but for your use I believe it is good enough - you could just ignore the failure and retry.

kan
  • 28,279
  • 7
  • 71
  • 101
  • I've added some images of my tmux status line. All I really want to see in that line is what the current state of the repository is. The information is automatically updated every couple of seconds. So in theory I can follow changes in "real time". – Michael Krupp Jan 09 '15 at 21:27
  • @keks , I've updated my answer with `cp` idea. Please try and say if it works well, I'm curious. – kan Jan 10 '15 at 21:15
  • Looks like the cp-version works as expected. I did not encounter any Problems so far. Even if a damaged index gets copied, that's not that bad. By the time I would notice an error, the status would have already been updated anyways. – Michael Krupp Jan 12 '15 at 16:54
4

Quick and dirty but most safely you could simply use a user with read-only permissions.

sudo -u nobody git status
rudimeier
  • 854
  • 1
  • 8
  • 20