3

I am working on a project where I want to add different reviewers for different branch of my repository.

I generally add reviewers with this command:

git push --receive-pack='git receive-pack --reviewer=abc.def --reviewer=john.doe' origin HEAD:refs/for/<branch_name>

Since I use powershell terminal I wrote few scripts to ease my work. How can I add different reviewers group dynamically based on my current repository branch?

So far my powershell function look like this...

$BranchReviewerMap = @{ 
    'devO' = "'git receive-pack --reviewer=abc.def --reviewer=efg.hij'"
    'devI' = "'git receive-pack --reviewer=m.ks --reviewer=t.ch --reviewer=imt.h'"
    'devT' = "'git receive-pack --reviewer=m.ks --reviewer=t.ch --reviewer=ay.an'"
    'test' = "'git receive-pack --reviewer=m.ks'"
}

function mkb_git_push {
    [CmdletBinding()]
    param (
            [ValidateSet("merge", "commit", "test")]
            [String] $commit_type = "commit"
    )
    $default_commit = "commit"
    $test_commit = "test"
    Clear-Host

    # ===========>>> Please ignore below parts. These are working just fine <<<=========== #
    # Get Current branch
    $cur_branch = git branch --show-current
    # Some other calculation and logic, which works.
    # ===========>>> Please ignore above parts. These are working just fine <<<=========== #

    #Not able to make it work. Tried both from below two lines.
    $reviewer = [String] $BranchReviewerMap[$cur_branch]
    #$reviewer = $BranchReviewerMap[$cur_branch]
    git push --receive-pack=$reviewer origin HEAD:refs/for/$cur_branch
}

The error I get is..

fatal: Gerrit Code Review: $reviewer: not found fatal: Could not read from remote repository.

Please make sure you have the correct access rights and the repository exists.

I am not looking for any if()-else if()-else type solution.

FYI: This is my first post on. Kindly ignore my mistakes on the post.

  • Given that PowerShell variable `$reviewer` is _expanded_ (replaced with its value) in the `git` command, it is surprising that the string `$reviewer` would show up in the error message. Or does `$reviewer` have special meaning in the context of Gerrit? – mklement0 May 24 '21 at 17:02
  • All the issues here are PowerShell-specific; consider removing the [tag:git] tag. (I'm leaving it in since the `--receive-pack=...` part is a Git trick that many Git users might not be aware of. That particular part is already working fine for you though!) – torek May 25 '21 at 01:47
  • @mklement0: Thank you very much for your kind suggestion. I'd definitely do so. Now for your first comment, I tried other random variable name other than $reviewer/$reviewers. It results the same. :( – Muhammad Rakeeb May 27 '21 at 10:25
  • @torek: I kept the git tag, because I am trying to build a git command dynamically. If someone tried something like this before, I'd like to know their suggestion/opinion. – Muhammad Rakeeb May 27 '21 at 10:27

1 Answers1

3

At least one problem is in how you construct your hashtable:

Do not include embedded '...'-quoting in the entry values; syntactic quoting, during entry definition, is sufficient (you could use single-quoting here, given that the values don't reference PowerShell variables):

$BranchReviewerMap = @{ 
    'devO' = "git receive-pack --reviewer=abc.def --reviewer=efg.hij"
    'devI' = "git receive-pack --reviewer=m.ks --reviewer=t.ch --reviewer=imt.h"
    'devT' = "git receive-pack --reviewer=m.ks --reviewer=t.ch --reviewer=ay.an"
    'test' = "git receive-pack --reviewer=m.ks"
}

PowerShell will automatically ensure that --receive-pack=$reviewer is passed as a single argument to git.

Caveat: On Windows, if $reviewer contains spaces (as is the case here), PowerShell will wrap the entire argument in "..." behind the scenes rather than just the part after =.

E.g., the actual Windows command line used behind the scenes may look something like this:

# Command line actually used, as rebuilt by PowerShell behind the scenes. 
git push "--receive-pack=git receive-pack --reviewer=m.ks" origin HEAD:refs/for/test

However, it appears that git on Windows accepts this quoting style; by contrast, other CLIs with similar options may not, such as msiexec.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • Thanks for the clarification how the internal command is working. As you suggested, I also tried with removing the single quote too from the Map. But the result is always same. I have been trying to solve this challenge for last couple of days and tried all sorts of combination for the quote/single quote.... but no luck so far... :( – Muhammad Rakeeb May 27 '21 at 09:52
  • 1
    @MuhammadRakeeb, following up on my comment above: If `$reviewer` refers to your _PowerShell_ variable, then it shouldn't appear in the _error message_, because in the command shown in the question `$reviewer` is _expanded_ (replaced by its value) before `git` ever sees the argument. In other words: the command you're showing in the question is probably not the same as the one that triggers your error. – mklement0 May 27 '21 at 12:11
  • 1
    @MuhammadRakeeb, note that if you had the following _typo_ in your real command, `$reviewer` would _not_ be expanded - due to a bug in PowerShell's parameter parsers - which in turn would explain why `$reviewer` shows up as a literal in your error message: `-receive-pack=$reviewer` - note the missing second `-` at the start. – mklement0 May 27 '21 at 12:17
  • Following the clue in your comment, I am finally able to solve it with another way. Using **Invoke-Expression** Initially I build up the full command as a string and later executed it with Invoke-Expression. Here is my final code.... – Muhammad Rakeeb May 27 '21 at 12:43
  • `$reviewers = $ProjectReviewerMap2[$cur_branch] $part1="git push --receive-pack=" $part2="'" $part3=" origin HEAD:refs/for/$cur_branch" $final_cmd = $part1+$part2+$reviewers+$part2+$part3 # Test print Write-Host $final_cmd -ForegroundColor "red" Invoke-Expression -Command $final_cmd` – Muhammad Rakeeb May 27 '21 at 12:47
  • Not sure going through this worth it, but your comment on how the command was working internally gave me a better understanding. Thanks a lot for that... :D – Muhammad Rakeeb May 27 '21 at 12:48
  • 1
    Glad to hear my pointers were helpful, @MuhammadRakeeb, but note that **[`Invoke-Expression` (`iex`) should generally be avoided](https://stackoverflow.com/a/51252636/45375)** - and there's no good reason to use it in your case. Looking at your final code, I don't see how it would work differently than the preferred direct invocation. – mklement0 May 27 '21 at 12:54