如果index.lock存在,有没有办法让git自动重试命令



我使用了Xcode的一些源代码控制功能,特别是主编辑器中的指责功能,但在命令行中使用git进行所有实际的版本控制。这意味着,命令行上的git命令通常会失败,并显示以下消息:

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

Xcode创建这个文件是为了在运行自己的git命令时锁定repo。我已经关闭了首选项中所有不必要的源代码管理选项(自动刷新本地状态、自动刷新服务器状态以及自动添加和删除文件)

我目前的策略只是重试命令,直到它工作为止,这很少需要多次尝试。

有没有办法降低Xcode创建index.lock的频率?

或者,如果以这种方式失败,有没有一种方法可以让git自动重试命令,直到它们成功?

下面是我的破解补丁:几行bash,等待锁定文件消失,然后运行git命令。比赛条件当然是可能的,这不是防弹的,但在大多数情况下都有效。

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
}

例如,您可以将其放入~/.bashrc中,然后使用它:

retry git commit -m "ohhh yeaaaa"

干杯!

如果以这种方式失败,我可以让git自动重试命令,直到它们成功?

不使用原生git:您需要编写一个git命令包装器的脚本,它将循环并基本上等待index.lock消失(这类似于"git-致命:无法创建'/path/my_project/.git/index.loc':文件存在"的答案中描述的等待策略)

这个包装可以:

  • 包括超时以便不无限期地等待
  • 尝试在超时时搜索git进程,并尝试杀死它,以便最终释放该锁

例如,像SublimeText这样的IDE就是这样做的

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)

就像其他人说的那样,git没有原生的东西,但Chromium开发人员做了一个名为git-retry的python脚本,该脚本由shell包装器调用。

而不是键入例如:

git commit您将键入git-retry commit

您可以从他们的工具存储库中克隆该工具:

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

我曾经使用Xcode的git客户端,它一直会导致包括这次在内的错误,所以我已经停止使用Xcode来设置我的工作区或进行提交。为了启用此设置,我从Xcode X.X的命令行工具安装了git支持,并参考外部git GUI了解导致本地或远程副本更改的任何命令,包括切换分支。

自从我开始使用外部客户端以来,我对index.lock文件没有任何问题在执行罕见操作时,如重置远程分支或重命名分支,我会使用终端。有一些高质量的git客户端是免费的,包括SourceTree。

如果您想将外部git客户端与Xcode中的新项目一起使用,请不要选择git工作区选项(如果已显示)。相反,使用外部git客户端"添加"一个额外的git工作区,并选择Xcode项目的根目录。

顺便说一句,当我这样做的时候,我通常有一个根目录来存放很多相关的杂项文件,这也是我的Xcode项目目录的主目录,它是我的git工作区的根目录。这使我可以拥有笔记和其他不希望受到版本控制的文件。

这是一个典型的设置:

+项目目录---+Xcode项目目录(gitroot)----其他项目文件(不受源代码管理)

希望能有所帮助!

因为这个文件是由git自己创建的和删除的
如果你想在创建时删除它,你需要在文件上设置一些"监视",当你看到它时删除它。

一个简单的解决方案是安装一些"watch"插件,该插件将在创建文件时"捕获"。

有很多库和工具可以完成这项任务。


以下是一些清单:

inotify-tools

inotify工具是一个C库和一组用于Linux的命令行程序,为inotify提供了一个简单的接口。这些程序可用于监视文件系统事件并对其采取行动


fswatch

fswatch是文件更改监视器,当指定文件或目录的内容被修改时,它会接收通知。

Usage example:

fswatch -o ~/path/to/watch | xargs -n1 ~/script/to/run/when/files/change.sh

watchdog

用于监视文件系统事件的Python API和shell实用程序。

您可以使用shell-command子命令执行shell命令以响应事件

watchmedo shell-command 
    --patterns="*.lock" 
    --recursive 
    --command='rm index.lock' 
    .


你是一个mac用户,但windows用户可以安装以下任何程序,这些程序将在文件创建时进行监控

https://www.raymond.cc/blog/3-portable-tools-monitor-files-folders-changes/

最新更新