Hacker News new | past | comments | ask | show | jobs | submit login
Git-blame-someone-else – Blame someone else for your bad code (github.com/jayphelps)
149 points by mablae on Feb 7, 2016 | hide | past | favorite | 65 comments



Should probably use this moment to plug my (opposite) project, git-upstage, which lets you claim credit for someone else's work and backdate it so it looks like you did it first:

https://github.com/SilasX/git-upstage


Much better. Love the hacker's twist. :)


It's been my experience, especially in the startup scene where business requirements change often, that `git blame` rarely shows you what you want. Files get renamed, moved, re-indented, etc, frequently.

I wrote a tutorial on a more effective (at least for me) solution to find the true author of a change: http://blog.andrewray.me/a-better-git-blame/


Nice tutorial, but aren't you aware that "git blame -w" ignores whitespace changes? git blame also always follows renames. git's rename detection isn't foolproof (if I edit and rename A.cpp to A-star.cpp at the same time as adding a new A.cpp file it won't detect it), however there are two more blame options for that: -C to follow lines copied between files, and -M to follow lines moved within a file.

Unfortunately, adding -M and -C will quite badly increases the time to compute the blame. Both take an adjustable parameter (min number of characters to match), but I found I actually had to reduce it to catch all the lines in an example of the A.cpp -> A-star.cpp move I did yesterday.


I would love to be able to use left and right to skip quickly through revisions when viewing a blame, do you know anything for that?


That's something I've wanted for a long time too.

