gitlint icon indicating copy to clipboard operation
gitlint copied to clipboard

Gitlint, Jenkins, Git Flow - How to combine them

Open Bearwolves opened this issue 4 years ago • 3 comments

First of all thanks a lot for your nice tool! We are heavily using different automation tools to ease our daily job and we want to use gitlint to clean up our commit messages to create changelog later on a in an automated fashion (example: commitizen).

The aim would be to showcase our use case and maybe get some help/hint about the way we use gitlint. It may profit to others users of gitlint.

Use case: Lint all commits added into the working feature branch locally and in the CI environment

Environment:

  • Jenkins
  • tox
  • GIT Flow as described here
    • merge commit for each Change/Pull Request
    • conventional commits

Initial approach: Revision ranges

We tried to use --commits origin..HEAD as mentioned at https://jorisroovers.com/gitlint/#linting-specific-commits, however it failed in our CI environment as origin (i.e. origin/HEAD i.e. .git/refs/remotes/origin/HEAD) is not downloaded/set by default by the Jenkins GIT Plugin. By trying to understand what origin actually means in that context (see git revisions documentation here and stackoverflow here) we developed the feeling that it's not the best choice to use origin as it represents the default branch of the GIT Repository and not the target branch during the Change/Pull Request. It may lead to confusion especially for repositories which are in transition phase to introduce conventional commits (false positive). Still we tried to find any other GIT Reference/Revision Range which matches our request. We searched a reference which would mean something like branched out commit but unfortunately we couldn't find any. So we tried to change the approach.

Looping over a list of commits

As using a revision range to use gitlint was not successful and we really wanted to find a way to use it, we thought about finding out all the commit which are part of the current feature branch. To do so we played around with git rev-list and created following command to generate the list of commit we want to lint git rev-list --first-parent --no-merges HEAD --not $(git rev-list --max-parents=0 HEAD).

Funnily after understanding better what we wanted, we found a stackoverflow answer which goes into that direction for git log here. For sure, we have to accept the multiple calls of gitlint as of now. May be you have an idea how we could improve that?

Command explanation

See also git-rev-list help

--min-parents= --max-parents= --no-min-parents --no-max-parents Show only commits which have at least (or at most) that many parent commits. In particular, --max-parents=1 is the same as --no-merges, --min-parents=2 is the same as --merges. --max-parents=0 > gives all root commits and --min-parents=3 all octopus merges.

--no-min-parents and --no-max-parents reset these limits (to no limit) again. Equivalent forms are --min-parents=0 (any commit has 0 or more parents) and --max-parents=-1 (negative numbers denote > no upper limit). --first-parent Follow only the first parent commit upon seeing a merge commit. This option can give a better overview when viewing the evolution of a particular topic branch, because merges into a topic branch > tend to be only about adjusting to updated upstream from time to time, and this option allows you to ignore the individual commits brought in to your history by such a merge.

--no-merges Do not print commits with more than one parent. This is exactly the same as --max-parents=1.

We are using git rev-list --max-parents=0 HEAD to remove the initial commit.

Summary

We will introduce this iteration in some of our components to check if we missed any corner cases but maybe you already have some ideas about that?

Bearwolves avatar Jan 18 '22 12:01 Bearwolves

You are correct, the only way to lint multiple commits that can’t be identified by a single refspec is by doing multiple gitlint invocations.

Something I have considered is allowing users to pass a comma-separated list of commit hashes (e.g. gitlint --commits abc123,edf456,etc) , but that’s not a feature that is implemented today.

As to the showcase part, I’m not entirely following. Are you suggesting to add something to the gitlint docs?

jorisroovers avatar Feb 10 '22 21:02 jorisroovers

After thinking about it again, I suggest two things:

  • Adding an argument to pass a command to git rev-list (I guess it's tricky and makes things quite complicated) so I prefer your proposal i.e. a way to provide a list of commit hashes! It would allow us to call gitlint only once.
  • Adding a hint in the documentation or a section like Lint all commit of a feature branch with our approach if you think it's also useful for others! Multiple people are using GIT Flow and may have similar complication to integrate gitlint in their CI/CD workflow.

Bearwolves avatar Feb 13 '22 20:02 Bearwolves

I've created #283 to track development for --commits accepting multiple comma-separated hashes. That should be fairly straightforward to implement.

Wrt documentation, it depends on what you have in mind. How long would this be and where would you fit this in? Might need a rough draft or outline to really understand what you mean.

jorisroovers avatar Apr 15 '22 09:04 jorisroovers