2

I'm trying to return all git commit hashes for commits that contain 'As delivered' in their commit message. Essentially, I want to capture the output of the below git command:

git log --all -i --grep 'As Delivered' --format='%H'

The above git command runs as I expect it to in the command line, returning one matched hash per output line. Here's the code I'm trying to use to accomplish my goal:

def getHashesMatchingGrep(grepStr="As Delivered"):
    grep_option = '--grep=\'' + grepStr + '\''
    format_option = '--format="' + '%H' + '"'
    cmd = ['git', 'log', '--all', '-i', grep_option, format_option]
    print("Using command: " + str(cmd))
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = process.communicate()
    #return namedtuple('Std', 'out, err')(process.stdout.read(), process.stderr.read())
    return process.returncode, stdout, stderr

code, out, err = getHashesMatchingGrep()
print('code = {}\nout = {}\nerr = {}'.format(code, out, err))

But all I get as output from this is:

Using command: ['git', 'log', '--all', '-i', "--grep='As Delivered'", '--format="%H"']
code = 0
out = b''
err = b''

I've also tried defining text=True, and shell=True for my Popen call. In this case I get 'None' from err, but still no other output. If I edit my function so that cmd=['git','log','--all'] I get something, but still, why won't it return anything when I add the --grep line? I know if I type the same git command (with grep) in the cmd terminal I get results.

Am I not understanding how subprocess is supposed to work? It seems to run OK, but if it is failing, why aren't I getting the stderr? I'm very confused, please help!

3
  • I will add that git is installed and in my windows cmd path. Commented Feb 22, 2022 at 21:50
  • maybe it finds nothing in repo and you get empty output. Did you test command git log --all -i --grep 'As Delivered' --format='%H' directly in console? When I run it in console on some my repo then it gives me empty output. Commented Feb 22, 2022 at 23:26
  • This isn't a Git issue: --subprocess without --shell means you don't want to add quotes. Commented Feb 23, 2022 at 9:28

1 Answer 1

3

It appears I hadn't 'tokenized' my cmd array appropriately.
Before:

grep_option = '--grep=\'' + grepStr + '\''
format_option = '--format="' + '%H' + '"'
cmd = ['git', 'log', '--all', '-i', grep_option, format_option]

After:

format_option = '--format="' + '%H' + '"'
cmd = ['git', 'log', '--all', '-i', '--grep', grepStr, format_option]
Sign up to request clarification or add additional context in comments.

5 Comments

Or just the literal '--format="%H"', since your string constants add up to that. You probably really just wanted '--format=%H' though, without the double quotes, just as you didn't really want the double quotes in your --grep. Note that git log with --format=%H is generally best converted to git rev-list, though, if at all possible.
@torek Yeah, I thought about using rev-list but I'm not as familiar with it. That grep is important, will rev-list output allow me to grep on commit messages? I also advanced the way I'm doing this to -p --follow filename, I don't know if rev-list allows for that
git rev-list and git log are sister commands, where rev-list is the plumbing variety and log is the porcelain one. Unfortunately, they're not quite twin sisters. If you want --follow you are forced to use git log, which respects user configuration, which is a real problem. Someone is trying to add a log.graph setting and it's breaking gitk and others that use git log as porcelain, when they would like to use git log as plumbing.
(The --grep stuff is supported by git rev-list, but --follow isn't.)
Interesting, thanks for the extra details, I appreciate it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.