Skip to content

GitX locks repository for read-only access #164

Closed

Description

@Timmmm

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.

Activity

  1. tiennou commented on Sep 24, 2018

    @tiennou
    Contributor

    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.

  2. Timmmm commented on Sep 24, 2018

    @Timmmm
    ContributorAuthor

    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.

  3. rjmunro commented on Sep 24, 2018

    @rjmunro

    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.

  4. Timmmm commented on Sep 24, 2018

    @Timmmm
    ContributorAuthor

    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.

  5. rjmunro commented on Sep 24, 2018

    @rjmunro

    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.

  6. tiennou commented on Sep 24, 2018

    @tiennou
    Contributor

    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).

  7. Timmmm commented on Jan 29, 2019

    @Timmmm
    ContributorAuthor

    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.

  8. tiennou commented on Jan 29, 2019

    @tiennou
    Contributor

    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 ?

  9. jspiro commented on Jan 23, 2021

    @jspiro
    Member

    I've experienced this as well. Let's fix it here #206

  10. ADTC commented on May 8, 2023

    @ADTC
    Contributor

    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).

  11. added 3 commits that reference this issue on Jun 6, 2026
    0b3bb46
    f95c90e
    7e01f5a
  12. Timmmm commented on Jun 14, 2026

    @Timmmm
    ContributorAuthor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions