Monday, February 25, 2013

UnFun with signed tags

I sometimes wish if we can revoke signature made (with PGP/GPG) to a specific tag.

I know that an electronic signature (like a handwritten one) is to protect both parties, the one who signs, and the one who gets something signed, and allowing a signer to retroactively cancel a signature invalidates the protection given to the latter. I'd be protected from a bogus claim that I made a promise I didn't make when somebody produces a document with a signature that does not match mine, and I'd be protected from somebody who changes his mind later after signing a document to promise me with his signature.

But in the context of signing a release tag for an open source project, non-repudiation is not an issue.

I often merge the last set of topics to the 'master' (or 'maint') branch, add a signed release tag to the tip, merge the result to 'next' and higher integration branches, only to find that a few more tweaks are necessary before the real release while testing the integration branches. Since I do not push out any branch before all the main integration branches (i.e. 'maint', 'master', 'next' and 'pu') are ready, it will not hurt anybody for me to rewind 'next' and 'pu' locally, discard the tag and redo the 'master' (or 'maint') branch. I also do not push out the signed tag until all these branches are ready, so in practice I just can discard the previous signed tag (that hasn't been pushed out) and tag the tip of 'master' with the same name. Nobody will notice.

So in practice, I do not need a feature to cancel a signed tag I created earlier, but at the philosophical level. But it somewhat feels awkward.

Sunday, February 24, 2013

More leftover bits

I've spent the past few days to see if there were discussions that are worth salvaging but somehow petered out without reaching conclusion, veered into tangent, or did not even start.

I tried to be fairly thorough, but I am sure I have missed some. Note that I deliberately excluded ones that fall into the Nobody who knows what they are talking about has any idea how to approach this feature category. I also left out discussions that are fairly young, hoping that they will stay alive without me keeping track of them.
  • Teach "--first-parent" to "git rebase" to deal better with a history with (possibly evil) merges from side branches.
    Cf. $gmane/198516
  • More fixes to bring sanity to "git diff --no-index", some discussed in the thread are definitely worthwhile, while some others are not.
    Cf. $gmane/200769
  • The name sanitization code may be overly conservative.
    Cf. $gmane/200823
  • The behaviour of "git filter-branch" around annotated tag may be under-documented to cause misunderstanding on the user's part, or it could be simply buggy.
    Cf. $gmane/212353
  • Annotating a pair of commit objects and trigger interesting behaviour when they both appear in the history.
    Cf. $gmane/212570
  • Make it safer to export mandir, htmldir, etc. from the top-level to Documentation/ Makefile.
    Cf. $gmane/216222
  • Allow escaping glob metacharacters in .gitattributes.
    Cf. $gmane/212631
  • Remove contrib/ciabot/.
    Cf. $gmane/212649
  • The return value from getenv(3) may be volatile across calls.
    Cf. $gmane/212660
  • Support VPATH build
    Cf. $gmane/212744
  • Build on "custom comment char" to make it "custom comment prefix string", e.g. "## ".
    Cf. $gmane/213802
  • Serving "git archive" over smart-http.
    Cf. $gmane/213243
  • "git fetch --deepen"?
    Cf. $gmane/213180 $gmane/212950
  • Perhaps reword some questions from "send-email"
    Cf. $gmane/213233
  • Improve "git remote -v" output to show where these URLs come from?
    Cf. $gmane/213806
  • Perhaps add a robust "shell portability check" mode for test scripts?
    Cf. $gmane/214709
  • Perhaps treat failures to write to a hook process that did not consume its input as success?
    Cf. $gmane/213548
  • "git rm -u"?
  • Cf. $gmane/213993
  • "git submodule foreach --untracked"
    Cf. $gmane/214860
  • [DONE] Prepare to change the default behaviour when "git add -u/-A" is run without pathspec with Git 2.0
    Cf. $gmane/214822
  • Perhaps concatenate young and small packs into one as a cheap repack?
    Cf. $gmane/215288
  • Align the logic format-patch decides to omit S-o-b to that is used by cherry-pick and commit.
    Cf. $gmane/216026
  • Allow installation filemode to be tweaked.
    Cf. $gmane/215119
  • "git log --cc" without other diff format specifiers like --raw should imply "--cc -p".
    Cf. $gmane/215470
  • [DONE] Perhaps "git grep" may want to pay attention to --textconv.
    Cf. $gmane/215385
  • Perhaps forbid "log --graph --no-walk", as --graph is about connected history while --no-walk is about discrete points?
    Cf. $gmane/216083
  • Possible merge-recursive corner case bug?
    Cf. $gmane/216117
  • Complete smart HTTP protocol documentation?
    Cf. $gmane/216262
  • Perhaps include an artificial HEAD to a bundle when HEAD is not specified from the command line?
    Cf. $gmane/216401
  • Restructure the revision parsing loop in bundle.c:create_bundle() to remove duplicates correctly, e.g. "git bundle create t.bundle master heads/master"
    Cf. $gmane/225837
  • Come up with a better default selection logic than the tentative "use the remote-tracking branch of the destination" for --force-with-lease option
    Cf. $gmane/230483
  • Force "git format-patch" (or at least allow it to be configured back to normal, when the user wants to use nonstandard settings for other commands) to use standard --commit-abbrev and --no-numstat settings.
  • Discuss and decide if we want to choose between the "mode word" UI (e.g. "git submodule add") and the "mode option" UI (e.g. "git tag --delete") and standardise on one; if it turns out to be a good idea, devise the migration plan to break the backward-compatibility.
    Cf. $gmane/231478

Tuesday, February 19, 2013

Missing the normal code review process

My favorite Bonker's World cartoon points out that the code review process alone does not necessarily ensure the quality of the code.

When you are living in the open, however, you as a reviewee are restrained with an extra incentive to be more careful, lest you embarrass yourself in public with silly mistakes. The reviewers have the same extra incentive to find flaws in others patches to earn their karma points. It also helps that any bug becomes shallow because the reviewers competing to find issues in your code gives any change a large enough number of eyeballs.

It is no wonder that the open source process can produce better-quality code more easily.

Unless you are working on fixing a vulnerability that is still under embargo, that is. It is even worse if the bug is in an obscure corner of the system you do not personally use very much.

You can only confide in a few of your trusted lieutenants, who all tend to think in a way similar to yourself. This greatly increases the chances of simple and silly bugs go unnoticed. And it makes you feel uneasy and stressed. You get only one chance to get this right, or the disclosure goes out. This is especially true when you thought you have everything tagged and ready, and decided to take a nap while waiting for the embargo to expire. It suddenly occurs to you that there was a corner case you missed, and you have to scramble to redo the fix.

Now that the embargo is over and the release is out, I can relax ;-)


