jos*_*iah 7 git parsing haskell
git status --porcelain如果您以编程方式解析当前的git分支状态,我会阅读其他各种SO帖子和Google搜索结果,这些结果并不是您想要依赖的命令.我终于指出rev-parse,diff-index和diff-files命令这样做-不过,我目前使用的方法是一个小马车,特别是在比主等分支机构.像oh-my-zsh这样的主题似乎正在使用git status --porcelain,我上面提到的并不是Git社区推荐的.那么阅读这些分支状态的正确方法是什么?
来自Bureau Oh-My-ZSH主题的代码段,以便清楚我正在尝试重现的行为.
bureau_git_status () {
_INDEX=$(command git status --porcelain -b 2> /dev/null)
_STATUS=""
if $(echo "$_INDEX" | grep '^[AMRD]. ' &> /dev/null); then
_STATUS="$_STATUS$ZSH_THEME_GIT_PROMPT_STAGED"
fi
if $(echo "$_INDEX" | grep '^.[MTD] ' &> /dev/null); then
_STATUS="$_STATUS$ZSH_THEME_GIT_PROMPT_UNSTAGED"
fi
if $(echo "$_INDEX" | command grep -E '^\?\? ' &> /dev/null); then
_STATUS="$_STATUS$ZSH_THEME_GIT_PROMPT_UNTRACKED"
fi
if $(echo "$_INDEX" | grep '^UU ' &> /dev/null); then
_STATUS="$_STATUS$ZSH_THEME_GIT_PROMPT_UNMERGED"
fi
if $(command git rev-parse --verify refs/stash >/dev/null 2>&1); then
_STATUS="$_STATUS$ZSH_THEME_GIT_PROMPT_STASHED"
fi
if $(echo "$_INDEX" | grep '^## .*ahead' &> /dev/null); then
_STATUS="$_STATUS$ZSH_THEME_GIT_PROMPT_AHEAD"
fi
if $(echo "$_INDEX" | grep '^## .*behind' &> /dev/null); then
_STATUS="$_STATUS$ZSH_THEME_GIT_PROMPT_BEHIND"
fi
if $(echo "$_INDEX" | grep '^## .*diverged' &> /dev/null); then
_STATUS="$_STATUS$ZSH_THEME_GIT_PROMPT_DIVERGED"
fi
echo $_STATUS
}
Run Code Online (Sandbox Code Playgroud)
我最终会支持上面的所有行为,这是我的开始以及我目前用来做事的基本命令(抱歉这是Haskell的事实,希望这不会阻止任何人获得关于代码正在做什么的要点 - 没有双关语意图.
hasCommitsToPush :: IO (Maybe Bool)
hasCommitsToPush = do
latestCommits <- liftM (fmap $ deleteNulls . splitOnNewLine) $ parseProcessResponse gitRemoteRefDiff
case latestCommits
of Nothing -> return Nothing
Just [] -> return $ Just False
Just [_] -> return $ Just True -- This case is for a new repository with the first commit in local but not yet pushed.
Just [latestRemoteCommit, latestLocalCommit] -> return . Just $ latestRemoteCommit /= latestLocalCommit
_ -> return Nothing
where gitRemoteRefDiff = readProcessWithExitCode "git" ["rev-parse", "@{u}", "HEAD"] []
hasStagedChanges :: IO (Maybe Bool)
hasStagedChanges = liftM (fmap isResponseNull) $ parseProcessResponse gitResponse
where gitResponse = readProcessWithExitCode "git" ["diff-index","--cached","--ignore-submodules","HEAD"] []
hasUnstagedChanges :: IO (Maybe Bool)
hasUnstagedChanges = liftM (fmap isResponseNull) $ parseProcessResponse gitStatus
where gitStatus = readProcessWithExitCode "git" ["diff-files","--ignore-submodules"] []
Run Code Online (Sandbox Code Playgroud)
编辑 AndrewC指出 - 在文档中描述了将瓷器用于脚本解析的目的.这使我要问的问题,当我应该使用rev-parse与--porcelain?
就这样,官方给出了一个答案:
正如在评论中一样,文档确实说带有 Git Status 的 --porcelain 标志是为了提供脚本解析。我感到困惑的原因是,一般来说,这不是瓷器标志的作用,传统上,通常会在 Git 中为此目的指定“管道”命令。因此,在这种情况下,使用 --porcelain 标志似乎是解析 Git 存储库状态的一种可接受的方法,但这是 --porcelain 通常含义的一个例外。
更多细节包含在下面的 SO 帖子中,这些帖子是我在寻找更好的解释时发现的。 git rev-parse 有什么作用? Git 中“瓷器”一词是什么意思?