gitlogstats 1.0.7__tar.gz → 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/PKG-INFO +99 -18
  2. gitlogstats-1.1.0/Pipfile.lock +751 -0
  3. gitlogstats-1.1.0/README.md +247 -0
  4. gitlogstats-1.1.0/docs/SPEC.md +237 -0
  5. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/pyproject.toml +4 -4
  6. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/scripts/board/config.mjs +1 -1
  7. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/scripts/board/manifest.yaml +147 -17
  8. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/src/gitlogstats/__main__.py +35 -5
  9. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/src/gitlogstats/git_logs_parser.py +128 -32
  10. gitlogstats-1.1.0/src/gitlogstats/github.py +271 -0
  11. gitlogstats-1.1.0/src/gitlogstats/github_stats.py +152 -0
  12. gitlogstats-1.1.0/src/gitlogstats/identity.py +251 -0
  13. gitlogstats-1.1.0/tests/fake_gh.py +92 -0
  14. gitlogstats-1.1.0/tests/fixtures/github/commit_linked.json +5 -0
  15. gitlogstats-1.1.0/tests/fixtures/github/commit_unlinked.json +5 -0
  16. gitlogstats-1.1.0/tests/fixtures/github/contributors.json +4 -0
  17. gitlogstats-1.1.0/tests/fixtures/github/contributors_page2.json +3 -0
  18. gitlogstats-1.1.0/tests/fixtures/github/pulls_page1.json +20 -0
  19. gitlogstats-1.1.0/tests/fixtures/github/pulls_page2.json +29 -0
  20. gitlogstats-1.1.0/tests/fixtures/github/user_full.json +1 -0
  21. gitlogstats-1.1.0/tests/fixtures/github/user_private.json +1 -0
  22. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/tests/test_git_logs_parser.py +111 -21
  23. gitlogstats-1.1.0/tests/test_github.py +542 -0
  24. gitlogstats-1.1.0/tests/test_identity.py +370 -0
  25. gitlogstats-1.1.0/tests/test_integration.py +1539 -0
  26. gitlogstats-1.0.7/Pipfile.lock +0 -579
  27. gitlogstats-1.0.7/README.md +0 -166
  28. gitlogstats-1.0.7/docs/SPEC.md +0 -185
  29. gitlogstats-1.0.7/tests/test_integration.py +0 -592
  30. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/.claude/CLAUDE.md +0 -0
  31. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/.claude/agents/developer-agent.md +0 -0
  32. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/.claude/agents/spec-reviewer.md +0 -0
  33. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/.claude/hooks/format-edited.sh +0 -0
  34. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/.claude/hooks/guard-paths.sh +0 -0
  35. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/.claude/hooks/guard-paths.test.mjs +0 -0
  36. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/.claude/hooks/verify.sh +0 -0
  37. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/.claude/settings.json +0 -0
  38. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/.claude/skills/phase-handoff/SKILL.md +0 -0
  39. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/.claude/skills/stale-check/SKILL.md +0 -0
  40. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/.github/workflows/build.yaml +0 -0
  41. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/.gitignore +0 -0
  42. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/.prettierrc.json +0 -0
  43. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/LICENSE +0 -0
  44. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/Pipfile +0 -0
  45. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/package-lock.json +0 -0
  46. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/package.json +0 -0
  47. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/repos.txt +0 -0
  48. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/requirements.txt +0 -0
  49. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/scripts/board/derive.mjs +0 -0
  50. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/scripts/board/derive.test.mjs +0 -0
  51. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/scripts/board/sync.mjs +0 -0
  52. {gitlogstats-1.0.7 → gitlogstats-1.1.0}/src/gitlogstats/__init__.py +0 -0
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: gitlogstats
3
- Version: 1.0.7
3
+ Version: 1.1.0
4
4
  Summary: Track developers' contributions to one or more git repositories within a particular time range.
5
- Project-URL: Homepage, https://github.com/bloombar/git-developer-contribution-analysis
6
- Project-URL: Repository, https://github.com/bloombar/git-developer-contribution-analysis.git
7
- Project-URL: Bug Tracker, https://github.com/bloombar/git-developer-contribution-analysis/issues
5
+ Project-URL: Homepage, https://github.com/bloombar/gitlogstats
6
+ Project-URL: Repository, https://github.com/bloombar/gitlogstats.git
7
+ Project-URL: Bug Tracker, https://github.com/bloombar/gitlogstats/issues
8
8
  Author-email: Tobody Tothing <nobody.nothing@nowhere.com>
9
9
  License: GNU GENERAL PUBLIC LICENSE
10
10
  Version 3, 29 June 2007
@@ -695,7 +695,7 @@ Requires-Dist: pytest-cov; extra == 'dev'
695
695
  Requires-Dist: twine; extra == 'dev'
