You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If I'm doing a git rebase in the terminal it very frequently breaks (sometimes in a way that means I have abort it and start again!). The problem is that the rebase starts, then GitX notices the repo has changed, and runs some git command to update it. But that git command locks the repo, which means that when my terminal git rebase command tries to apply the next patch it bails out with an error like this:
$ git rebase --continue
error: Unable to create '/Users/me/myrepo/.git/index.lock': File exists.
Another git process seems to be running in this repository, e.g.
an editor opened by 'git commit'. Please make sure all processes
are terminated then try again. If it still fails, a git process
may have crashed in this repository earlier:
remove the file manually to continue.
Could not apply ab89cba1... Mycommit
Usually you can just do git rebase --continue and it's fine, but sometimes it breaks completely.
I think that reading the status of the Git repo shouldn't lock the repository. It can watch the index.lock file to see if some other process starts modifying the repo while we are reading it.
Reacted by Cédric Raud, Igor Pellegrini, Geremia Taglialatela and tewe
The thing is I can't see any reason why reading the index should lock it. As far as I can tell in libgit2 it is locked by git_indexwriter_init_for_operation() which is only referenced by merge.c, cherrypick.c etc.
Couldn't the fix be something like don't refresh for 2 seconds after detecting a change to the file system, rather than refreshing straight away? If more activity happens in the 2 seconds, reset the timer.
That sounds like it would work but is definitely a hack so I doubt it would be reliable. E.g. what if you have to edit a commit message during a rebase and it takes exactly 2 seconds? We should definitely try to make reading the repository a completely read-only action and I can't really work out why it isn't already.
Even if it wasn't for the read only locking thing, I think it would still be a good idea to reduce flickering and the amount of CPU etc. used by gitx. 2 seconds might be a bit longer than needed, though. Perhaps more like 500ms would be good.
The thing is I can't see any reason why reading the index should lock it.
GitX doesn't yet use libgit2 to do that, it's still a bunch of git update-index/git diff-index/git diff-files in -[PBGitIndex refresh]. Updating the index (ie. ensuring what's in the index matches what's in the work tree) will lock it, because this is not a pure read operation, as the index keep track of file stat information, which is what gets updated and causes the lock.
A workaround would be to make the watch mechanism be aware that "something" is going on (a rebase, a COMMIT_MSG file being saved), and skip refreshing in that case. But given that the refresh code doesn't notice it's going to react to something that was caused because of a previous in-progress refresh 🤷♂️ (see #156). Rewriting the index management to use libgit2, which is in progress in one of my branches, would allow usage of in-memory indexes, but then GitX has its own index that's not visible when using git.
To be frank, I've disabled Auto-refresh almost 10 years ago, and never looked back 😉. I'm actually pondering whether it's worth saving, because of the shortcomings it has (losing commits is a big no-no).
I've been running with auto-refresh disabled for a while now and to be honest it's kind of annoying. I think we should fix this. Can you explain why update-index --refresh is needed? The man page doesn't really explain it (of course).
Also git does seem to love locking the index at the drop of a hat, but it seems there is an option to not do that, at least for diffs.
The index refresh code is used only by the Stage view, and works like this (AFAIU) :
make sure the index is aware of the latest tracked files state in the worktree (update-index)
grab a list of all untracked files so you can stage them (ls-files)
grab the list of tracked files changes currently in the index (diff-index).
It's all done so that when you commit, you're not commiting "stale" data (be it stat info, or actual contents), and also to make PBChangedFile behave.
I'm pretty sure 2 doesn't touch the index. I'm also under the impression that 3 might be generating a diff which we completely ignore, as the actual diff we show is done by -diffForFile:…, (which BTW might also lock). So this leaves 1 and 3 (+diff generation) as the ones needing to lock.
To be frank, I've never looked close enough at which of those steps are the ones responsible for the locking to fail, since I'm trying to move to libgit2 and I think it's possible it can handle this better (since we can work on an in-memory copy, that we can then paste over anything done externally 😬).
So, if you want to work on that, I don't mind (I'm not reenabling Refresh until I can see reflogs in the History view, as I use the out-of-date view as a oops-resolver 😉), but maybe you should take a look at the file-system watcher. As @rjmunro says above, maybe pushing the refresh 2s later would be sufficient ?
you can disable the automatic refresh in the preferences.
Note that after disabling "Watch for changes in repositories" it looks like you must restart GitX for it to take effect. I hadn't restarted GitX, and it was still watching (and thus crashing git rebase that I ran in Terminal). Once I restarted GitX, the problem stopped.
I think there should be a warning that a restart is required for this particular setting (unless we can fix it to not require a restart).
Activity
tiennou commentedon Sep 24, 2018
As a workaround, you can disable the automatic refresh in the preferences. That will prevent GitX from stomping all over.
The thing is that, AFAIK it's not easily fixable, as git uses The User© as some kind of mutex, and the refresh code is basically seeing something moving, reload/refreshes the index for the stage view, which locks it, which causes the rebase to complain. Also note that I've witnessed lost commits because the rebase got confused and thought it was somehow done.
Timmmm commentedon Sep 24, 2018
The thing is I can't see any reason why reading the index should lock it. As far as I can tell in
libgit2it is locked bygit_indexwriter_init_for_operation()which is only referenced bymerge.c,cherrypick.cetc.rjmunro commentedon Sep 24, 2018
Couldn't the fix be something like don't refresh for 2 seconds after detecting a change to the file system, rather than refreshing straight away? If more activity happens in the 2 seconds, reset the timer.
Timmmm commentedon Sep 24, 2018
That sounds like it would work but is definitely a hack so I doubt it would be reliable. E.g. what if you have to edit a commit message during a rebase and it takes exactly 2 seconds? We should definitely try to make reading the repository a completely read-only action and I can't really work out why it isn't already.
rjmunro commentedon Sep 24, 2018
Even if it wasn't for the read only locking thing, I think it would still be a good idea to reduce flickering and the amount of CPU etc. used by gitx. 2 seconds might be a bit longer than needed, though. Perhaps more like 500ms would be good.
tiennou commentedon Sep 24, 2018
GitX doesn't yet use
libgit2to do that, it's still a bunch ofgit update-index/git diff-index/git diff-filesin-[PBGitIndex refresh]. Updating the index (ie. ensuring what's in the index matches what's in the work tree) will lock it, because this is not a pure read operation, as the index keep track of file stat information, which is what gets updated and causes the lock.A workaround would be to make the watch mechanism be aware that "something" is going on (a rebase, a
COMMIT_MSGfile being saved), and skip refreshing in that case. But given that the refresh code doesn't notice it's going to react to something that was caused because of a previous in-progress refresh 🤷♂️ (see #156). Rewriting the index management to uselibgit2, which is in progress in one of my branches, would allow usage of in-memory indexes, but then GitX has its own index that's not visible when usinggit.To be frank, I've disabled Auto-refresh almost 10 years ago, and never looked back 😉. I'm actually pondering whether it's worth saving, because of the shortcomings it has (losing commits is a big no-no).
Timmmm commentedon Jan 29, 2019
I've been running with auto-refresh disabled for a while now and to be honest it's kind of annoying. I think we should fix this. Can you explain why
update-index --refreshis needed? The man page doesn't really explain it (of course).Also git does seem to love locking the index at the drop of a hat, but it seems there is an option to not do that, at least for diffs.
tiennou commentedon Jan 29, 2019
The index refresh code is used only by the Stage view, and works like this (AFAIU) :
update-index)ls-files)diff-index).It's all done so that when you commit, you're not commiting "stale" data (be it
statinfo, or actual contents), and also to makePBChangedFilebehave.I'm pretty sure 2 doesn't touch the index. I'm also under the impression that 3 might be generating a diff which we completely ignore, as the actual diff we show is done by
-diffForFile:…, (which BTW might also lock). So this leaves 1 and 3 (+diff generation) as the ones needing to lock.To be frank, I've never looked close enough at which of those steps are the ones responsible for the locking to fail, since I'm trying to move to
libgit2and I think it's possible it can handle this better (since we can work on an in-memory copy, that we can then paste over anything done externally 😬).So, if you want to work on that, I don't mind (I'm not reenabling Refresh until I can see reflogs in the History view, as I use the out-of-date view as a oops-resolver 😉), but maybe you should take a look at the file-system watcher. As @rjmunro says above, maybe pushing the refresh 2s later would be sufficient ?
jspiro commentedon Jan 23, 2021
I've experienced this as well. Let's fix it here #206
ADTC commentedon May 8, 2023
Note that after disabling "Watch for changes in repositories" it looks like you must restart GitX for it to take effect. I hadn't restarted GitX, and it was still watching (and thus crashing
git rebasethat I ran in Terminal). Once I restarted GitX, the problem stopped.I think there should be a warning that a restart is required for this particular setting (unless we can fix it to not require a restart).
Fix index.lock contention caused by git update-index on every FSEvent…
Fix index.lock contention caused by git update-index on every FSEvent…
Fix index.lock contention caused by git update-index on every FSEvent…
Timmmm commentedon Jun 14, 2026
Lol "Claude, fix all the bugs". Fair enough I guess.
I switched to SourceGit which has a similar UI to GitX but more modern and maintained, and cross-platform.