Magali's Blog

Present and future

Table of Contents

1 What has been done so far

I can't believe it's been three whole weeks. Time has gone by really quickly. I feel like I've been learning a lot: there are so many new ways to approach a problem. In order to keep a certain uniformity in the code, I tend to spend some time reading and analyzing the Guix source code. This way, I also get to learn some new procedures.

1.1 Motivation

My internship task is to implement a subcommand so that all Guix commit history can be retrieved easily. Using this subcommand, a user could know in which commit a package was added or updated. This will be available with 'guix git log'.

To achieve my goal, I have been using the Guile Git library, which provides bindings to the libgit2 C library. With this module, it's easy to have repository and commits information.

1.2 Results

First things first, the code I am currently working on can be found on this link. As I'm writing this, if you run the code with ./pre-inst-env guix git log --oneline1, five commits will be shown on the screen, presented in a format as if it were git log --oneline itself. If, instead of the hard-coded 5, used for now to speed up my tests, the number of commits shown is changed to, let's say, 10000 then we start seeing some interesting results. For instance, suppose I want to see commits that have 'nano' in their message title:

$ ./pre-inst-env guix git log --oneline | grep nano
eeb3db0 gnu: nano: Update to 5.4.
e6b2a3e gnu: nano: Update to 5.3.
5abbf43 gnu: nano: Update to 5.2.
0b4327f gnu: Add nanomsg.
5b893f4 gnu: nano: Update to 5.1.
c09f22a gnu: nano: Update to 5.0.
dfc4265 gnu: nano: Update to 4.9.3.

It's easy to see in which commit the nano text editor was last updated, or updated to a specific version, or when the nanomsg library was first added to Guix.

1.3 A stone in the middle of the road2

Although these three weeks have been amazing and I have learned a lot, the road has not always been easy. I faced a few problems while trying to make the subcommand work as it is right now.

Of course, there were silly, easy-to-solve problems that only required a little bit of attention to find the solution. An example was when I spent thirty minutes trying to understand why I was getting an error message, and it turned out that I hadn't imported the required module to use a certain function.

The hardest problem I had was segmentation fault occurring when running a piece of code I wrote. What I wanted to do was quite simple: I wanted to write a function that, given a Git repository path, would return all the Git commits found there. The code I wrote seemed pretty simple, so having it lead to a segfault wasn't something I expected. Here's what I was trying to do, using Guix REPL, which has proved to be great for testing how things work - or figuring out why they don't work.

$ guix repl
GNU Guile 3.0.4
Copyright (C) 1995-2020 Free Software Foundation, Inc.

Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.

Enter `,help' for help.
scheme@(guix-user)> (use-modules (guix git) (git) (guix channels) (ice-9 match) (srfi srfi-1))
scheme@(guix-user)> (define cache (url-cache-directory (channel-url %default-guix-channel)))
scheme@(guix-user)> cache
$1 = "/home/magali/.cache/guix/checkouts/pjmkglp4t7znuugeurpurzikxq3tnlaywmisyr27shj7apsnalwq"
scheme@(guix-user)> (let* ((repo (repository-open cache))
			   (latest-commit
			    (commit-lookup repo (reference-target (repository-head repo)))))
		      (let loop ((commit latest-commit)
				 (res (list latest-commit)))
			(match (commit-parents commit)
			       (() (reverse res))
			       ((head . tail)
				(loop head (cons head res))))))
Segmentation fault (core dumped)

And the solution to that is actually a workaround, as I stepped on a bug in the Guile Git library that hasn't been fixed yet. Instead of opening the repository inside let*, if the Git repository is defined in a global variable, then I can get the commits, like I wanted to.

2 Next steps

Up to now, what 'guix git log' does is walk the commit history, visiting only the first parent of a commit, ignoring any other parent and thus leaving behind other commits. So, on my to-do list, I have to fix this, finding a better way to walk the commit history, including every commit. There are also two other improvements that I should do:

-Manage with different channels, as Guix can be extended using different channels3. Right now, the subcommand can only handle with the default channel.

-Add some other formatting options. At the time of this writing, there's only 'guix git log –oneline' but the plan is to expand it so that we can also have different formatting with 'guix git log –format=<format>', and <format> could be any of 'short', 'medium' or 'full'.

Footnotes:

Date: 2020-12-22 Tue 00:00

Author: Magali Lemes

Created: 2021-02-21 Sun 01:33

Emacs 26.3 (Org mode 9.1.9)

Validate