HNHacker News
TopNewBestAskShowJobs

peff

655 karma · joined October 22, 2012

submissionscomments
peff··on Proving false in Coq using an implementation bug
It's actually a little dangerous; what happens when you hit "^C" and the process dies before getting a chance to clean up? It's safer to do:

  some_cmd >foo.tmp && mv foo.tmp foo
The mv will do an atomic rename(), so that you either get the fully formed contents, or nothing at all.
peff··on Git client vulnerability announced
I think we are actually agreeing.

I think it is important to have this Git fix, because it lets people be careful if they choose. But in practice most people are _not_ careful, and will happily clone and run code without inspecting it (or pipe curl to bash!). It's almost impossible to do otherwise, as there are only so many hours in the day.

Ultimately I think we are mostly protected by the fact that this kind of attack is simply not all that common. And if it were done in a very widespread way, somebody would probably notice and the repo would come under scrutiny. It would probably be very effective as a directed attack against a small number of people, especially if the code you executed was sneaky (i.e., install a rootkit, not `rm -rf /`).

peff··on Git client vulnerability announced
You were and are vulnerable to malicious projects by running:

    git clone git://...
    make
or anything similar, since you are running arbitrary code out of the repository. This release fixes the problem of:

    git clone git://...
    git show
etc. Git cannot fix the "clone and run" problem, which is a social one. But it should be safe to run git commands to inspect the repository contents.
peff··on Git client vulnerability announced
We found 10 repositories which would have been blocked on push with the new restrictions. None of them were found to be malicious.
peff··on Show HN: Gitfs – mount Git repos as local folders
It's not exactly plaintext versus binary. Git "stores" a copy of every file, no matter the content. But it also does "delta compression" between objects when you run "git gc"; it tries to find binary diffs between objects that are similar. So the poor performance comes from files that don't "delta" well.

These tend to be things which are compressed or encrypted, where a small semantic change can cascade into a lot of bytes changing. Of course, binary formats often do both of those things. And the larger the files, the more painful it is when it happens.

peff··on Show HN: GitHub Treemaps
Sort of. All of the test scripts are written in bourne shell. There are ~10K lines of bourne shell in git itself, and ~136K lines of test scripts.

That may be nitpicking, but I think it also goes to show that sometimes seemingly simple numbers or visualizations can miss subtle but important points.

peff··on Proposal for a Friendly Dialect of C
No, those are things that _usually_ happen in most C implementations. But reading from uninitialized memory provokes "undefined behavior" according to the standard. Which might mean returning an unspecified value, might mean whole chunks of code being skipped, or might mean demons flying out of your nose.

The first one seems like an obvious choice of behavior, and one that some C programs doubtless depend on. But when you throw advanced optimizations into the mix, compilers may do unexpected things (e.g., assuming that a certain thing can't happen because it's not allowed by the standard, and then manipulating the code under that assumption). If you read other articles from Regehr, he describes some examples.

peff··on Flight rules for Git – What to do when things go wrong
`git gc` will not remove objects mentioned in the reflog. The reflog entry for a commit that is not referenced from any refs (e.g., because you deleted the branch it was on) will last for `gc.reflogExpireUnreachable` time units. By default this is 30 days.

After that, then the object is subject to pruning by `git gc`, and may go immediately, or up to 14 days later, depending on the packing. That 14-day grace period is there for objects that never got referenced in the first place (so a tree that you are building to make a commit, for example, would not go away before you run `git commit`).

peff··on Merge Pull Request Considered Harmful
Keep in mind that `git am` is not identical to pulling the commits. You might be applying the commits on a different base, and certainly your committer field will be different (not to mention any substantive changes you make). As a result, the sha1 of the commits you create will be different than those of the original submitter.

This makes life harder for the submitter, because they cannot ask a simple question: were my commits merged into the upstream repository? Because no, they weren't; but commits that are the moral equivalent were. Usually `git log --cherry-pick` can correlate the two, but not always.

We do use `git am` upstream when working on git itself, for the reasons you indicate in the article (plus we like mailing-list based review). But it does come at a cost in managing the various versions of patches.

peff··on Projects that power GitHub
No, GitHub primarily uses regular git on the backend. It powers all fetches and pushes, diffs, and most of the history traversals. Some functionality is provided by libgit2, and it's ever-increasing because libgit2/Rugged is often more natural to call from ruby code (though a lot of it is replacing old Grit code, not git itself).

libgit2 powers much of GitHub's desktop apps, with regular git mostly filling in any functionality still missing from libgit2.

peff··on Rainbow Sort Visualisations
Radix sort is one of those tricks that doesn't help often, but every once in a while can produce spectacular results. Here it is showing a 4x speedup on a particular operation in git:

https://github.com/git/git/commit/8b8dfd5132ce91f632b5303c39...

