我阅读了各种其他SO帖子和Google搜索结果,如果您以编程方式解析当前的git分支状态,那么git status --porcelain
实际上并不是您想要依赖的命令。我最终指向了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
}
我最终将支持上述所有行为,这是我的开始以及我目前用来做事的基本命令(对不起它是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"] []
编辑 AndrewC指出 - 文档中描述的是用于通过脚本解析的目的。这导致我提出问题,我应该何时使用rev-parse
与--porcelain
?
答案 0 :(得分:1)
就这样有一个正式答案:
在评论中,文档可以说,带有Git Status的--porcelain标志可以为脚本提供解析。我的困惑之处在于,一般来说,这不是瓷旗的作用,而传统上,这是一个“管道”的问题。通常在Git中为此目的指定命令。因此,在这种情况下,使用--porcelain标志似乎是解析Git存储库状态的可接受方式,但这是 - 通常意味着--porcelain的例外。
我在搜索周围寻找更好解释时发现的SO帖子中详细介绍了更多详细信息。 What does git rev-parse do? What does the term "porcelain" mean in Git?