The commit hash of the blamed commit and all ones after that change, so the system works. One day we may be able to reliably/easily generate SHA-1 collisions to really get someone else to take the blame :-)
I was expecting this to be like `git blame`, but to automatically check previous revisions for any lines touched by the current user. That would be a fun toy :-)
At one company I did a project that among other things involved bringing in a code formatter. I deliberately tagged that commit with a generic author :-)
I think it's best to migrate to a preferred formatting slowly, versus touching everything at once. I've had open pull requests that I've started over due to aggressive reformatting like that. Between that and breaking tools like 'git blame', it can be painful.
This approach sometimes works for formatting but the issue with ad-hoc approaches is finding ways of enforcing on new commits. This is especially so with a large developer base.
Once you move on from just banal issues like whitespace and move your way up to actual structural concepts in the code, ad-hoc starts completely falling apart (at least in my experience.)
I once encountered someone who did a giant re-formatting of code by rewriting past commits. Pretty disruptive for a day but did manage to keep history in-tact. Also, a little (or a lot?) dangerous...
That was our problem. We added a git hook to reject new malformed commits. The easier way to not mess more things was to make all the code base compliant.
Ran into this issue where contributors editors were reformatting the whole file they touched based on the newly created code formatting config file. Some editors would pick it up and automatically reformat on save so a commit with 3 actual lines changed looked like 90% of the file had changed in the diff. So we went with the nuclear option and did one massive PR that reformatted the whole codebase.
That's common. Most tools like Magit make it easy to dig down through multiple layers of formats, renames, refactors and typo fixes to find the commit that actually introduced something.
Stop using git blame to look up who authored code, it's not a useful tool. Use git log -S <string> to search for changes to that line (then repeat with the previous version of that line, until you find the original author), and/or git log -L to track changes to a code block. Don't waste your time with git blame.
My editor (sublime text) has built in git blame support. It's literally right-click -> blame file, and it will put the author of every line in the margin.
how is git log -S more efficient? You have to write whole line, what if line is long? What if you need to look at several lines within some range. git blame is much better than your git log -S
git blame can't possibly work well in all cases, which is why the author is saying that.
Git doesn't store what actually was changed. Git stores how to reconstruct the new file from the old file in a space efficient way.
This is unrelated to storage of who changed what, only "what is the minimal way to reproduce the end state from the beginning state".
As a result, tools like blame take the two versions and try to figure out what someone actually changed, trying to turn applesauce back into apples.
Whether it gets it right or not has an element of luck to it (the diff algorithms are also often based on finding the minimal sequence of edits.). Whether it happens depends on the algorithm and it's heuristics, and often whether there is a single unique minimal sequences that could produce your end state from your beginning state (if not, it's not actually possible to say what you changed with 100% accuracy)
git log -S instead is saying "give me all the times this line seems to have changed", and then you do the work of figuring out which were real and which are artifacts of the diff algorithm.
git blame and git log -S are both granular tools with their own blindspots. To actually get to the bottom of something you need a higher level tool which lets you iterate through historical changes across multiple files over time. The workflow is 1) git blame problematic area 2) open full commit + diff for that change so you can see context 3) open relevant file(s) as they existed in that commit 4) repeat steps 1,2 and 3 until you get to root cause.
This workflow is not subject to any limitations around code structure, variable naming, file moving or anything else. fugitive.vim is a plugin which lets you very quickly recurse into history in this fashion using multiple vim windows.
This thought occurred to me, too. The example given is about pinning bad code on someone else, but the inverse is also possible: changing the author of good code to yourself. I'm kind of wondering, now, if there are some unscrupulous coders out there messing with their employer's internal git repos to give themselves credit for work other people did. I knew one guy who would create tickets, assign them to himself, and then abuse the tickets closed metric to inflate his productivity claims. He wasn't very subtle about it, either. Of course management ought to have been more skeptical of that, but .. stuff happens.
Yeah, I work in information security for a living, how did you guess?
Well for one thing, the unscrupulous employee would need to have force push permissions to the origin repo.
Even if they they did, once they change the history change, other developers working with the repo would be alerted of the remote branch changing out from under them next time they try to pull. And even if the change doesn't result in a conflict, and each of those other devs blindly accept the resulting merge, the original authors' commits will still be in the history resulting from the merge. So if those developers ever pushed anything, the original commits would be re-introduced.
Now, it could be abused if a single developer inherits a project that nobody else has checked out. But it's still a high risk strategy for the unscrupulous dev.
> Well for one thing, the unscrupulous employee would need to have force push permissions to the origin repo.
Have you ever seen that old video "The website is down"? [1]. In it, the guy covers his own tracks with admin privileges. I'm not saying it's easy, just that it's possible.
It’s not just blame. GitHub uses commits to build the contributor list on your repo home page, so you can make it look like it has some famous contributors:
I assumed they were recording actions taken via the github UI and APIs, not the git commit log. If someone merges a pull request you opened, poof, you contributed the lines merged from that pull request regardless of the git author line. Same if you run `git push` with your github login credentials.
Apart from attributing things to the wrong person, git author line seems like it must also have the issue of not attributing things at all. What if I signed up with a different email address than I use for git?
it runs git rebase under the hood, in production environment with multiple people pushing to repo it will break things and it'll be spotted immediately. So this actually shows how hard it is to spoof commit author, you can't do it without leaving a trace, git is a solid system.
Well, if you collect commits on a feature branch you can just create a new one with a slightly different name - all the commits on your branch are rewritable before you push it in and create a pull request (deleting and pushing it again with different history does not work for me). I often do this for rebasing, I doubt anyone would have ever noticed if I changed the authors.
This has saved me so many times. I’m sure I would have lost my job a while ago had I not been able to use this, it’s one of my most actively use tools. I’m sure eventually I’ll be losing my job, but at least this repo has enabled me to keep it a little bit longer.
Curious how do you get away with it without anyone noticing. Doesn’t this imply rewriting the master branch? Wouldn’t that cause noticeable issues for everyone else? Or maybe you’re the only active contributor on that codebase (but then who else can you blame?)
Why do they have to sign their commits? Their contributions are unverified, as are any commits made in your name without your signature, but they don't have to do anything.
You gain the ability to prove that a certain commit came from your machine or someone with full access to it, they don't.
To be honest, everyone should be signing their commits in a professional environment. It takes minutes of work to set up and greatly increases the trust you can have in the code base.
If you're scared of affecting your workflow, just don't protect the GPG keys with a password (dangerous) or use your operating system's trust store to unlock them at login (less dangerous, but still suboptimal).
I sign my work commits without ever entering a password in a prompt. Some of my coworkers also sign their commits, most of them don't.
Does it feel like gardening? Moderating HN that is. It'd have to be one of those "wild gardens" that's mostly the plants doing what they want with a bit of nudging. Pull out a weed here, tie up some branches there, clear the path, give a little extra water to something that didn't get a good chance yet, etc. Sorry for the OT, I was just curious if that analogy resonated.
This is hilarious! Got a good laugh from this. It also illustrates how easy it is to impersonate other people in Git. I’m surprised this isn’t discussed more.
To be honest, when you really think about it, any commit that is not GPG signed is unverifiable. It could be anybody. I wish signing commits was more widespread.
yeah, we recently started switching from mercurial to bitbucket (not our choice) and we took the time to make commit signing mandatory, piggybacking on the infrastructure that was already in place to sign the mercurial commit, but with new gpg keys as the mercurial commits were signed with p12 keys, which are not supported by git/bitbucket (can't remember which).
Conversely, if you do sign your commits but are careless if your keys (e.g. storing your private-key directly in your repo...) then you've got even more work for yourself.
99 comments
[ 3.5 ms ] story [ 150 ms ] threadhttps://git-scm.com/docs/git-blame#Documentation/git-blame.t...
Once you move on from just banal issues like whitespace and move your way up to actual structural concepts in the code, ad-hoc starts completely falling apart (at least in my experience.)
I once encountered someone who did a giant re-formatting of code by rewriting past commits. Pretty disruptive for a day but did manage to keep history in-tact. Also, a little (or a lot?) dangerous...
It's usually called "blame previous revision".
Git doesn't store what actually was changed. Git stores how to reconstruct the new file from the old file in a space efficient way.
This is unrelated to storage of who changed what, only "what is the minimal way to reproduce the end state from the beginning state".
As a result, tools like blame take the two versions and try to figure out what someone actually changed, trying to turn applesauce back into apples.
Whether it gets it right or not has an element of luck to it (the diff algorithms are also often based on finding the minimal sequence of edits.). Whether it happens depends on the algorithm and it's heuristics, and often whether there is a single unique minimal sequences that could produce your end state from your beginning state (if not, it's not actually possible to say what you changed with 100% accuracy)
git log -S instead is saying "give me all the times this line seems to have changed", and then you do the work of figuring out which were real and which are artifacts of the diff algorithm.
This workflow is not subject to any limitations around code structure, variable naming, file moving or anything else. fugitive.vim is a plugin which lets you very quickly recurse into history in this fashion using multiple vim windows.
Yeah, I work in information security for a living, how did you guess?
Even if they they did, once they change the history change, other developers working with the repo would be alerted of the remote branch changing out from under them next time they try to pull. And even if the change doesn't result in a conflict, and each of those other devs blindly accept the resulting merge, the original authors' commits will still be in the history resulting from the merge. So if those developers ever pushed anything, the original commits would be re-introduced.
Now, it could be abused if a single developer inherits a project that nobody else has checked out. But it's still a high risk strategy for the unscrupulous dev.
Have you ever seen that old video "The website is down"? [1]. In it, the guy covers his own tracks with admin privileges. I'm not saying it's easy, just that it's possible.
https://github.com/jayphelps/git-blame-someone-else/graphs/c...
I assumed they were recording actions taken via the github UI and APIs, not the git commit log. If someone merges a pull request you opened, poof, you contributed the lines merged from that pull request regardless of the git author line. Same if you run `git push` with your github login credentials.
Apart from attributing things to the wrong person, git author line seems like it must also have the issue of not attributing things at all. What if I signed up with a different email address than I use for git?
Guess that's middle management then.
[1] https://docs.github.com/en/github/authenticating-to-github/m...
My workmates would hate me if i introduced this to production.
You gain the ability to prove that a certain commit came from your machine or someone with full access to it, they don't.
To be honest, everyone should be signing their commits in a professional environment. It takes minutes of work to set up and greatly increases the trust you can have in the code base.
If you're scared of affecting your workflow, just don't protect the GPG keys with a password (dangerous) or use your operating system's trust store to unlock them at login (less dangerous, but still suboptimal).
I sign my work commits without ever entering a password in a prompt. Some of my coworkers also sign their commits, most of them don't.
https://i.imgur.com/TqbfZaP.png
Git Blame-Someone-Else - https://news.ycombinator.com/item?id=21004193 - Sept 2019 (66 comments)
Git-blame-someone-else – Blame someone else for your bad code - https://news.ycombinator.com/item?id=11049993 - Feb 2016 (65 comments)
To be honest, when you really think about it, any commit that is not GPG signed is unverifiable. It could be anybody. I wish signing commits was more widespread.
(Still among the best-commented code I’ve ever written.)