peff··on For the Love of God, Ask FizzBuzz
That is the fallback implementation in case a platform does not have an optimized version available. Try `sysdeps/x86_64/strcpy.S` to see an optimized version.
peff··on How to Set Up Git Completion and Repo State on OS X
That prompt can be really slow, as it runs `__git_ps1` multiple times (through several branches of the conditional, and then for the final output). On my git.git repository, running `time __git_ps1` takes about .085s. If I hit the "cyan" condition in the prompt, we run it three times, and doing `time eval "echo \"$PS1"\""` takes about 0.263s, which feels noticeably laggy.

Changing it to cache the result, like this:

   export PS1=$LIGHT_GRAY"\u@\h"'$(
    g=$(__git_ps1 " (%s)")
    if [[ "$g" =~ \*\)$ ]]
    then echo "'$YELLOW'$g"
    elif [[ "$g" =~ \+\)$ ]]
    then echo "'$MAGENTA'$g"
    else echo "'$CYAN'$g"
    fi)'$BLUE" \w"$GREEN": "
drops it back down to the .085s range.
peff··on Die Git Die
I notice that he omits the full output of `git push`. A lot of the confusion is caused by the fact that the default push mode is `matching`. I don't know what git version he is running, so I can't say exactly what text was omitted, but I would have expected to see two things:

1. Not only mention of the rejected `master` branch, but also the successful push of the `gh-pages` branch. Which makes it a lot more clear that git is trying to push multiple branches, and that the rejection has to do with `master` and not `gh-pages`.

2. The push default of `matching` is changing soon in upstream git (because it is suitable for certain types of workflow, but can cause confusion, as seen here), and the last several versions complain loudly if you do not set the default. This is intended to call attention to this common pitfall, and to notify users so that they are not surprised by the change when it happens.

With git v1.8.2, here is the full output of `git push` in his situation (you may note that the non-fast-forward advice has been improved, too):

  $ git push
  warning: push.default is unset; its implicit value is changing in
  Git 2.0 from 'matching' to 'simple'. To squelch this message
  and maintain the current behavior after the default changes, use:
  
    git config --global push.default matching
  
  To squelch this message and adopt the new behavior now, use:
  
    git config --global push.default simple
  
  See 'git help config' and search for 'push.default' for further information.
  (the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
  'current' instead of 'simple' if you sometimes use older versions of Git)
  
  Counting objects: 8, done.
  Delta compression using up to 8 threads.
  Compressing objects: 100% (2/2), done.
  Writing objects: 100% (6/6), 428 bytes, done.
  Total 6 (delta 0), reused 0 (delta 0)
  To /home/peff/foo/die-git-die/parent.git
     148db6f..25cd4ef  pages -> pages
   ! [rejected]        master -> master (fetch first)
  error: failed to push some refs to '/home/peff/foo/die-git-die/parent.git'
  hint: Updates were rejected because the remote contains work that you do
  hint: not have locally. This is usually caused by another repository pushing
  hint: to the same ref. You may want to first merge the remote changes (e.g.,
  hint: 'git pull') before pushing again.
  hint: See the 'Note about fast-forwards' in 'git push --help' for details.
peff··on ASCII bit trick to convert lowercase to uppercase and back
For a fun application, this trick is used in a proposal to encode extra randomness into the 0x20 bit of each character of a DNS query (to increase resistence to poisoning attacks):

https://tools.ietf.org/html/draft-vixie-dnsext-dns0x20-00

peff··on The driverless road ahead
By the way, I'm assuming a taxi-like shared car fleet here, where you just get in some car that is available, it takes you where you want to go, and then goes to pick somebody else up afterwards. Without that, you would not have the reduction in number of cars on the road and need for parking.
peff··on The driverless road ahead
Is utilization over time important? If we assume that people will still travel the same number of miles[1], then while there will be fewer cars on the road at any given moment, they will wear out more quickly as they are utilized more heavily.

Another way of thinking of it is that there is demand for a certain number of vehicle-miles per year. In the aggregate over the long term, it is no different if we buy 5 cars, each of which lasts 5 years, or if we buy one car every year for 5 years as the old one wears out[2].

Higher utilization should make fleet replacement a smoother function over time (whereas now, you can see dips and spikes as people decide when to put capital in their cars based on factors like the overall health of the economy).

[1] It is not clear what the impact of driverless cars would be on mileage. It would eliminate some useless trips (e.g., doubled miles for dropping somebody off). But the convenience may mean that people simply use it more.

[2] I'm assuming that wear and replacement time are purely a function of miles traveled. This is not entirely true, as age is a factor, but I think mileage tends to dominate in the average car (i.e., one that is being used, not one having its belts dry-rot over many years of neglect). Companies that maintain car fleets probably have data on this.

peff··on Git 1.8.0
Writing it in the passive voice is slightly more awkward. E.g., "git cherry-pick" was enhanced with an "--allow-empty-message option".

Similarly, writing it in the active voice but attributing the verb properly ends up with meaningless words: "Developers taught cherry-pick to..." or "We taught cherry-pick to...". Every entry would begin that way; having the first words be the relevant subsection of git makes it easier to skim through the release notes.

← PreviousPage 3 of 3