Comparing function changes across branches with process substitution, git, and sed
I came across a scenario where I had a TON of functions move from a public .c to a private .c
Github displayed all the functions as part of a massive diff. I guess they are different in some ways, but not RREEAALLLYYYY though. The contents of these files is the exact same, the only thing that has changed is their location.
I was asked to verify that all these functions were the exact same.
THIS seemed like a good thing to attempt to automate some.
A few tools immediately jumped out to me when thinking about this problem.
git - to grab files from specific branches (in this case a feature branch and main)
sed - a text processing utility to search for and grab a function body
diff - do the two functions differ?
With the above I could start off by grabbing a single file from a branch using
git show <BRANCH_NAME>:<PATH_TO_FILE> The above command will go to <BRANCH_NAME>, search for the file specified at <PATH_TO_FILE>, and then display it in the terminal window.
Now, in the repo I was working in we have formatting scripts that will ensure a closing “}” exists at the same level as the opening one for a function. This will ALWAYS be at the very beginning of a line in this context.
uint16_t randomFunc(void)
{ // <- This
. CODE
. CODE
. CODE
} // <- and this exist at the same level (start of a line)To parse the above function sed can be utilized.
The command in particular I used looks like this
sed -n "/randomFunc/,/^}/p"Some info on my sed:
The -n option suppresses the default behavior of sed to print every line.
/randomFunc/ is the starting pattern. It matches lines containing "randomFunc".
, indicates a range of lines.
/^}is the ending pattern. It matches lines starting with a closing curly brace.
p is the print command, which prints the matched lines.
With the two commands above I can search the contents of a file within a given branch, search that file for a function, and then print the contents of the function.
If I did this on two different branches/files I could visually inspect the differences between two functions. Something like this:
$ git show main:bar.c | sed -n "/randomFunc/,/^}/p"
$ git show featureBranch:foo.c | sed -n "/randomFunc/,/^}/p"Would allow me to compare randomFunc between bar.c in my main branch and foo.c in my featureBranch.
Visual inspection kinda defeats the whole purpose of this exercise however. What we can instead do is process substitution. Process substitution will allow us to treat the output of a command as if it were a file. This will help us to avoid creating temporary files and allow easy comparison for the two outputs of our commands above.
The final command will look something like this:
$ diff <(git show main:bar.c | sed -n "/randomFunc/,/^}/p") <(git show featureBranch:foo.c | sed -n "/randomFunc/,/^}/p")Note the <() is the process substitution part. This allows us to treat the output of a command as an input file.
The command above might be making some inaccurate assumptions in parsing and displaying the function you are looking for. In any case however, it could be tweaked. HOPEFULLY, the above serves as a good starting point for further development.