696
696
  Description-Content-Type: text/markdown
697
697
 
698
- ![build](https://github.com/bloombar/git-developer-contribution-analysis/actions/workflows/build.yaml/badge.svg)
698
+ ![build](https://github.com/bloombar/gitlogstats/actions/workflows/build.yaml/badge.svg)
699
699
 
700
700
  # Git Developer Contributions Analysis
701
701
 
@@ -707,6 +707,9 @@ This script calculates the following, for each developer in each repository:
707
707
  - number of **lines added**
708
708
  - number of **lines deleted**
709
709
  - number of **files changed**
710
+ - number of **merges** into the analyzed branch
711
+
712
+ With `--github`, it also reports each developer's GitHub **pull requests** opened, merged and closed without merging (see [GitHub pull requests](#github-pull-requests)).
710
713
 
711
714
  The results can be formatted as `csv`, `json`, or `markdown`.
712
715
 
@@ -721,26 +724,36 @@ e.g. `pip install gitlogstats`, `pip3 install gitlogstats`, depending on your en
721
724
  The command `gitlogstats --help` shows the usage instructions:
722
725
 
723
726
  ```
724
- usage: gitlogstats [-h] (-r REPOSITORY | -rf REPOFILE) [-u USER] [-s START] [-e END] [-x EXCLUSIONS] [-f {csv,json,markdown}] [-b BRANCH] [-v] [-c]
727
+ usage: gitlogstats [-h] (-r REPOSITORY | -rf REPOFILE) [-u USER] [-s START]
728
+ [-e END] [-x EXCLUSIONS] [-f {csv,json,markdown}]
729
+ [-b BRANCH] [-v] [-c] [--github]
725
730
 
726
- optional arguments:
731
+ options:
727
732
  -h, --help show this help message and exit
728
733
  -r REPOSITORY, --repository REPOSITORY
729
734
  the public URL of the repository whose logs to parse
730
735
  -rf REPOFILE, --repofile REPOFILE
731
- the path to simple text file with a list of repository URLs to parse
732
- -u USER, --user USER The git username (or email address) to report. Default is all contributing users
736
+ the path to simple text file with a list of repository
737
+ URLs to parse
738
+ -u USER, --user USER The git username (or email address) to report. Default
739
+ is all contributing users
733
740
  -s START, --start START
734
741
  Start date in mm/dd/yyyy format
735
742
  -e END, --end END End date in mm/dd/yyyy format
736
743
  -x EXCLUSIONS, --exclusions EXCLUSIONS
737
- A comma-separated string of files to exclude, e.g. --excusions "foo.zip, *.jpg, *.json"
744
+ A comma-separated list of files, patterns or
745
+ directories to exclude, e.g. --exclusions "foo.zip,
746
+ *.jpg, vendor". Replaces the default list; use "" to
747
+ exclude nothing
738
748
  -f {csv,json,markdown}, --format {csv,json,markdown}
739
749
  The format in which to output the results
740
750
  -b BRANCH, --branch BRANCH
741
- The branch to checkout before compiling statistics. Defaults to the repository's default branch.
751
+ The branch to parse, if not the default branch
742
752
  -v, --verbose Whether to output debugging info
743
753
  -c, --clean Remove contributors without any contribuition
754
+ --github Also report GitHub pull requests opened, merged and
755
+ closed per contributor, and match GitHub users to git
756
+ authors. Needs the GitHub CLI (gh), signed in
744
757
  ```
745
758
 
746
759
  In case `gitlogstats` is not found as a command, even after installing, try `python -m gitlogstats` or `python3 -m gitlogstats` instead.
@@ -754,7 +767,7 @@ The `-r` and `-rf` flags control whether the script looks at a single repository
754
767
  Output the contributions of all developers to a single repository:
755
768
 
756
769
  ```bash
757
- gitlogstats -r https://github.com/bloombar/git-developer-contribution-analysis.git
770
+ gitlogstats -r https://github.com/bloombar/gitlogstats.git
758
771
  ```
759
772
 
760
773
  Output the contributions of all developers to a set of repositories stored in a file named `repos.txt`, one URL per line (see [example file](./repos.txt)). Blank lines and lines starting with `#` are ignored. The results for all repositories are combined into a single table:
@@ -770,7 +783,7 @@ By default, the statistics of all contributors are calculated. The `-u` flag can
770
783
  Output the contributions of only the contributor named `bloombar` to a single repository:
771
784
 
772
785
  ```bash
773
- gitlogstats -u bloombar -r https://github.com/bloombar/git-developer-contribution-analysis.git
786
+ gitlogstats -u bloombar -r https://github.com/bloombar/gitlogstats.git
774
787
  ```
775
788
 
776
789
  The same, but to a batch of repositories listed in the `repos.txt` file:
@@ -786,7 +799,7 @@ By default, contributions from a year ago until today are analyzed. Use the `-s`
786
799
  Output the contributions to a single repository for a specific date range, inclusive.
787
800
 
788
801
  ```bash
789
- gitlogstats -s 11/15/2021 -e 12/15/2021 -r https://github.com/bloombar/git-developer-contribution-analysis.git
802
+ gitlogstats -s 11/15/2021 -e 12/15/2021 -r https://github.com/bloombar/gitlogstats.git
790
803
  ```
791
804
 
792
805
  The same, but to a batch of repositories listed in the `repos.txt` file:
@@ -795,6 +808,24 @@ The same, but to a batch of repositories listed in the `repos.txt` file:
795
808
  gitlogstats -s 11/15/2021 -e 12/15/2021 -rf repos.txt
796
809
  ```
797
810
 
811
+ ### Excluding files
812
+
813
+ By default, common generated and binary files are left out of the analysis: `package.json`, `package-lock.json`, `Pipfile`, `Pipfile.lock`, `requirements.txt`, `*.jpg`, `*.png`, `*.gif`, `*.svg`, `*.pdf`, `*.zip`, `*.gz`, `*.tar`, `*.csv` and `*.json`. Use `-x` to give your own comma-separated list instead. It replaces the default list rather than adding to it.
814
+
815
+ Each item can be a file name, a glob pattern or a directory, and is matched in any directory of the repository. A directory name, such as `vendor` or `vendor/`, excludes everything inside it. A path such as `docs/*.md` matches only inside directories with that name.
816
+
817
+ ```
818
+ gitlogstats -rf repos.txt -x "*.json, *.lock, vendor, docs/*.md"
819
+ ```
820
+
821
+ Exclude nothing:
822
+
823
+ ```
824
+ gitlogstats -rf repos.txt -x ""
825
+ ```
826
+
827
+ Excluded files are left out of the commit, line and file counts. A commit that only touches excluded files is not counted at all. Exclusions do not affect the merge count.
828
+
798
829
  ### Filter Contributors
799
830
 
800
831
  By default, every contributor in a repository's history is listed, with zeros for those who were inactive in the date range. Use `-c` to show only contributors with activity.
@@ -803,6 +834,46 @@ By default, every contributor in a repository's history is listed, with zeros fo
803
834
  gitlogstats -rf repos.txt -c
804
835
  ```
805
836
 
837
+ ### GitHub pull requests
838
+
839
+ Add `--github` to also count each contributor's pull requests. Four columns are appended to every output format:
840
+
841
+ | Column | Meaning |
842
+ | --------------------- | ----------------------------------------------------------------------------------------------------- |
843
+ | `github_username` | the GitHub account matched to the contributor (never the display name), so you can check the matching |
844
+ | `prs_opened` | pull requests they opened in the date range, whatever their state now (drafts included) |
845
+ | `prs_merged` | pull requests they authored that were merged in the date range, by anyone and in any way (squash too) |
846
+ | `prs_closed_unmerged` | pull requests they authored that were closed without merging in the date range |
847
+
848
+ ```
849
+ gitlogstats -r https://github.com/bloombar/gitlogstats.git --github
850
+ ```
851
+
852
+ **Requirements.** Only `--github` needs the [GitHub CLI](https://cli.github.com) (`gh`); without the flag nothing changes and GitHub is never contacted. Install `gh`, then run `gh auth login`. The tool checks this before cloning anything. If it fails, nothing is printed to standard output, the exit status is 1 and one of these messages is printed to standard error:
853
+
854
+ ```
855
+ gitlogstats: --github needs the GitHub CLI (gh), which is not installed. Install it from https://cli.github.com and run 'gh auth login', or run without --github.
856
+ gitlogstats: --github needs the GitHub CLI (gh) to be signed in. Run 'gh auth login', or run without --github.
857
+ ```
858
+
859
+ **Empty versus zero.** A zero means GitHub was asked and the person has none. An empty value (`null` in JSON) means GitHub could not be asked for that repository: it is not on github.com, or the request failed (no network, rate limit, a private repository you cannot see). The git statistics are still reported, the reason is printed to standard error, and the other repositories carry on. A contributor with no GitHub account matched has an empty `github_username` and zero pull requests. A GitHub user who opened pull requests but has no commits is listed in a row of their own with an empty `username` and zero git statistics.
860
+
861
+ **Matching GitHub users to git authors.** Each git author name is compared with the GitHub users active in the repository, trying these in order and stopping at the first that finds exactly one user:
862
+
863
+ 1. **Email.** The email is a GitHub `noreply` address containing the username, GitHub itself links one of the author's commits to an account, or the email is the public email of a GitHub profile.
864
+ 2. **Username.** The author name, or the part of the email before the `@`, is the GitHub username (ignoring case, and treating spaces, hyphens, underscores and dots as alike). The part before the `@` is skipped when it names a role rather than a person (such as `noreply`, `admin` or `info`), or when several author names in the repository share it (`alex@gmail…` and `alex@school…`), since it could belong to either.
865
+ 3. **Display name.** The author name is the GitHub profile name (ignoring case, accents, punctuation and word order, so `Grace Hopper` matches `Hopper, Grace`).
866
+
867
+ If a step finds several users it is skipped as ambiguous and the next is tried. All git names matched to one GitHub user become one row: the `username` is the name with the most commits and the git statistics are added up. Use `-v` to see which step matched each name, the ambiguous and unmatched names, and how many `gh` calls were made. A wrong match can be fixed with a `.mailmap` file.
868
+
869
+ **How the other options apply.**
870
+
871
+ - `-s` / `-e`: each pull request count uses its own timestamp (opened, merged or closed) against the same inclusive local-time range as commits.
872
+ - `-b`: only pull requests whose base branch is that branch are counted; without `-b`, all pull requests count.
873
+ - `-u`: selects the combined row whose author names or emails equal the value exactly, or whose GitHub username equals it ignoring case. The whole combined row is reported, so `-u` with one email address also includes the person's commits under their other names and emails, and a value that matches nobody prints no row.
874
+ - `-c`: removes only rows with no git activity and no pull requests.
875
+ - `-x`: has no effect on pull requests.
876
+
806
877
  ### Formatting the results
807
878
 
808
879
  The results can be formatted as `csv`, `json`, or a `markdown` table. The default is `csv`. Use the `-f` flag to control the output format.
@@ -816,7 +887,7 @@ gitlogstats -s 11/15/2021 -e 12/15/2021 -rf repos.txt -f markdown
816
887
  Flags can be combined to provide more targeted analysis, e.g. a specific contributor over a specific date range
817
888
 
818
889
  ```
819
- gitlogstats -u bloombar -s 11/15/2021 -e 12/15/2021 -r https://github.com/bloombar/git-developer-contribution-analysis.git -f json
890
+ gitlogstats -u bloombar -s 11/15/2021 -e 12/15/2021 -r https://github.com/bloombar/gitlogstats.git -f json
820
891
  ```
821
892
 
822
893
  The same, but to a batch of repositories listed in the `repos.txt` file:
@@ -831,11 +902,21 @@ Use `-v` to print debugging information. It is written to standard error, so the
831
902
 
832
903
  ## How statistics are counted
833
904
 
834
- - **commits** — commits authored by the contributor in the date range, including merge commits. Commits that change no files, or only excluded files (`-x`), are not counted.
835
- - **insertions** / **deletions** — lines added and removed, as reported by `git log --shortstat`. Binary files and merge commits add no lines, so merged work is never counted twice.
905
+ - **commits** — non-merge commits authored by the contributor in the date range. Commits that change no files, or only excluded files (`-x`), are not counted. Merge commits are counted under **merges** instead.
906
+ - **insertions** / **deletions** — lines added and removed, as reported by `git log --shortstat`. Binary files add no lines, and merges add none either, so merged work is never counted twice.
836
907
  - **files** — the number of files each commit changed, summed over the contributor's commits.
908
+ - **merges** — merge commits the contributor made directly on the analyzed branch in the date range. The author of a merge commit is the person who merged, so this covers merges made locally and pushed, and pull requests merged on GitHub, GitLab or Bitbucket with a merge commit.
909
+
910
+ Some merges are not counted:
911
+
912
+ - Merges that leave no merge commit: fast-forward merges, and pull requests merged with "Squash and merge" or "Rebase and merge". A squash commit counts as an ordinary commit by whoever made it.
913
+ - Merges made inside another branch, such as merging `main` into a feature branch with `git pull` or GitHub's "Update branch" button. These keep a branch up to date rather than merge work into it.
914
+ - Merges on other branches, unless that branch is analyzed with `-b`.
915
+ - Local merges that were never pushed.
916
+
917
+ A merge made on GitHub uses the person's GitHub profile name and email, which may differ from their local git settings. They can then appear under two names (see [Redundant usernames](#redundant-usernames)).
837
918
 
838
- Each commit is credited to its author's name, after applying the repository's `.mailmap` if it has one. Commit messages are never read, so statistics are the same whether messages are one line, many lines, or empty.
919
+ Each commit is credited to its author's name, after applying the repository's `.mailmap` if it has one. Merges are credited the same way. Commit messages are never read, so statistics are the same whether messages are one line, many lines, or empty.
839
920
 
840
921
  ## Development
841
922