Is there a way to make git automatically retry commands if index.lock exists?

I use some of Xcode's source control features, specifically the blame feature in the main editor, but use git on the command line for all of my actual version control. This means that, fairly often, git commands on the command line fail with the message:

fatal: Unable to create '/path/to/repo/.git/index.lock': File exists.

Xcode is creating this file to lock the repo as it runs its own git commands. I've already turned off all the unnecessary source control options in Preferences (Refresh local status automatically, Refresh server status automatically, and Add and remove files automatically.)

My current strategy is just to retry the command until it works, which rarely takes more than one attempt.

Is there a way to make Xcode any less aggressive with how often it creates index.lock ?

Or, is there a way I can make git automatically retry commands until they succeed if they fail in this way?


I can make git automatically retry commands until they succeed if they fail in this way?

Not with native git: you would need to script a git command wrapper which will loop and essentially wait for index.lock to disappear (which is similar to the wait strategy described in the answers of "Git - fatal: Unable to create '/path/my_project/.git/index.lock': File exists")

That wrapper could:

  • include a timeout in order to not wait indefinitely,
  • try and search for a git process when the timeout and try and kill it, in order to finally free that lock.
  • That is what, for instance, an IDE like SublimeText does

    root = git_root(self.get_working_dir())
    if wait_for_lock and root and os.path.exists(os.path.join(root, '.git', 'index.lock')):
        print("waiting for index.lock", command)
        do_when(lambda: not os.path.exists(os.path.join(root, '.git', 'index.lock')),
            self.run_command, command, callback=callback, show_status=show_status, filter_empty_args=filter_empty_args, no_save=no_save, wait_for_lock=wait_for_lock, **kwargs)
    

    Like others said there is nothing native to git but the Chromium devs did a python script called git-retry that is called by a shell wrapper.

    Instead of typing for example:

    git commit you would type git-retry commit

    You can get the tool from their tools repository by cloning it:

    https://chromium.googlesource.com/chromium/tools/depot_tools.git


    Here's my hacky patchy for this: a few lines of bash which waits till the lock file disappears and then runs your git commands. Race conditions are certainly possible, this isn't bullet proof but would work most of the time.

    function retry {
        while [ 1 == 1 ]; do
            if test -f /path/to/repo/.git/index.lock; then
                echo -n ".";
                sleep 0.5;
            else
                "$@";
                return;
            fi  
        done
    }
    

    You could throw this into your ~/.bashrc for example then to use it:

    retry git commit -m "ohhh yeaaaa"
    

    Cheers!

    链接地址: http://www.djcxy.com/p/91000.html

    上一篇: 使用SwashBuckle中的IOperationFilter删除路线

    下一篇: 如果index.lock存在,是否有办法让git自动重试命令?