GSoC Week 4 [One month special]
One month complete!
A month has passed now since GSoC started (it will on June 4) and it is a fine milestone I think! I feel happy about it. This week was more about studying things and what is under the hood rather than programming something like it has been always. I was stuck with the callback mechanism of the submodule code. I could not understand the purpose behind it and thought that it was not needed. But as always, the things which confuse me are the ones with very simple and crystal clear logic behind them (but again, not to fret, we learn to walk by falling over and over right?); I will cover the callback mechanism in the blog so that anyone who ever wants to work on submodules or a future student like me has some reference to what is going on.
What are callbacks?
Callbacks are defined in regard to a function or a segment of a program you call when encountered with a particular trigger (such as an if
statement or end of function). And by “you call”, I mean that you write a statement calling another function via another function by passing it as an argument. This is a callback made to sync_submodule
using the for_each_listed_submodule()
function.
Relevance with summary
Callbacks have a direct relation with not only the subcommand summary
but with git submodule
in general. This issue from gitgitgadget/git
provides a bit of a primer to what is going on. Quoting from the issue:
In the meantime, Git has matured a lot, and most of its code is in proper C, and quite some of that code has been prepared for more versatile use already, e.g. for in-process submodule handling, by avoiding global variables.
After reading the issue you may have realised that there has been an existence of two global variables (there are others too but these are relevant to us right now): the_repository
and the_index
denoting the working repository (everything in the .git
folder of your repository) and the staging area respectively. Now, arrival of submodules happens and a global variable to denote the repo wasn’t enough because submodules are repo inside a repo (roughly speaking). A submodule will need to have its own variables to denote its staging area and its own repository, hence a global variable will error out this whole scenario, therefore we needed local instances of such variables as the issue suggests.
Now, git submodule
is a command which helps to manipulate one or more than submodules at once, hence some subcommands may need to called again and again and therefore there is need of a good callback mechanism to you know, callback subcommands (one may notice that this whole command has a very different style of various elements: the functions, structs, etc. as compared to other commands like push
, pull
, etc.). To explain a bit further, one will need to make sure that when the functions are called, they are called for the correct submodule i.e., the correct repository and the corresponding staging area. Due to having a callback mechanism, we are able to call various subcommands at ease without much manipulation (as you may see here, We call the subcommand sync
just by passing the list of submodules, the sync_submodule
function and the callback struct holding the flags and prefix; otherwise I would have had to create an equivalent line, something like: git submodule sync ...
by appending to a string buffer and then passing it to let’s say module_sync()
function which obviously would require a couple of extra lines). Hence, this is how all of this is related to each other. Though, mind you, to call commands not having such a functionality, such as the call of git rev-parse
in git submodule summary
, I will have to create a child process followed by calling the command using run_command
or capture_command
.
Takeaways from Month 1
To the reader (especially a GSoC student or anyone in general), you might want to consider some of this for the future. This is what I have learnt as of now (not necessarily in order):
-
Nothing is really impossible! Things may seem too big at first but you will complete it piece by piece, at your own pace. To me,
set-url
andset-branch
seemed like mountains to cross, especially when I was writing my proposal in March. I kinda knew what all might be needed and how things might go about but I still was heavily underconfident. But, with time, and believing in myself, I slowly kept going and did not stop and eventually two subcommands later, I have some faith in my abilities! DO NOT GIVE UP! I can vouch for Git, there are people who will be there to help you always! Plus, you get to make friends too :) -
Keep listening to your mentors! There may be disagreements sometimes, but that’s OK! Trust me they know way more than you’d think and are way more experienced. Try having a healthy discussion with them about stuff you are confused about, you will always find something new to learn (there have been multiple such instances for me, my previous blogs have their mentions).
-
Try to reply to others’ suggestions and critiques on the List (or wherever you the reader gets them). People are trying to help you because you are making mistakes. If you don’t like their suggestions, debate, defend yourself or whatever you like (be polite) but don’t leave them hanging. This is a mistake I have made and something I do not want to repeat and might as well advise you not to do!
-
There is a lot of material to look around for! Git for instance has a ton of detailed Documentation. You cannot obviously Google everything because of how highly specific things get sometimes and for such times, good projects have Documentation available of tons of varieties. Git has the regular Documentation which talks about the commands but also has a Technical Documentation which talks about the various nuances of the whole code (such as option parsing, error handling, etc.) and even an FAQ too! You may also find some old questions on StackOverflow and discussions on the List. The List is a very handy tool if you use it right. A correct method of searching things will fetch you the EXACT results you desire. What I do is, search for keywords such as command-name, author (found using git blame, another amazing tool which isn’t known to many) and sort by relevance or even reverse sort things sometimes. Now, there are some other small artifacts too but you too have to explore something too no? ;)
-
Stay active on the List! This includes two things, commenting on others’ patches and supporting your patches. Let’s talk about the latter first. Your mentors will enforce this thought a lot that you should keep providing support to your patches and you, as a student/new contributor do try your best to do so. But let’s talk from YOUR perspective now (and I will be brutally honest because: I do not like shenanigans and you need to hear this). You will sometimes get annoyed that why do I have to supply so many versions continuously with changes not even bigger than 5 lines?! You will think that people are being too judgmental or picky, but that isn’t the case; sometimes you even have to drop out commits at the end or they aren’t queued in by Junio (happened with me twice). Here is an explanation: the thing is that, Git is one of those organizations (other which crosses my mind is Linux) who aim to keep their code pristine (not discrediting any other project/organization, just talking about my own experience). What does pristine mean here? It roughly includes: zero errors, minimal redundancies, no ambiguities in code, no failures of tests (always run the appropriate tests when done coding to make sure everything is alright), no immediate bugs or vulnerabilities in the work and finally no ambiguities for the end-user. At first even I was confused with the whole idea of keeping things this way but with time I realised that this is what we need, as an organization and as an end-user of a product. To maintain these high standards, strict checks need to be there. You cannot necessarily wrap things up at a v2 or v3; things may go as far as a v10 or a v12 sometimes and that is something you should keep in mind and appreciate too! People outside Git applaud this level of professionalism and knowledge in the Git community! Even in my own college, when I tell people that I do things for Git with the cherry on top called GSoC, I get a very awestruck and positive feedback from people! Thus, if you want to be proud about this, be a good contributor and try not to leave your patch hanging and keep providing support to your work in the form of comments and re-rolls.
Also, if you have the liberty of time, do try commenting on others’ patches. You gain more experience and knowledge and make new friends along the way too! People will come to comment on your patches as well which is a great plus right?
Next steps
Now, I am on the conversion of summary
to C. I am making progress though there lies one confusion regarding the options of the subcommand which are: quiet
, cached
, files
, for-status
and summary-limit
. Now, as we use a callback mechanism, the options provided by the user need to pass in to the module_summary()
function (for parsing) and a summary_submodule
function (for acting upon the given options). There exists the usual callback struct holding the flags
and prefix
variable, but I need to configure the flags cleverly. There are three ways:
- Create a macro for the respective options. Something like
#define OPT_FILES
. But this thing does not seem feasible to me as the above mentionNow, I am on the conversion ofsummary
to C. I am making progress though there lies one confusion regarding the options of the subcommand which are:quiet
,cached
,files
,for-status
andsummary-limit
. Now, as we use a callback mechanism, the options provided by the user need to pass in to themodule_summary()
function (for parsing) and asummary_submodule
function (for acting upon the given options). There exists the usual callback struct holding theflags
andprefix
variable, but I need to configure the flags cleveed options are subcommand specific (exceptquiet
) and creating a separate macro for them means extra clutter. - Putting these options into the callback struct by creating a variable for each of them. This (line 769) is the approach adopted by my GSoC senior of two years, Prathamesh, when he tried to convert
summary
. This approach seems the easiest with a low risk high reward. - Finding some clever way to pass options further by
- Now, I am on the conversion of
summary
to C. I am making progress though there lies one confusion regarding the options of the subcommand which are:quiet
,cached
,files
,for-status
andsummary-limit
. Now, as we use a callback mechanism, the options provided by the user need to pass in to themodule_summary()
function (for parsing) and asummary_submodule
function (for acting upon the given options). There exists the usual callback struct holding theflags
andprefix
variable, but I need to configure the flags cleverly. There are three ways: - Create a macro for the respective options. Something like
#define OPT_FILES
. But this thing does not seem feasible to me as the above mentioned options are subcommand specific (exceptquiet
) and creating a separate macro for them means extra clutter. - Putting these options into the callback struct by creating a variable for each of them. This (line 769) is the approach adopted by my GSoC senior of two years, Prat
taking a hybrid of the above two approaches. What comes into my mind is that I will declare variables corresponding to each option inmodule_summary()
itself and allot them values like they are done in the macros (left shifts of 1, 2, … n) and OR-gate them, kinda like :info.flags |= cached
. Now, as each option will have its own values, detecting which option was given in the first place will be very easy. But the downside is that in case any new option were to be introduced (let’s say I were to introduce arecursive
into the mix as I have planned for summary) then there may need to be a change of values of options. So a careful planning is must.
I will figure this out with time and help from my mentors for sure! I think I have talked a lot.
On a final note, there is this one idea/saying I love a lot:
- Hardwork and perseverance never betrays
- Mighty Guy
Whoever is reading this, keep going. Things will get tough, but you have to get tougher :’)
I do not pretend to be a monk or an all-knowing person, even I am learning slowly and steadily. This is just a part of the story of my life, hoping that this makes someone else’s better too. I have some of my own principles, like the one mentioned above.
Anything useful I learn, I will surely share, be it about programing, Git, GSoC or life in general :)
Over and out,
Shourya Shukla
Comments
Post a Comment