Я прочитал различные другие сообщения SO и результаты поиска Google, которые git status --porcelain
- это не настоящая команда, на которую вы хотите положиться, если вы разыгрываете текущий статус ветки git программным способом. В конце концов я указал на rev-parse
, diff-index
и diff-files
команды для этого - однако метод, который я использую в настоящее время, немного глючит, особенно на ветвях, кроме мастера. Темы, такие как Bureau for oh-my-zsh, похоже, используют git status --porcelain
, о которых я говорил выше, не был рекомендован сообществом Git. Итак, каков правильный способ чтения в таких статусах таких филиалов, как эти?Каким образом можно определить статус ветви Git программно?
Сегмент кода из темы 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 отметил, что --porcelain описано в документации, как быть предназначен для разбора с помощью скриптов. Это заставляет меня задавать вопрос, когда следует использовать rev-parse
против --porcelain
??
В документации для 'git status -porcelain' явно указано, что он предназначен для анализа синтаксическими сценариями. Без описания того, в какой ситуации вы плохо обращаетесь, трудно сказать, что не так с вашим подходом. Я бы предположил, что вы не обрабатываете не отслеживающие ветви правильно. –
@AndrewC Это вызывает вопрос, почему я читаю (или помню чтение) ответы, говорящие, что -porcelain не был таким, а затем продолжал рекомендовать команды, такие как rev-parse. Я бы подумал, что сошел с ума, за исключением того, что -процедура была самым очевидным подходом, но я отказался от нее из-за этих предложений, как показывает мой код. Хммм. – josiah
Связанные: [Библиотека Haskell для управления git repo] (http://stackoverflow.com/q/6609643/279627) –