1

I have several Git repositories containing a file mergedriver.info

This file looks always like this:

<project name>
<repository name>

A script, triggered by a Git merge driver, is evaluating this file:

mergedriverinfo="$(git cat-file -p HEAD:mergedriver.info)"
success=$?
if [[ "$success" == "0" ]]; then
    log "Evaluating mergedriver.info"

    PROJECT_KEY="$(sed -E 's/([^\s]+)\s+([^\s]+)/\1/' <<< $mergedriverinfo)"
    REPO_SLUG="$(sed -E 's/([^\s]+)\s+([^\s]+)/\2/' <<< $mergedriverinfo)"

    log "PROJECT_KEY=$PROJECT_KEY"
    log "REPO_SLUG=$REPO_SLUG"
else
    log "Unable to read mergedriver.info"
    exit 1
fi

I don't understand the behaviour of sed in this case.

For this mergedriver.info:

test
conflict-on-auto-merge

The log output looks like this:

2017-07-20 11:05:51.747 PROJECT_KEY=test
2017-07-20 11:05:51.748 REPO_SLUG=tesconflict-on-auto-merge

At first I tried reading the mergedriver.info with sed -n 1p/2p and head/tail -1, but unfortunately the output of $(git cat-file -p HEAD:mergedriver.info) is different for two different platforms on which this script is running:

Platform 1:

$ od -c <<< $(git cat-file -p HEAD:mergedriver.info)
0000000   t   e   s   t  \n   c   o   n   f   l   i   c   t   -   o   n
0000020   -   a   u   t   o   -   m   e   r   g   e  \n
0000034

Platform 2:

±  od -c <<< $(git cat-file -p HEAD:mergedriver.info)
0000000   t   e   s   t       c   o   n   f   l   i   c   t   -   o   n
0000020   -   a   u   t   o   -   m   e   r   g   e  \n
0000034

How to solve this problem?

2

You need to realize that the sed regex [^\s] will not do what you think it should, viz. hunt for a non-whitepspace, rather it shall negate two characters, a backslash \ and the letter s.

What is needed is the \S which is meant specifically for this.

And to manage the output of mergerdriver.info command spilling over multiple lines is the N command from sed's toolbox.

PROJECT_KEY=$(sed -nEe '$!N;s/(\S+)\s+(\S+)/\1/p' <<<"$mergedriverinfo")
  REPO_SLUG=$(sed -nEe '$!N;s/(\S+)\s+(\S+)/\2/p' <<<"$mergedriverinfo")
| improve this answer | |
  • This works pretty fine, thanks for explaining :) One last question: What exactly is $!N; doing at the beginning of the sed expression? – BlackEye Jul 20 '17 at 11:57
  • N command appends the next line into the pattern space. But what if you are already at the eof and there's no next line? To prevent that from happening we prefix the N with a qualifier $!, meaning, append the next line, only if we are not ! at at the last line $ , written in sed as $!N. – user218374 Jul 20 '17 at 12:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.