如何在Makefile中强制清理Git工作库?

5
我正在尝试在我的Makefile中创建一个“deploy”命令,它会简单地覆盖到“deployment”分支,然后将该分支推送到“origin”。但是,当工作树不为空时,该命令必须停止/失败并显示错误消息。类似于以下内容:
deploy:

    status=$(git status --porcelain)
    test "x$(status)" = "x"
    git branch -f deployment
    git push origin deployment

很遗憾,这个测试和状态变量似乎不像期望的那样工作。

如何实现这个呢?我该确实使用test吗?


1
在 makefile 中,每个命令都将在单独的 shell 中运行。此外,$(status) 将是 makefile 中变量 status 的值,而不是 shell 中的值。 - William Pursell
1个回答

15

使用git diff-index命令检查代码库是否有更改:

deploy:
        git diff-index --quiet HEAD 
        git branch -f deployment
        git push origin deployment

如果你想在Makefile中检查shell变量,需要确保在与设置变量的shell相同的shell中检查变量的值。Make会在单独的shell中调用每个命令,因此你需要做类似以下的操作:

deploy:
        @status=$$(git status --porcelain); \
        if test "x$${status}" = x; then \
            git branch -f deployment; \
            git push origin deployment; \
        else \
            echo Working directory is dirty >&2; \
        fi

请注意双美元符号、分号和行连续符。


谢谢你的帮助。我不太确定现在应该使用第一段代码还是第二段。当我使用第二段时,会出现 make: *** [deploy] Error 1 的错误提示,但它并没有告诉我具体哪里出了问题。我该如何输出第一行后 status 的值以查看它是否正确?另外,为什么除了第一行之外,你都使用 && - Tom
1
&& 并不是必需的。使用 && 会使 shell 短路并不调用 git branch/git push,但如果省略它们,则会导致 make 在测试后中止并不调用分支/推送。我只是为了多样化而将它们放在其中。要查看 status 的值,请在设置 status 的行后添加 "echo $$status;"。 - William Pursell
谢谢,那个可以正常工作。我可能需要学习更多关于Makefiles和shell的知识。您可以告诉我如何在测试失败时输出错误消息,例如“当前工作目录不干净”吗? - Tom
1
更新:我不知道Make只支持制表符,我一直在使用空格作为缩进。非常抱歉,感谢您的帮助。 - Tom
1
哦,我不明白为什么我写了“行连续性只是为了人类可读性”。也许那是指之前的编辑。那是我曾经写过的最愚蠢的事情,即使在6.5年前我也会意识到这一点。那是完全错误的;行连续性绝对是必要的,以确保Make在同一个shell中运行所有命令。 - William Pursell
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接