如何判断git操作是否正在进行?

如何判断git操作是否正在进行?,git,version-control,Git,Version Control,如果像git pull这样的操作在监视模式下与后台构建同时运行(在我的例子中是webpack),它通常会失败,因为编译锁定文件git想要覆盖 我想添加脚本,以便在任何git操作当前正在修改工作目录时暂停观察程序。这应该是可能的,因为git本身会检查是否有另一个git同时执行某些操作 请注意,如果正在进行合并等操作,我不感兴趣,我感兴趣的是git当前是否正在积极编写文件。我想检查一下 yourepo/.git/index.lock 存在,当它不创建它时,运行一点,删除它,休眠一点,然后重复。我认

如果像
git pull
这样的操作在监视模式下与后台构建同时运行(在我的例子中是webpack),它通常会失败,因为编译锁定文件
git
想要覆盖

我想添加脚本,以便在任何
git
操作当前正在修改工作目录时暂停观察程序。这应该是可能的,因为
git
本身会检查是否有另一个
git
同时执行某些操作


请注意,如果正在进行合并等操作,我不感兴趣,我感兴趣的是
git
当前是否正在积极编写文件。

我想检查一下

yourepo/.git/index.lock
存在,当它不创建它时,运行一点,删除它,休眠一点,然后重复。我认为如果后台程序真的持续运行的话,这是很昂贵的。它有时也会妨碍你工作到睡觉

一个可行的选择是包装
git
命令本身。纯粹在bash中,函数将执行以下操作:

function mygit {
    pid=$(ps -eo pid,comm a | grep webpack)
    pid=${pid%% *}
    kill -TSTP $pid
    git $*
    kill -CONT $pid
}
运行
mygit
将暂停进程,运行git,然后让它继续。如果您喜欢,还可以通过该机制更改
git
命令本身的行为方式,您可以对该机制进行微调,使其仅影响仅更改索引的内容,例如在提交前(挂起)和提交后(恢复)运行的内容。可以在中找到初始化此文件的教程-基本上它只是在指定目录中具有特定名称的脚本

编辑

在回顾了下面的评论之后,我想补充一点,
git-hook
解决方案在Windows上是完全可行的,因为
git
在Windows上有自己的bash。这里有一个关于如何实现这一点的教程,但是请确保脚本都是bash的,上面的任何内容都可以工作。唯一需要注意的是查找并挂起PID

taskkill //PID <num>
taskkill//PID

会杀了它,但我不知道如何暂停。也许在装有bash it的windows 10上,上面的操作也会起作用。

通过使用另一个答案所建议的
.git/index.lock
,我最终修改了我的构建脚本,以等待删除此文件,并在构建过程中自行创建它,从而使git在构建过程中也无法启动

以防JavaScript代码对其他人也有用

const gitIndexLock = path.join(__dirname, "..", ".git", "index.lock");
let hasWrittenOwnGitIndexLock = false;
function lockParallelGitOperations(callback) {
    if (!fs.existsSync(gitIndexLock) || hasWrittenOwnGitIndexLock) {
        writeLockFile();
        callback();
        return;
    }

    console.log("Git operation in progress... Waiting...");
    const sleepStarted = Date.now();
    sleep();

    function sleep() {
        setTimeout(() => {
            if (fs.existsSync(gitIndexLock)) {
                if (Date.now() - sleepStarted > 30000) {
                    console.log("Git has been locked for over 30 seconds. Removing foreign lock...");
                    fs.unlinkSync(gitIndexLock);
                } else {
                    sleep();
                    return;
                }
            }

            writeLockFile();
            callback();
        }, 200);
    }

    function writeLockFile() {
        if (!hasWrittenOwnGitIndexLock) {
            console.log("Creating .git/index.lock.");
            fs.writeFileSync(gitIndexLock, "");
            hasWrittenOwnGitIndexLock = true;
        }
    }
}

这不是答案,但Git操作应该都是原子的。因此,一种选择可能是继续尝试从脚本中提取,直到成功。不应该存在部分损坏拉取的风险。包装您的
git
命令(可能只有更改索引的命令)是否更有意义?否则
webpack
将不得不连续ping
index.lock
或其他什么,并防止您偶尔进行更改以防止冲突。@TimBiegeleisen-不起作用。如果
pull
git
无法写入文件的错误中断,则已写入的任何其他文件将保留。由于工作目录中已有更改,运行新的
git pull
将出错@kabanus—如果某个IDE用于git操作(不使用git cli),那么这将不起作用。简单但有效:在脚本中停止/运行git/重新启动all。每次可能会花费您几秒钟的时间,但我认为这仍然少于您尝试使用更智能的解决方案所花费的时间。包装器脚本假定使用了git CLI,并且它没有在Windows上运行。但是感谢您提供了指向锁文件的指针-这可能是answer@Knaģ是正确的对不起,也许在问题中添加windows标记?并提到您使用的是图形界面。git钩子仍然可以工作,并且在某种意义上是“更好的”。
pre-commit
hook和
post-commit
hook拆分上述函数可能会修复您的大部分错误(pull毕竟只是获取、合并和提交),但您可能需要添加一些错误,或者执行一个全局错误,这样它甚至会影响状态(没有任何原因)。@Knaģis我不确定如何(自动)查找在我看来,index.lock似乎更好-它应该在不依赖操作系统细节或修改repo(添加挂钩)的情况下工作-这更好,因为更新将分发给100名开发人员…@Knaģ是在脚本方面仍然是操作系统特有的,在检查文件是否存在等方面。主要的反对意见是,与只在需要后台进程时才挂起git不同,您的后台进程将不得不持续ping和sleep,这会使它变得相当慢。另外,我不确定您是如何修改
网页包的,但它必须在过程本身的某个地方。