"We're so plugged into the consumer entertainment industry that we don't know what's going on in the world. We know all about Johnny Depp and Angelina Jolie and U2 and The Family Guy, but we don't know the laws that are being passed in our countries. We don't know about the injustices of our social systems. We don't know where our food comes from, or the suffering required to get food onto our table. We don't know about the people in our neighbourhoods who are writing books and making movies and putting on plays and singing in choirs and running garage bands. Just like the citizens of The Matrix, we are mostly oblivious to reality, in part because somebody has convinced us that consuming entertainment is a worthwhile pursuit."
- Paul Nijjar, Adjacency Matrix
I think the reasoning should be viewed as less of a security measure for the source tree itself, and more of a best practice. Consider it a kindness extended to your end users.
Developers who commit to a tree are often familiar with the code. Those that are truly involved in a project may read every commit that comes in. They know what the code is supposed to do, and how it works. They know who the other contributors are, and they are in the best position to spot defects, bugs, or security holes.
The end user has none of this advantage. In most cases, he doesn't even know where the source code is. He wouldn't know how to read it if he did. And he may not know a good patch from a bad one, nor have the time to figure it out.
How do you bridge this chasm? The most practical way is to have a string of GPG signatures from the developer to the end user, and make it easy for the end user to verify this.
So, the developer signs his release with his GPG key. The distro packager checks this key, builds a package, and signs that with his own GPG key. And the end user downloads the updated software with the packaging tool, which automatically verifies the package signature. A very friendly verification chain from developer to end user.
So the question is: if you're not willing to sign a tagged release of your software, should you be in charge of releasing the code to end users at all?
You can see an updated list of presentations on the website. This year's fest is packed full of FLOSS goodness.
Hope to see you there.
Registration is open! It has been open for a few weeks now, and I've just gotten around to announcing it in my blog here now. Apologies.
This year's event is being held on Saturday, October 24. Just 3 weeks away! If you register in advance at the website the cost is only $40. If you show up at the door, it is $60. Earlier is better.
If you would like your name in lights, and would like to help sponsor the event, you can become an individual sponsor as well. More details on the registration page.
As usual, there's a welcome party on Friday night, and an after party Saturday night. Let us know if you can join us by checking the party options during your registration.
The official Twitter feed for the Ontario Linux Fest is @OntarioLinux. We're using the group tag #oglf09. The 'g' is for GNU.
You can also follow me personally on Identi.ca as @cdfrey. I may post there from time to time as I work on the show guide.
Hope to see you at the Fest! I'll update this blog more regularly as more news becomes available.
But with that flexibility comes complexity. Have you ever wondered what the difference was between "commit1..commit2" and "commit1...commit2"?
If so, then this mini howto is for you.
(If you want to follow along, use the sample setup commands at the end of this document)
1. What is a branch?
It is helpful to remember that git thinks of a branch as any name or tag that refers to a SHA1 commit ID. The branch represented by that commit includes that commit itself along with all the ancestors that make it up.
git log master
will show you the master commit, with all the parent commits that belong to it. If you say:
git log master desktop
it will list all the ancestor commits of both master and desktop.
2. Commit walking
The command git-rev-list takes a list of commits and prints the SHA1 commit IDs of all the ancestors for those commits. This is a low level git command and is the basis for specifying commit ranges.
For example, on a repository I have on my hard disk, I have the following branch structure:
/---o---o master / o----o (base) \ \---o---o desktop
The following command:
git rev-list master | wc -l
shows 3 commits. If I include the desktop branch, which has 2 unrelated commits in it, and does not have the 2 commits from master:
git rev-list master desktop | wc -l
it shows 5 commits.
This shows that specifying multiple branch names is inclusive. All commits from all branches are included in the resulting list of ancestors.
3. Limiting the list
If I want to see all commits that are in master but not in desktop, I can invert one of the branches:
git rev-list master ^desktop | wc -l
This shows 2. The two commits on the master branch. I can verify this with:
git log master ^desktop
which shows only the patches on the master branch.
I can reverse this as well, showing only the 2 commits on the desktop branch:
git log ^master desktop
The shorthand for this is the 2 dot ellipsis. The following are identical:
git log ^master desktop git log master..desktop
Again, reversing, the following are identical:
git log master ^desktop git log desktop..master
4. Finding the branch point
Git does not store branch divergence points. This can be calculated on the fly by looking at the heads of two branches and finding the first common commit in the list of ancestors.
This job is done by git-merge-base. If we used it on the above branch structure, we would get a SHA1 commit ID of the point marked (base) above.
git merge-base master desktop
This returns c79f6f286e720b39976531b7a5b713b87308b576 in my repo. It will be different in yours, since you have different author information.
5. Listing all changes
Using what we know, we can now list all the changes on both branches that are not in the main repo:
git log master desktop ^c79f6f
This shows 4 commits, from both branches.
The shortcut to this, is the triple ellipsis:
git log master...desktop
Basically, this means show all the commits from both branches that happened since they diverged.
6. Diff: turn the world upside down
This is all fine and good, but wait! The git-diff command turns this inside out.
Git-diff takes two branches and shows a unified diff patch between the _endpoints_ that they represent. The usual format of the command is as follows:
git diff master desktop
This will create a patch which, if applied to master, will turn it into desktop. i.e. it removes the 2 changes done on master and adds the 2 changes done on desktop.
The reverse will do as expected:
git diff desktop master
This is the same as having two trees checked out, and running a manual diff -ru on them from the command line.
The double ellipsis is used in git-diff as well, but has no special meaning. It is an alias for the above usage. The following are identical:
git diff master desktop git diff master..desktop
The difference in git-diff is that the triple ellipsis uses the same logic as git-log does when finding the merge-base, but the result is the difference between the base and _one_ of the branches.
git diff master...desktop
This will find the branch point of master and desktop, and then generate a diff between that base commit and the commit of desktop.
In other words, the diff will contain only the 2 changes on the desktop branch, and is effectively the same as:
git diff c79f6f desktop or git diff $(git merge-base master desktop) desktop
Reversing the options will do the same for master. The following commands are identical:
git diff desktop...master git diff c79f6f master
Now, the diff will contain only the 2 changes on the master branch.
The parsing logic of the triple ellipsis range is the same, but the result is the opposite. With git-log, all 4 commits are shown, with git-diff, only 2 commits from one side of the branch are shown.
Pasting the following commands into a shell will create a sample branch with which you can experiment with these range specifiers.
mkdir play cd play git init echo data > file.txt git add file.txt git commit -m "Initial commit" echo data > README git add README git commit -m "Added README" echo data > license git add license git commit -m "Added license file" git checkout -b desktop master^^ echo data > main.c git add main.c git commit -m "New source code" echo data >> main.c git commit -a -m "Bug fix" git checkout master
Thanks to Ilari on #git irc.freenode.net for the discussion that lead to enlightenment.
git checkout -b staging master
git checkout -b base_url staging
git rebase --onto master staging
This does: finds all the commits between the current branch (base_url) and staging, switches base_url's HEAD to master, and then reapplies the above found commits. You end up with a base_url branch that looks like it was only branched from master originally.
Excuse me? A foreign company wants to buy taxpayer-funded Canadian technology and they want the Canadian government to foot the bill.
Are we Canadians stupid or what?
New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.
Keep up with the latest Advogato features by reading the Advogato status blog.
If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!