I'm guessing it has something to do with update-guix-package using git-predicate to add only git-known (but not necessarily committed) files to the store and then calculating the checksum of that--but the git-fetch for the guix package not necessarily doing the same. Then update-guix-package.scm does one worse and actively prevents guix from doing the checkout from git when building that "guix" package. That means the person invoking update-guix-package.scm can't notice even when the sha256 hash is definitely wrong--because guix will have the source for package "guix" in the store already (a faked entry added by update-guix-package.scm) and thus won't fetch it again. Also, doesn't this entire approach have a problem? If you make a commit into the git repo of guix in order to update the package "guix" to commit A, at that point you can't know what commit hash commit A will have (since you haven't committed it yet) and yet you have to know the commit hash of commit A in order to write it into the package definition of package "guix". That cannot work. The only way it works, more or less by accident is that, (1) At first, update-guix-package.scm does NOT update the "guix" package inside, and calculates the hash of the working copy (hash A). (2) Then, it updates the "guix" package inside to refer to hash A and to a USER-SPECIFIED COMMIT HASH (the latter is determined by the user via git rev-parse HEAD). (3) Then, it commits that changed working copy as commit B. Commit B is essentially not referred-to by anyone--it's just to make it to the git repository so guix pull can pick it up. That works only as long as there will be no reference to a nested-nested "guix" package, by the eventual user. @Maxim: I think this entire thing has to assume that git rev-parse HEAD (which it did at the very beginning of make update-guix-package) actually refers to a commit that is available on the guix git repository on savannah. That means as soon as you change anything (no matter what) (and not actually commit that) before invoking make update-guix-package the commit it refers to in the "guix" package will be one which cannot be resolved by users. Worse, if you change anything but not commit it (even locally), then that surely counts as "part of the checkout" for make update-guix-package, so the hash will be calculated including those change--but the changes are not committed, so no one can build the resulting guix package (because of a hash mismatch). That can happen automatically very easily if "make" updates po files. An easy fix, also done by a lot of other such release tools, is to make make update-guix-package first check whether there are any uncommitted changes. If so, make it fail. There's guix build guix --with-git-url=guix=. but even that won't work with (locally) uncommitted changes. Note: uncommitted and unpushed are different. It's totally fine to have UNPUSHED changes and then use ./pre-inst-env guix build guix --with-git-url=guix=`pwd` in order to build it anyway. But it's not fine to do that with UNCOMMITTED changes--because the sha256 hash will include those, but the commit id won't. Long story short, we should make "make update-guix-package" check for uncommitted changes in the working copy, and fail if any such exist[1]. There are no downsides that I can see. Even building from local working copy still works then. Also, let's please document update-guix-package. [1] git diff-index --quiet HEAD || echo fail