Сценарий BATCH - цикл FOR останавливается в тесте IF - PullRequest
0 голосов
/ 08 июня 2018

Я пытаюсь проанализировать файлы в git-ревизиях и предпринять действия по их статусу

По какой-то причине после моего 'if then goto' цикл больше не продолжается, пока он не обходится без теста ветвления

весь скрипт:

@ECHO OFF
setlocal enabledelayedexpansion

SET max=10
set "TAB=   "

REM parse N revision

FOR /f "delims=" %%a IN ('git rev-list --max-count=%max% HEAD') DO (

    REM parse all modifs in this revision

    ECHO Checking revision %%a 

    FOR /f "delims=" %%b IN ('git diff-tree --no-commit-id --name-status -r %%a') do (

    rem echo b %%b

    set string=%%b

    rem echo string !string!

    set status=!string:~0,1!
    set filename=!string:~2!

    echo %TAB%Filename: '!filename!'
    echo %TAB%Status: !status!

    IF "!status!"=="A" GOTO :CASE_A
    IF "!status!"=="M" GOTO :CASE_M
    IF "!status!"=="D" GOTO :CASE_D

    :CASE_A
        echo added
    :CASE_M
        echo modified
    :CASE_D
        echo deleted

############## LOOPS STOPS HERE ###############

    )
)

объяснения:

git rev-list --max-count=%max% HEAD

возвращает 2 строки, содержащие хэш ревизий

git diff-tree --no-commit-id --name-status -r %%a

проверяет все файлы вэта ревизия

например:

A       New Text Document.txt
M       test.bat

Я бьюсь головой об эту, если кто-нибудь знает, как это исправить, спасибо

Ответы [ 2 ]

0 голосов
/ 09 июня 2018
@echo off
setlocal

set max=10
set "TAB=   "

for /f "tokens=*" %%A in (
    'git rev-list --max-count=%max% HEAD'
) do (
    echo Checking revision %%A
    for /f "tokens=1,*" %%B in (
        'git diff-tree --no-commit-id --name-status -r %%A'
    ) do call :case_do "%%~B" "%%~C"
)

goto :case_done

:case_do
    setlocal
    set "status=%~1"
    set "filename=%~2"

    echo %TAB%Status: %status%
    echo %TAB%Filename: '%filename%'

    if "%status%" == "A" goto :case_A
    if "%status%" == "M" goto :case_M
    if "%status%" == "D" goto :case_D
    goto :case_else
exit /b
    :case_A
    echo added
exit /b
    :case_M
    echo modified
exit /b
    :case_D
    echo deleted
exit /b
    :case_else
    echo fixme
exit /b
:case_done

На основе идеи случая.

  1. 1-й цикл for получает каждую ревизию как %%A и печатает ее.
  2. Вложенный цикл forполучает статус %%B и имя файла %%C.
  3. Метка :case_do вызывается с "%%~B" и "%%~C" в качестве аргументов.
  4. Необязательный setlocal используется вметка :case_do для сохранения установленных переменных в качестве локальной области.
  5. status присваивается значение 1-го аргумента.
  6. filename присваивается значение 2-го аргумента.
  7. Печатает имена и значения двух переменных.
  8. Сравнивает %status% с каждым из A M D и переходит к метке совпадения.
  9. Если нет ни одного из A M D, он переходит к необязательному :case_else.
  10. Когда дело заканчивается, выполнение возвращается к вызывающей стороне в цикле for.
  11. После завершения циклов for, goto :case_done завершит этот раздел.

Подстановка переменных не выполняется, так как токены, установленные во вложенном цикле for, должны быть хороши с примером вывода, опубликованным в question.

В этом примере кода расширение с задержкой не требуется.

0 голосов
/ 08 июня 2018

Как упоминалось в моем комментарии, вы не можете использовать :Labels в конструкции цикла For.

Вместо этого просто используйте блоки в скобках:

@Echo Off
SetLocal EnableExtensions EnableDelayedExpansion

Set "Max=10"
Set "Tab=   "

For /F "Delims=" %%A In ('git rev-list --max-count=%Max% HEAD') Do (
    Echo Checking revision %%A 
    For /F "Delims=" %%B In ('git diff-tree --no-commit-id --name-status -r %%A') Do (
        Set "String=%%~B"
        Echo %Tab%FileName: '!String:~2!'
        Echo %Tab%Status: !String:~,1!
        If /I "!String:~,1!"=="A" (
            Echo Added
        )
        If /I "!String:~,1!"=="M" (
            Echo Modified
        )
        If /I "!String:~,1!"=="D" (
            Echo Deleted
        )
    )
)
Pause
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...