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?
Generally, if you have an index. lock file, it's because a Git process is running or waiting on a prompt for user input. However, if the editing process is terminated or becomes unresponsive, the index. lock file can be left behind and remain present even if no Git process is running.
The index. lock file prevents changes to your local repository from happening from outside of the currently running git process so as to ensure multiple git processes are not altering or changing the same repository internals at the same time.
The git push command is used to upload local repository content to a remote repository. Pushing is how you transfer commits from your local repository to a remote repo. It's the counterpart to git fetch , but whereas fetching imports commits to local branches, pushing exports commits to remote branches.
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!
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:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With