GSoC Week 6

A hot and humid week

This week I have been trying to get deeper into the subcommand summary and its nuances. I aim to start coding the rest of the functions in the coming days. I am complete with the most of the front end module_summary() function, Of course, more edits may follow later but I want to focus on a bare working version as of now.

Current Progress

In this week I had been studying about Parameter Substitution and Parameter Expansion and the code of git submodule summary. I will talk about what I have learnt from these two concepts in this blog and where are they being used as well as about the commit verification part of summary which gives us a starting point to proceed from. I gave a teaser of Parameter Substitution in my Week 2 blog.

Parameter Substitution

Parameter Substitution in Shell scripting helps us to substitute the value of a parameter/variable with another value in minimal number of steps. The equivalent of this in C would be a conditional ?. Let’s say we want to achieve:
Set the value of variable var1 to var2 if the former is not set i.e., it is null else make var1 as null. This will be done as:

${var1:=$var2}

The : checks if the variable exists and is not null and the = will set the parameter to var2 if var1 is null. Isn’t this quite simple? Something which would’ve taken a line or two to implement in C (unless you use a conditional ? operator), can be done in one expression. The mnemonics are a bit tough to memorise in one go but with practice this becomes quite fluid.
Some common operators for parameter substitution are:

  • - checks if the variable in question exists or not before it was put in a parameter substitution. For instance:

     var1=1
     var2=2
     echo "${var3-$var2}"  ## outputs 2 which is value of var2
    
  • : is a stricter check than - and also checks if the variable is null or not. For instance:

      var1=
      var2=2
      echo "${var1:-$var2}" ## outputs 2 b/c var1 is existing yet set to null
    
  • + will set the value of the variable in question to the other variable if it is set. For instance:

      var1=1
      var2=2
      echo "${var1+$var2}" ## outputs 2 b/c var1 is set to 1
    
  • = will set the value of the variable in question to the other variable if it is unset. It is the exact opposite of +. For instance:

      var1=
      var2=2
      echo "${var1=$var2}" ## outputs 2 b/c var1 is set to null
    

NOTE: We can use + and = in conjunction with :.

Parameter expansion

Parameter expansion feeds on the results from substituted parameters to further expand or modify a parameter. What I have learned till now about expanding parameters involves using the : operator but is not the meant in the same way as in parameter substitution. Here, it is used more like a separator/descriptor.

A very basic format of parameter expansion is ${var:offset:length}.

  • The offset denotes the distance we take from the starting point. For instance, an offset of 3 in var=abcdef means we start from the alphabet d (3 places ahead of a). Offsets can be negative and a negative value of -n denotes that we start counting n places from reverse. Therefore offset of -4 in the above variable will mean will start from c (counting back 4 places from f). Use an extra space between : and offset if the latter is negative. NOTE: For offset of start calculation from n+1 if n > 0 else start from N-n (where N is the final index of the parameter).

  • The length denotes the distance we have to go from the offset if length > 0 else if length < 0, it denotes how back we go from the end of the parameter and hence take the net result with the offset one. If no length is provided then we go till the end of the parameter. For instance:

     var1=1234567890abcdefgh
     #output 78, go to offset 6 then add 2 and that is the output.
     echo ${var1:6:2} 
     #output 890abcdefgh as no length given
     echo ${var1:6}
     #output cd as we go back 6 places from h and then add 2
     echo ${var1: -6: 2}
     #output cdef as we go back 6 places from h and then go back 2 places from h and take the net result (cdef)
     echo ${var1: -6: -2}
    

git submodule summary

I have also studied more about summary in terms of its code. As far as I have learned, summary prints a git log --oneline between the revision checked out in the submodule and the revision known to the superproject (i.e., the revision found in the superproject). Going by the usage of git submodule:

git submodule summary [options] [commit] [<path>​]

The commit is the commit hash of the superproject we want our comparison to happen in. The path is the path of the submodule in question; failure to provide a path will give the summary of all the submodule(s) existing in the superproject.

An example of an output for summary could be:

$ git submodule summary HEAD my-subm
  * my-subm abc123..def456
    < some commit
    < another commit
    < some another commit 

As one may see, we get three different commits meaning that there are 3 commits between the version checked out in the submodule and the version checked out in the superproject’s HEAD version.

The main check we have to do in such a case is to make sure that the revisions we are going to work on exist and are valid. If they do not exist then we either error out or come to the conclusion that our tree is empty in fact. cmd_summary()in git-submodule.sh does three checks to make sure the working is safe

if rev=$(git rev-parse -q --verify --default HEAD ${1+"$1"})
then
	head=$rev
	test $# = 0 || shift

This check makes sure that the revision (if specfied else default to HEAD) will be able to fetch a SHA1 for itself, hence we use the verify option to make sure this verification happens.

elif test -z "$1" || test "$1" = "HEAD"
then
	# before the first commit: compare with an empty tree
	head=$(git hash-object -w -t tree --stdin </dev/null)
	test -z "$1" || shift

This part checks if there are any commits in our tree (of the submodule) or not. If there aren’t any commits then it simulates an empty repo environment using head=$(git hash-object -w -t tree --stdin </dev/null). The /dev/null is the UNIX null device and is sort of a blackhole meaning things if gone into it completely disappear never to be seen again. Making stdin as /dev/null means giving nothing as input hence nothing to create a hash object of.

else
	head="HEAD"
fi

This means that if the above 2 cases fail which for instance, may be due to providing a non-existent commit-ish or due to failure to provide a hash:

git submodule summary my-subm

This will take the my-subm argument as a commit hash even though we intended to provide it as a path to the submodule and will therefore run the third case taking revision specified as HEAD hence taking head as HEAD.

This thus marks the end of the verification part and thus will be followed by the main working of summary.

Next steps

Now, I have to implement the further functions for summary which are: summary_cb() and print_summary() (this one is already implemented though I need to use it with my current work). After some guidance from my mentors, I am first implementing the work done by Prathamesh and then address the comments made on that patch as well as amend it to the current CodingGuidelines and the make it consistent with the current submodule--helper.c.
Also, I have started to maintain notes on GSoC relating to Git, C and Computer Science because: I forget things and it would be better to have all the useful stuff at one place. I am also reading Matheus` blogs and trying to take some inspiration from there because of some reasons. Hopeful to see some good progress in the coming days! The weather is irritably humid and hot here! Hope it gets better soon.

Over and out,
Shourya Shukla

Comments

Popular posts from this blog

The Final Report

GSoC Week 4 [One month special]

GSoC Week 10