Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[action] git_commit - skip commit if git status is clean for paths #17913

Merged
merged 3 commits into from
Jan 21, 2021

Conversation

felginep
Copy link
Contributor

@felginep felginep commented Jan 7, 2021

Checklist

  • I've run bundle exec rspec from the root directory to see all new and existing tests pass
  • I've followed the fastlane code style and run bundle exec rubocop -a to ensure the code style is valid
  • I've read the Contribution Guidelines
  • I've updated the documentation if necessary.

Motivation and Context

Reverts the commit ef1ccf1 and fix a regression introduced in #17804.

There is an issue when the git_commit lane is executed alone (meaning without git_add before).
In this case, it is not possible to run the sh command git commit because there is no staged files and git --no-pager diff --name-only --staged always returns an empty string.

Description

The proposed solution is to run git status #{paths} --porcelain to check if the git status is clean, only for the paths we want to commit. This way, even if there are other files modified, the git commit can be skipped.

In practice, there are two cases:

  1. fileA is modified (meaning git status fileA --porcelain will return a non empty string)
    1.1 if we call git_commit(path: "fileA", allow_nothing_to_commit: true) -> the commit is created
    1.2 if we call git_commit(path: "fileA", allow_nothing_to_commit: false) -> the commit is created

  2. fileA is not modified (meaning git status fileA --porcelain will return an empty string)
    2.1 we call git_commit(path: "fileA", allow_nothing_to_commit: true) -> the commit is skipped (even if there are other files modified, i.e. git status --porcelain does not return an empty string)
    2.2 we call git_commit(path: "fileA", allow_nothing_to_commit: false) -> an error occurs because fileA can't be staged

Testing Steps

Revert the commit ef1ccf1.
There was an issue when the git_commit lane was executed alone (meaning without git_add before).
In this case, it was not possible to commit because there are no staged files and `git --no-pager diff --name-only --staged` always returns an empty string.
Copy link
Contributor

@ainame ainame left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for doing this.
I'd like to request you to add a way to avoid future regressions. Just a code comment + description updates for allow_nothing_to_commit to clarify the behaviours is fine🙇

Otherwise LGTM 🚀

allow(Fastlane::Actions).to receive(:sh)
.with("git status ./fastlane/README.md --porcelain")
.and_return("M ./fastlane/README.md")
allow(Fastlane::Actions).to receive(:sh)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
allow(Fastlane::Actions).to receive(:sh)
expect(Fastlane::Actions).to receive(:sh)

It feels like this must be called in the given scenario so expect makes sure future change will also behave the same. Though it is checked by below assertion, this would produce a slightly better error message when failing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, I made the change

nothing_staged = Actions.sh("git --no-pager diff --name-only --staged").empty?
UI.success("Nothing staged to commit ✅.") if nothing_staged
return if nothing_staged
repo_clean = Actions.sh("git status #{paths} --porcelain").empty?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add a comment about this behaviour here, and at the description for "allow_nothing_to_commit" param, which "unstaged" changes are taken account and this way allows you to keep the repo dirty without failing?

We missed the behaviour in the last PR so it's definitely worth documenting. Ideally, we should cover it in unit tests but the way we test doesn't allow us to describe the exact situation for it due to sh being mocked or the difficulty to prepare a complete git repo just for a minor action. I can only come up leaving a comment as a way to avoid regressions for now.

@felginep felginep requested a review from ainame January 8, 2021 07:20
Copy link
Contributor

@ainame ainame left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done🎉

@joshdholtz will double-check and merge this PR when he can!

@ainame ainame requested a review from joshdholtz January 8, 2021 09:29
Copy link
Member

@joshdholtz joshdholtz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the tests and comment here! Thanks for fixing! Teamwork ❤️

@joshdholtz joshdholtz merged commit 44a49ad into fastlane:master Jan 21, 2021
Copy link

@fastlane-bot fastlane-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congratulations! 🎉 This was released as part of fastlane 2.172.0 🚀

@felginep felginep deleted the feature/fix_commit_staged branch January 21, 2021 10:50
@fastlane fastlane locked and limited conversation to collaborators Mar 22, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants