{"id":20384945,"url":"https://github.com/d-e-s-o/git-blamediff","last_synced_at":"2026-02-19T06:31:33.569Z","repository":{"id":37383760,"uuid":"494345389","full_name":"d-e-s-o/git-blamediff","owner":"d-e-s-o","description":"A program to automatically annotate changes to a file in git(1).","archived":false,"fork":false,"pushed_at":"2024-09-18T04:37:37.000Z","size":46,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-29T23:35:56.516Z","etag":null,"topics":["cli","git","git-addons","git-commands","git-workflow","git-workflows","rust","rust-lang"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/d-e-s-o.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-20T06:20:32.000Z","updated_at":"2024-09-18T04:36:13.000Z","dependencies_parsed_at":"2024-11-15T02:31:48.796Z","dependency_job_id":"44214309-f123-4a23-b01e-9fc2d01b508a","html_url":"https://github.com/d-e-s-o/git-blamediff","commit_stats":{"total_commits":11,"total_committers":1,"mean_commits":11.0,"dds":0.0,"last_synced_commit":"730474b8812a710ba22d4e07b29d4df938c54cf5"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d-e-s-o%2Fgit-blamediff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d-e-s-o%2Fgit-blamediff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d-e-s-o%2Fgit-blamediff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d-e-s-o%2Fgit-blamediff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/d-e-s-o","download_url":"https://codeload.github.com/d-e-s-o/git-blamediff/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253036719,"owners_count":21844268,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","git","git-addons","git-commands","git-workflow","git-workflows","rust","rust-lang"],"created_at":"2024-11-15T02:30:56.700Z","updated_at":"2025-10-07T02:06:50.901Z","avatar_url":"https://github.com/d-e-s-o.png","language":"Rust","readme":"[![pipeline](https://github.com/d-e-s-o/git-blamediff/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/d-e-s-o/git-blamediff/actions/workflows/test.yml)\n[![crates.io](https://img.shields.io/crates/v/git-blamediff.svg)](https://crates.io/crates/git-blamediff)\n\ngit-blamediff\n=============\n\n- [Changelog](CHANGELOG.md)\n\nPurpose\n-------\n\n**git-blamediff** is a program aiding in annotating changes made in a\n``git`` repository with the SHA1 hashes the respective lines in the base\nstate were modified in. This process allows for quick lookup of previous\ncommits of interest or creation of fix-up commits. Depending on your\nworkflow the latter might be massively helpful for sorting in changes to\nthe proper previous commits in a set of changes.\n\n\nUsage\n-----\n\nConsider the following example where a developer noticed that he/she\nforgot a trailing newline on a string to print. The code has not gotten\npushed and so fixing up the commit of interest is the best option. The\npatch looks as follows:\n\n```patch\n --- main.c\n +++ main.c\n@@ -6,6 +6,6 @@ int main(int argc, char const* argv[])\n     fprintf(stderr, \"Too many arguments.\\n\");\n     return -1;\n   }\n-  printf(\"Hello world!\");\n+  printf(\"Hello world!\\n\");\n   return 0;\n }\n```\n\nThere can potentially be a couple of changes being made in the\nrepository. How to find the commit that introduced the initial (faulty)\nline? Usually, one would use ``git blame`` or ``git annotate`` and scan\nthrough the annotated diff to find the line and with it the SHA1 hash of\ninterest. Doing so one either has to manually inspect the entire\nannotated file for the lines of interest or to tediously figure out the\nlines in a file that were modified and craft and pass in an -L argument\nto the blame/annotate invocation.\n\n**git-blamediff** can be used to automated this process. It reads a\npatch such as the one above and automatically invokes ``git`` on the\nrespective lines to print it in annotated form. For example:\n\n```\n$ git diff --relative --no-prefix | git blamediff\n--- main.c\n+++ main.c\n8d4442c  6)     fprintf(stderr, \"Too many arguments.\\n\");\n8d4442c  7)     return -1;\n8d4442c  8)   }\nbd7ee05  9)   printf(\"Hello world!\");\nbd7ee05 10)   return 0;\nbd7ee05 11) }\n```\n\nThis example also illustrates two important properties a patch must have in\norder to be annotated correctly: it should contain paths relative to the\ncurrent working directory (by using the ``--relative`` argument) and contain no\nprefixes (i.e., instead of ``a/some-path/some-file`` just use\n``some-path/some-file``; produced by providing the ``--no-prefix`` option to\n``git``).\n\nThese requirements exist to keep the program concise and not have to\ndeal with too many special cases. Since under normal circumstances one\nwould create an alias shortening the ``git diff`` invocation shown\nbefore, this property is not considered a restriction (see section\n``Installation`` for an example of such aliases).\n\nContinuing the workflow, one could create a fixup commit and then, at\nsome point, perform an interactive rebase in order to automatically have\nthe original changes amended, e.g.:\n\n```shell\n$ git add --all\n$ git commit --fixup bd7ee05\n...\n$ git rebase --interactive --autosquash bd7ee05^\n```\n\n\nInstallation\n------------\n\n**git-blamediff** is written in Rust and requires the Cargo package\nmanager to be built. It can be installed using `cargo install\ngit-blamediff`.\n\nOnce installed, due to the program's name, ``git`` will recognize the\ncommand directly, so it can be invoked as ``git blamediff`` but also via\n``git-blamediff``.\n\nTo simplify usage, a ``git`` alias should be introduced. Two aliases for\nannotating the currently unstaged (``git bd`` -- *\"git blame diff\"*) and\nstaged (``git bds`` -- *\"git blame diff staged\"*) changes, respectively,\ncould look like this:\n\n```git\n[alias]\n  bd = \"!bd() { git diff --relative --no-prefix | git blamediff; }; bd\"\n  bds = \"!bds() { git diff --relative --no-prefix --staged | git blamediff; }; bds\"\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd-e-s-o%2Fgit-blamediff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fd-e-s-o%2Fgit-blamediff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd-e-s-o%2Fgit-blamediff/lists"}