tig (a curses-based git interface) fits the bill, though it can be quite confusing (too many keybindings). "tig blame -w <file>" to view a blame (-w to ignore whitespace), and then you can press , on a line to recompute the blame using the parent of that commit, while moving to the ancestor of that line (but tracking the line frequently doesn't work). And < to go back to the previous commit.

I remember that tortoisesvn was fairly nice for viewing blames, IIRC you can move through history inside it with some clicking around, and the tortoisegit interface appears to be largely the same: https://tortoisegit.org/docs/tortoisegit/tgit-dug-blame.html Windows only however.


I found http://1dan.org/git-blameall/ an incredibly useful tool for similar (not identical) purposes.


> It's been my experience, especially in the startup scene where business requirements change often, that `git blame` rarely shows you what you want. Files get renamed, moved, re-indented, etc, frequently.

Blame follows renames in most cases (unless you're doing something like creating a new file with the same name as the renamed one in the same commit), and you can use the -w flag to ignore whitespace changes.


Should really use "git filter-branch", not "git rebase -i", for automated history modifications. "git rebase -i" is good for interactive usage, not scripting.


And this is why I pgp sign all my commits. :-P


It's a bit worrying that GitHub will happily associate someone's face on a commit that they didn't write: https://github.com/jayphelps/git-blame-someone-else/commit/e...

Perhaps GitHub should only do this for signed commits or commits to the author's own repository or something.

GitHub also allows you to add anyone to a project without their consent (or has this changed?). This reminds me of the Facebook prank where someone added Mark Zuckerberg to a fake(?) pro-paedophile group.


Agreed.

It should be trivial for them to allow you to paste your pgp public key as you would your ssh public key, then place a nice little "verified" check mark next to commits that can be validated as having been signed with one of your associated private keys.


There are so many things that GitHub could easily do, but don't... Makes me wonder what they actually do.


You mean besides developing and operating one of the best services on the web?


Well, yeah. It is a good service. They've contributed good stuff to Git core, too.

I really wonder what they do. I have some complicated feelings about them, also, that has to do with them becoming the central hub for open source.

Like, if the product itself were open source, it might be more obvious what they are working on. But I can't demand that kind of transparency... It would just be interesting to know.

With almost 500 employees, what happens? I've never even worked at such a large company myself.

Should GitHub users have some say in what the company builds? I mean, we're promoting them like hell, and the social network is a huge part of their value.

I often wonder what well-funded large product companies do with all their manpower. Feature development doesn't seem to scale. Nor innovative design. GitHub's mobile layout is pretty crippled. I dunno. Just curious.


Best in what sense? Bitbucket does everything Github does, plus gives free private repos. GitHub is just more widely used.


But Bitbucket is fricken awful though. I think I have an allergy to everything designed by Atlassian


Bitbucket crashes minimal browsers like Surf and github doesn't. So, in that regard, Github is better.


It seems odd to blame BitBucket and not Surf for this.


Interesting, didn't know that. But it seems easily fixable for BB and probably doesn't drive much of the difference in popularity.


Is there anyway to search bitbucket? Can I link my profile to someone so they can see all my projects? I'm only dimly aware of bitbucket, but if these criteria are easily met then I might even consider changing over.


i don't use bitbucket so can't comment if they provide this. but github has a nice hack allowing you to svn checkout a portion of a tree

on a slow connection, this allows you to work on or inspect repos that are too large to git clone (one of the few major complaints i have with git itself)


Best as in market share, but certainly not best by it's own merits. (ie there is better git management software)


Well maintaining software and infrastructure is one thing. But they also seem to lack features compared to the competition. They might want to quickly sort their management issues out and be more agressive feature-wise.


They are carrying the torch for rectifying social injustices, apparently. Oh, and selling out for the enterprise big-bucks.


If you can sell them on it as an important enterprise feature, they might implement something. :)


Alternatively, they could provide some sort of on-page indication of a credentials/e-mail mismatch, i.e. detect and publicly report when the HTTPS/SSH credentials used for a `git push` aren't associated with a verified e-mail address matching the commit's `user.email`.

I reported this issue a long time ago to their security team, and got a really condescending "we're a collaborative community, it's not a problem, you obviously don't understand" type of response. Pretty frustrating.


But isn't it somewhat reasonable that I push someone else's commit? Say I want to rewrite an old commit, and then force push that, then all the commits after the rewritten commit by other people would effectively be pushed by me.

Or consider the common case where the public repository on Github is just a mirror of an official repository somewhere else -- then commits from a bunch of people would all be pushed by whoever is responsible for keeping the repos in sync.

But maybe Github could just add some kind of a "pushed by" label that identifies the Github user who pushed the commit?


> But isn't it somewhat reasonable that I push someone else's commit? Say I want to rewrite an old commit, and then force push that, then all the commits after the rewritten commit by other people would effectively be pushed by me.

Even worse: rebasing (what rewriting an old commit actually does) changes all SHA hashes of the following commits, thus breaking existing PGP signatures on the commits. There should be two signatures... one for the patch+comment, one for the history.


They do have a "committed by" feature that appears when you cherry-pick someone else's commit to a branch.

It shows up as "Bob committed with Alice".

I've only noticed it showing up for cherry-picks, I'm unsure if that's the only place it's used.


They show that if the git commit has differing author and committed fields (It shows up when I reorder and squash commits on branches before merging).

All one has to do to make it go away is change the committer field on the git, this isn't security added by GitHub.


Yeah, the "pushed by" indicator would be a great idea IMO.


Worrying and potentially libelous. Some countries (e.g. UK) have strict libel law, and by using this you could get Github in trouble for publishing libelous material.

Of course, this has always been possible with git.


Though since GitHub does not have an office in the UK and in the US is protected from foreign defamation judgements under the SPEECH Act, it probably doesn't have much to worry about.


Just wait until they want to take advantage of Ireland's favourable tax regime. Ireland also has strict libel/defamation laws.


I actually just noticed this yesterday when realizing that some commits to my personal repository on an unrelated-to-work project had my work account's username and picture, even though I used by personal account key. I guess this uses the global email and name settings, and github matches the picture. I got a bit worried that this stuff would start appearing on my work organization's timeline.


Back when I was first learning to use git, I accidentally pushed a commit to my repo as the author of a set of dotfiles I'd cloned. It was a bit mortifying.


One of my coworkers did the same thing years ago, and he still takes flak for it.


I'm actually surprised that git doesn't sign commits by default. (i.e. I had assumed that it did.)

It already has the keys set up and such.


No it doesn't. Git works independently of SSH.


Oh.

Oops. Thanks for the correction.


This probably could be done using git filter-branch as well.

Not rewriting history, I still have this little script called fakecommit[0] lying around I have used in the past to commit stuff under other people's names.

[0]: https://github.com/winks/dotfiles/blob/cfd9d994d0bcd7510203a...


Hell, I can do _all_ my work as somebody else with "git config user.name" and "git config user.email".

If that's really a genuine concern, then a) you are working with a big bag of dicks and b) there are _way_ worse things that person can do with write access to the repository than masquerade as somebody else.


As stated in the project read me, it's just a joke project.


No, I get it, but even in this thread there is a higher-than-expected amount of hand-wringing.


I totally agree with 32bitkid's view of the other comments, makes a good point.


This was also being discussed here [1]

[1] https://news.ycombinator.com/item?id=11049993

Apparently it will be obvious to folks that this has occurred.


We moved the comments here from a later thread that hijacked "Show HN" (https://news.ycombinator.com/item?id=11053078). We also rolled back the clock on the current thread so it would go to the same position on the front page. It's still not really a fair swap because the other post has most of the points, but people will probably keep upvoting this one.


Um, mostly no. This can be trivially detected only when you are changing things already pushed.

Being a dvcs, you create atleast one commit on your local repo before pushing to a remote. That one (or more) commit can be changed to point at anyone and pushed.


Mostly yes. You rewrite the whole history from the commit you changed authors on and onwards so git will let you know that you have two conflicting histories that needs to be merged. This is why the author needs to force push to master.

The only exception to this is if someone else has not pulled into their private repo any changes at or before the commit you changed.


What I am saying is that this tool can be used exclusively while creating commits. Not for retroactive changes.


Hey Bob, what is up with the `git push --force master`?


This is a good example of why git repos should be snapshot and archived to read-only media periodically.

I like this! Thank you


It does a rebase, so everybody that has a copy and pulls will notice.


Good point. Would code review tools catch this? Gerrit, Crucible, et al? More specifically, how obvious would it be and would people question what they see?


Tools will probably show that you are trying to merge/push all commits since (and including) the changed one, unless they have something special to detect rebases and display them differently.



(When I saw the title, I was wondering if this does something beyond the basic rebase, like trying to brute force a commit such that all following commits are preserved (hash doesn't change), but that's essentially impossible.)

I'm tempted to make the observation that there's nothing here you can't already do with a git rebase -i and:

    GIT_COMMITTER_NAME=a GIT_COMMITTER_EMAIL=a@a.com GIT_COMMITTER_DATE=2006-01-02T15:04:05Z git commit --author='a <a@a.com>' --date 2006-01-02T15:04:05Z
But I realize this ability will be novel/surprising to some people, and this is meant to be a joke.

I don't do this not because I can't, but because I have no incentive to lie about who wrote/committed certain code.


> all following commits are preserved (hash doesn't change), but that's essentially impossible.

Actually, you only need one brute-force (of the commit that you're changing); subsequent commits only refer to the parent hash, and here we're not changing the commit trees either.

SHA1 is already considered broken, so git really should switch to SHA256 soon. This whole "sha1 commit hashes are not for security" argument is mostly naive and bogus.

The only way it would be safe, is if (a) everyone set their GPG to default to SHA256 or above (older versions still default to SHA1) and (b) either (b.1) everyone signed every commit this way, or (b.2) everyone signed their tags this way and just before tagging, reviewed their local commits including commits not authored by them up to the previously trusted tag.

But if git defaulted to SHA256 or SHA512, then we wouldn't have to reason through the complex scenarios involving (b). Making something "too secure" is a good thing if it simplifies your security analysis and allows you to use your head for other productive things.


Good point, only need to brute the commit being modified to have it match the original hash.

To get a brief sense of how hard it is to do, one can look at a sample project like gitbrute [0] that tries to brute force the first n letters of a commit hash. It took someone 30 mins to brute first 8 hex letters (of 40) on a MBP [1] with that.

[0] https://github.com/bradfitz/gitbrute

[1] https://github.com/bradfitz/deadbeef/commit/deadbeefa1a98280...


Why SHA-256 instead of SHA-3?


No particular reason, I just picked that as the default choice in my head. SHA-3 also works, just less widely implemented atm. (Still waiting for a sha3sum command in coreutils).



$ git push SEP-field


what's the point? you just rebased with a incompatible tree. nobody will be able to update that because their trees will say the commit differs.

and in the only case this would work, i.e. nobody has that commit yet, you could just have commited as that person. nothing new or interesting.

now, github being garbage and not accounting for PGP signatures, now this is something else.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: