{"id":15377242,"url":"https://github.com/kevinsawicki/gitective","last_synced_at":"2025-04-08T04:18:58.072Z","repository":{"id":1522422,"uuid":"1782903","full_name":"kevinsawicki/gitective","owner":"kevinsawicki","description":"Find the Git commits you're looking for","archived":false,"fork":false,"pushed_at":"2023-01-26T23:55:05.000Z","size":2832,"stargazers_count":118,"open_issues_count":11,"forks_count":53,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-24T09:07:35.400Z","etag":null,"topics":["java","jgit"],"latest_commit_sha":null,"homepage":"http://gitective.org","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kevinsawicki.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2011-05-22T05:30:37.000Z","updated_at":"2024-12-25T07:27:16.000Z","dependencies_parsed_at":"2023-02-15T03:15:40.360Z","dependency_job_id":null,"html_url":"https://github.com/kevinsawicki/gitective","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevinsawicki%2Fgitective","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevinsawicki%2Fgitective/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevinsawicki%2Fgitective/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kevinsawicki%2Fgitective/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kevinsawicki","download_url":"https://codeload.github.com/kevinsawicki/gitective/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247773726,"owners_count":20993639,"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":["java","jgit"],"created_at":"2024-10-01T14:10:07.368Z","updated_at":"2025-04-08T04:18:58.047Z","avatar_url":"https://github.com/kevinsawicki.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":":rotating_light::rotating_light::rotating_light:\n\n**This library is no longer maintained or updated. You should fork it and release\nyour own version to Maven Central if you need updates for new features or bug\nfixes.**\n\n:rotating_light::rotating_light::rotating_light:\n\n# gitective - Find the commits you're looking for\n\ngitective is a Java library built on top of [JGit](http://www.eclipse.org/jgit)\nthat makes investigating Git repositories simpler and easier.  Gitective makes\nit straight-forward to find interesting commits in a Git repository through\ncombining the included filters.\n\nThis library is available from [Maven Central](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.gitective%22%20AND%20a%3A%22gitective-core%22)\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eorg.gitective\u003c/groupId\u003e\n  \u003cartifactId\u003egitective-core\u003c/artifactId\u003e\n  \u003cversion\u003e0.9.9\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nJavadocs are available [here](http://gitective.org/apidocs/index.html).\n\n# Details\n\ngitective supports finding commits through registering filters that first\nselect commits and then run matchers against those commits.\n\nThe included filters can be used interchangebly for matching and selecting\ncommits.  This allows you to collect data on all commits visited as well as the\ncommits that match filters.\n\nSuppose you want to find all the commits that fix bugs to Java source files. But\nyou also want to know the total number of commits that fix bugs so you can track\nwhat subset of all the fixes are fixes to Java source files.\n\nYou would find this using the following steps:\n\n  1.  Create a filter that selects commits that reference a bug in the message.\n  2.  Create a filter that selects commits that alter a ```.java``` file.\n  3.  Create a filter that counts the number of commits that are selected.\n\n```java\nCommitCountFilter bugCommits = new CommitCountFilter();\nCommitCountFilter javaBugCommits = new CommitCountFilter();\nCommitFinder finder = new CommitFinder(\"/repos/myrepo/.git\");\n\nfinder.setFilter(new AndCommitFilter(new BugFilter(), bugCommits));\nfinder.setFilter(PathFilterUtils.andSuffix(\".java\"));\nfinder.setMatcher(javaBugCommits);\nfinder.find();\n\nSystem.out.println(javaBugCommits.getCount() + \" java bugs fixed\");\nSystem.out.println(bugCommits.getCount() + \" total bugs fixed\");\n```\n\n## Why would you use gitective?\n\n  * You are new to Git and/or JGit and need to write an application that uses revision history.  Gitective aims to be simple enough to not require a deep understanding of Git or JGit in order to construct a filter to locate the commits you are looking for in a Git Repository.\n\n  * You need to write an application that searches for commit information from multiple Git repositories.  Gitective supports re-using filters across repositories as well as multiple commit searches of the same repository.\n\n  * You want to generate stats or reports based on the commit activity in Git repositories and are looking to use Java/JGit and want a head-start in writing the code that finds the commits needed.\n\n## Commit Examples\nShown below are several examples of using the gitective filters and commit service classes, more examples can be found in the [unit tests](https://github.com/kevinsawicki/gitective/tree/master/org.gitective.core/src/test/java/org/gitective/tests).\n\n### Get the HEAD commit in a repository\n\n```java\nRepository repo = new FileRepository(\"/repos/myrepo/.git\");\nRevCommit latestCommit = CommitUtils.getHead(repo);\nSystem.out.println(\"HEAD commit is \" + latestCommit.name());\n```\n\n### Find the number of commits you authored but weren't the committer of\nThis case is common when doing peer code review or using a code review system.\n\n```java\nPersonIdent person = new PersonIdent(\"Michael Bluth\", \"michael@sitwell.com\");\nCommitCountFilter count = new CommitCountFilter();\nAndCommitFilter filters = new AndCommitFilter();\n\nfilters.add(new AuthorFilter(person));\nfilters.add(new CommitterFilter(person).negate());\nfilters.add(count);\n\nCommitFinder finder = new CommitFinder(\"/repos/myrepo/.git\");\nfinder.setFilter(filters).find();\nSystem.out.println(count.getCount());\n```\n\n### Find everyone who has authored commits that were 10-way merges\nThis example may seem uncommon but it will return 6 different users when run against the [linux kernel repository](http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=summary).\n\n```java\nAuthorSetFilter authors = new AuthorSetFilter();\nAndCommitFilter filters = new AndCommitFilter();\nfilters.add(new ParentCountFilter(10), authors);\n\nCommitFinder finder = new CommitFinder(\"/repos/linux-2.6/.git\");\nfinder.setFilter(filters).find();\n\nfor (PersonIdent author : authors.getPersons())\n     System.out.println(author);\n```\n\n### Find the number of commits that occurred in master since a branch was created\nThis example assumes two current branches,  _master_ and a  _release1_ branch that was created from master some time ago. Both branches have had subsequent commits since the _release1_ branch was created.\n\n```java\nRepository repo = new FileRepository(\"/repos/productA/.git\");\nRevCommit base = CommitUtils.getBase(repo, \"master\", \"release1\");\n\nCommitCountFilter count = new CommitCountFilter();\nCommitFinder finder = new CommitFinder(repo).setFilter(count);\n\nfinder.findBetween(\"master\", base);\nSystem.out.println(\"Commits in master since release1 was branched: \" + count.getCount());\n\ncount.reset();\nfinder.findBetween(\"release1\", base);\nSystem.out.println(\"Commits in release1 since branched from master: \" + count.getCount());\n```\n\n### What fraction of commits have a Gerrit Change-Id?\nThis example finds the number of commits in a repository that contain a [Gerrit](http://code.google.com/p/gerrit/) Change-Id entry in the commit message.\n\n```java\nCommitCountFilter all = new CommitCountFilter();\nCommitCountFilter gerrit = new CommitCountFilter();\nAllCommitFilter filters = new AllCommitFilter();\nfilters.add(new AndCommitFilter(new ChangeIdFilter(), gerrit), all);\n\nCommitFinder finder = new CommitFinder(\"/repos/egit/.git\");\nfinder.setFilter(filters).find();\n\nSystem.out.println(MessageFormat.format(\n     \"{0} out of {1} commits have Gerrit change ids\",\n     gerrit.getCount(),\tall.getCount()));\n```\n\n### Get commits in blocks of 100\nThis example collects commits into a list of a configured size and iteratively processes subsequent commit blocks.\n\n```java\nCommitListFilter block = new CommitListFilter();\nCommitFilter limit = new CommitLimitFilter(100).setStop(true);\nAndCommitFilter filters = new AndCommitFilter(limit, block);\nCommitCursorFilter cursor = new CommitCursorFilter(filters);\n\nRepository repo = new FileRepository(\"/repos/jgit/.git\");\nCommitFinder finder = new CommitFinder(repo);\nfinder.setFilter(cursor);\n\nRevCommit commit = CommitUtils.getHead(repo);\nwhile (commit != null) {\n     finder.findFrom(commit);\n\n     // block filter now contains a new block of commits\n\n     commit = cursor.getLast();\n     cursor.reset();\n}\n```\n\n### Find commits referencing bugs\nThis example collects all the commits that have a 'Bug: XXXXXXX' line in the commit message.\n\n```java\nCommitListFilter commits = new CommitListFilter();\nAndCommitFilter filter = new AndCommitFilter(new BugFilter(), commits);\n\nCommitFinder finder = new CommitFinder(\"/repos/jgit/.git\");\nfinder.setFilter(filter).find();\n```\n\n### Find files modified during a merge\nThis example visits all the files that were modified as part of a merge.\n\n```java\nCommitDiffFilter diffs = new CommitDiffFilter() {\n\n     protected boolean include(RevCommit commit, Collection\u003cDiffEntry\u003e diffs) {\n          // Diffs collection contains all files modified during merge\n     }\n\n};\nAndCommitFilter filter = new AndCommitFilter(new ParentCountFilter(), diff);\n\nCommitFinder finder = new CommitFinder(\"/repos/jgit/.git\");\nfinder.setFilter(filter).find();\n```\n\n### Inspect notes associated with commits\nThis example visits all Git notes associated with each commit visited.\n\n```java\nNoteContentFilter notes = new NoteContentFilter() {\n\n     protected boolean include(RevCommit commit, Note note, String content) {\n          // Content string contains text of note associated with commit\n     }\n\n};\n\nCommitFinder finder = new CommitFinder(\"/repos/jgit/.git\");\nfinder.setFilter(notes).find();\n```\n\n### Generate commit histogram\nThis examples prints out how many commits happened each year in August.\n\n```java\nAuthorHistogramFilter filter = new AuthorHistogramFilter();\nCommitFinder finder = new CommitFinder(\"/repos/redis/.git\");\nfinder.setFilter(filter).find();\n\nUserCommitActivity[] activity = filter.getHistogram().getUserActivity();\nCommitCalendar commits = new CommitCalendar(activity);\n\nfor(YearCommitActivity year : commits.getYears())\n     System.out.println(year.getMonthCount(Month.AUGUST)\n                          + \" commits in August, \" + year.getYear());\n```\n\n## Blob Examples\n\n### Get content of file in HEAD commit\n\n```java\nRepository repo = new FileRepository(\"/repos/jgit/.git\");\nString content = BlobUtils.getHeadContent(repo, \"src/Buffer.java\");\n```\n\n### Diff two files\n\n```java\nRepository repo = new FileRepository(\"/repos/jgit/.git\");\n\nObjectId current = BlobUtils.getId(repo, \"master\", \"Main.java\");\nObjectId previous = BlobUtils.getId(repo, \"master~1\", \"Main.java\");\n\nCollection\u003cEdit\u003e edit = BlobUtils.diff(repo, previous, current);\n```\n\n## Building from source\ngitective can be built using [Maven](http://maven.apache.org/). The pom.xml to build the core plug-in is located at the root of the org.gitective.core folder.\n\n```\ncd gitective/org.gitective.core\nmvn clean install\n```\n\n## Dependencies\n\nJGit 1.0+\n\n## License\n\n[MIT License](http://www.opensource.org/licenses/mit-license.php)\n\n## Contributors\n\n* [Kevin Sawicki](https://github.com/kevinsawicki) :: [contributions](https://github.com/kevinsawicki/gitective/commits?author=kevinsawicki)\n* [Mykola Nikishov](https://github.com/manandbytes) :: [contributions](https://github.com/kevinsawicki/gitective/commits?author=manandbytes)\n* [James Moger](https://github.com/gitblit) :: [contributions](https://github.com/kevinsawicki/gitective/commits?author=gitblit)\n* [Maik Schreiber](https://github.com/blizzy78) :: [contributions](https://github.com/kevinsawicki/gitective/commits?author=blizzy78)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinsawicki%2Fgitective","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkevinsawicki%2Fgitective","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinsawicki%2Fgitective/lists"}