The latest maintenance release Git is now available at the usual places.
This is primarily to tighten the host verification when imap-send is talking to your mail server via TLS/SSL. The topic that was merged to the tip of 'maint' track consists of 3 patches and is based on the 1.7.6 maintenance track. This is to make it easier for the distro folks to merge the topic to their older maintenance branches to issue hotfix binary releases if they wanted to.
This release itself also contains many small updates to the user-manual.

The release tarballs are found at:

and their SHA-1 checksums are:

553191fe02cfac77386d5bb01df0a79eb7f163c8  git-
bb71df6bc1fdb55b45c59af83102e901d484ef53  git-htmldocs-
98c41b38d02f09e1fcde335834694616d0a615f7  git-manpages-

Also the following public repositories all have a copy of the v1.8.1.4 tag and the maint branch that the tag points at:

  url = git://
  url =
  url = git://
  url = git://
  url =

Thanks, and enjoy.

Monday, February 18, 2013

The Maintainer's Life (1)

While I was getting interviewed for an article in the "Open Source community leaders" series on a Japanese trade publication (due to come out in many weeks), I was asked an interesting question:
What is your role in the community? What is your job?
My immediate reaction was "Huh?". The interviewer contacted me knowing that I am the Git maintainer. Don't all maintainers do more or less the same thing and operate more or less in the same way?

But here is my version of what I do, anyway. What I do fall into two categories.

One is what I do as a member of the Git development community like everybody else.
  • Triage end-user bug-reports into non-bugs and real bugs. Non-bugs may result in referring the user to an appropriate manual page, or may result in updates to the documentation. Bugs may result in fixes.
  • Read other end-user requests, ranging from "Help, I do not know what I am doing" to a solidly written feature requests. Again, many may result in referring the user to an existing documentation, some may result in real enhancements.
  • Design and propose fixes and/or enhancements (possibly inspired by end-user inputs above, or perhaps scratching own itch) to the community and discuss with the members to reach consensus. Post a series of patches to implement the design and get them reviewed by community members. With their help, polish the patches to perfection.
  • Participate in the discussion and the review process initiated by other community members who do the above.
The other is what I the maintainer alone does as the project leader.
  • Keep an eye on end-user reports and requests that haven't been responded, find somebody in the community (i.e. victims) who are knowledgeable enough to handle them, and redirect.
  • Accept the patches polished in the review process and manage releases.
An interesting thing to notice is that the latter, at least when expressed as a list of bullet items, is a lot smaller than the former. Strictly speaking, the "Keep an eye on leftover bits and redirect" item could be done by anybody in the community, and in fact we saw various people acting as capable project secretaries to do exactly that from time to time. Even though I rarely do a "grand redesign with a road-map toward the future", such a topic would not be done by me as the maintainer descending from above with an edict, but as a proposal by me as one of the members of the community (bullet 3 in the former list). Also, compared to less experienced community members, I find myself saying "Let's step back a bit" a lot more often, asking other participants in design discussions to temporarily free their thinking of whatever narrow problem description originally given by the proposer of the topic, and instead to view the issue with wider context in mind. That is not done as the maintainer, but as one of the more experienced members of the development community. Other experienced community members can and often do the same to inject sanity to ongoing discussions.

