Home > Back-end >  PowerShell for loop pattern check
PowerShell for loop pattern check

Time:07-13

I wanted to search for missing Id from PowerShell for loop

I'm using this command

git log -10 --no-merges master | Select-String -Pattern "commit"

then doing for loop

foreach($commit in $commitMessage) {
        Write-Host $commit.
    }

If one pre-commit Id missing I need to exit the loop (need to skip the loop if pre commit not existing)

example: if Highlighted Id missing How can find that? can we check patterns?

loop retuning list like this

1 Commit id 2 Pre-commit 3 Commit id 4 Pre-commit etc...

enter image description here

CodePudding user response:

The following assumes that you're looking for the presence of commit lines that aren't followed by at least one precommit line rather than looking for a specific precommit hash.

$havePreCommit = $true; $missing = $false
$commitAndPreCommitLines = 
  switch -Regex (git log -10 --no-merges master) {
    '^commit ' {
      if (-not $havePreCommit) { $missing = $true; break }
      $havePreCommit = $false
      $_ # output
      continue
    }
    '^\s Precommit-Verified:' {
      $havePreCommit = $true
      $_ # output
    }
  }
$missing = $missing -or -not $havePreCommit

if ($missing) {
  Write-Warning "Not all commit lines are followed by at least one precommit line."
} else {
  # Output the collected lines (no need for a loop).
  $commitAndPreCommitLines
}

The solution uses a switch statement with regex matching. This allows you to maintain state across lines, which Select-String alone cannot do.

CodePudding user response:

git log --grep Precommit-Verified will show you only commits whose messages contain that string, but when you're postprocessing you'll be searching for that string anyway so maybe it's best to not duplicate the searches.

There's an easy oneliner for this with unix tools,

git rev-list -10 --no-merges --pretty='%w(0,4,4)%B' master \
| sed '/^commit/!{/Precommit-Verified:/H;$!d};x;/\n/!d'

is probably better for this task, it just drops any group that didn't find the body line you're looking for.

/firstline/!{...H;$!d};x is a group-accumulation idiom; the first line of each group gets xchanged into the hold buffer, and the accumulated lines from the previous group are processed as a unit. Here we're just picking the Precommit-Verified lines, and only printing groups that have more than just the header.

I'd be interested in a powershell way to do this too, it really doesn't seem suited for tasks down in oneliner territory like this.

  • Related