I think one of the biggest reasons why the community does not come to a screeching halt when I disappear for a few weeks is because there aren't many tasks only the maintainer is supposed to do in our community in the first place. Capable others can take over fairly smoothly while I am away, because no matter who the interim maintainer is, what other community members do do not change very much.

Perhaps what the maintainer does may be different from communities to communities. How does your community work?

Sunday, February 10, 2013

Git: Version Control for Everyone

Received a sample copy of a new Git book from Packt publishing.

It says "Beginner's Guide" on the cover; its target audience is "everyone", which apparently means those of us who have not yet read existing Git books by Swicegood, Loeliger, or Chacon, or find them a bit intimidating.

This book turned out to be a very interesting read.

It is relatively short (160 pages), and can be browsed in pretty much a single sitting. I found its approach to introduce Git to "everybody" readers very interesting. After showing step-by-step installation on major platforms (which every Git book unfortunately needs to do), the document it tracks in its first Git repository as its example is "content.docx" (surprise!).

I do not recall seeing anybody start teaching Git (or any other SCM for that matter) by tracking something you cannot get a meaningful diff out of its history you can manipulate. But we coders have to admit that that is one of the definitions of "everybody"; normal people do not read diffs and apply patches.

And the book demonstrates that tracking "content.docx" is sufficient to teach many parts of Git, and successfully teaches resetting to an earlier point to discard recent history, setting up a central repository and using it to work with others by communicating, reviewing the history with gitk, git log, git shortlog, etc., without ever mentioning diffs or merges. It is only at page 107 we see text files added to the history and merge conflicts getting resolved. We do not even see git blame mentioned anywhere in the book.

If somebody tried those other "for programmers" Git books and found their introductory parts a little over his head, this book may be a good introductory book to help him get over that very initial hump.

I have never heard of the author of this book, nor any of the people listed as reviewers, on the Git mailing list or elsewhere. I find that fact alone satisfyingto see that a Git book is written by somebody who is not an insider, and the book is targeted for "everybody". It shows how much progress we, the Git development community, have made to make the system more accessible and how much Git has become to matter in the real world. Thank you, everybody in the Git community, for working on making Git a better system every day. Your work is very much appreciated.

Thursday, February 7, 2013


Another release to give fixes for a handful bugs to users who are stuck with the maintenance track ;-)  This maintenance release contains the following fixes, and other fixes to the documentation.
  • The attribute mechanism didn't allow limiting attributes to be applied to only a single directory itself with "path/" like the exclude mechanism does. The fix for this in had performance degradation.
  • Command line completion code was inadvertently made incompatible with older versions of bash by using a newer array notation.
  • Scripts to test bash completion was inherently flaky as it was affected by whatever random things the user may have on $PATH.
  • A fix was added to the build procedure to work around buggy versions of ccache broke the auto-generation of dependencies, which unfortunately is still relevant because some people use ancient distros.
  • We used to stuff "user@" and then append what we read from /etc/mailname to come up with a default e-mail ident, but a bug lost the "user@" part.
  • "git am" did not parse datestamp correctly from Hg generated patch, when it is run in a locale outside C (or en).
  • Attempt to "branch --edit-description" an existing branch, while being on a detached HEAD, errored out.
  • "git cherry-pick" did not replay a root commit to an unborn branch.
  • We forgot to close the file descriptor reading from "gpg" output, killing "git log --show-signature" on a long history.
  • "git rebase --preserve-merges" lost empty merges in recent versions of Git.
  • Rebasing the history of superproject with change in the submodule has been broken since v1.7.12.
  • A failure to push due to non-ff while on an unborn branch dereferenced a NULL pointer when showing an error message.
For those of you who may not be familiar with how Git development works, these fixes were developed and reviewed on our mailing list (, and were first applied to the next branch of the main repository where developers and testers regularly pull from. They build and use the version from this branch daily to help ensuring the stability and correctness of the changes.

These changes proved to be safe after a few weeks testing period. And then they were merged to the master branch to become a part of upcoming release (1.8.2, scheduled to happen sometime in February).

Thanks to this fairly conservative development process, you can generally expect that the tip of our master branch is more stable than any released version of Git.

There are, however, people who want to avoid disruptive changes by staying behind, and to satisfy these people, among the changes that have been applied to the master branch, only the ones that are bugfixes (not feature enhancements) are merged from time to time to the maint branch and the results are tagged as maintenance releases.

This is such a release.