From 3558649572ba79e8e44f7b67c5e5d6bbe8a30838 Mon Sep 17 00:00:00 2001 From: Marco Ferrari Date: Fri, 27 Sep 2024 14:40:56 +0000 Subject: [PATCH] fix: handle push tag events on merge commits When a "push tag" event triggers a GitHub Actions workflow, the "commits" array in the event payload is empty, so the commit count in this case (GITHUB_PUSH_COMMIT_COUNT) is 0. In the particular case of a tag pointing to a merge commit, adjust the logic that initializes GITHUB_PUSH_COMMIT_COUNT. Close #6193 --- Makefile | 9 +- lib/functions/githubEvent.sh | 2 + lib/linter.sh | 20 +- .../github-event-push-tag-merge-commit.json | 172 ++++++++++++++++++ test/lib/validationTest.sh | 26 ++- test/run-super-linter-tests.sh | 61 ++++--- test/testUtils.sh | 11 ++ 7 files changed, 256 insertions(+), 45 deletions(-) create mode 100644 test/data/github-event/github-event-push-tag-merge-commit.json diff --git a/Makefile b/Makefile index 3f1d8ca1..ca3b0cf1 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ all: info docker test ## Run all targets. .PHONY: test -test: info validate-container-image-labels docker-build-check docker-dev-container-build-check test-lib inspec lint-codebase fix-codebase test-default-config-files test-actions-runner-debug test-actions-steps-debug test-runner-debug test-find lint-subset-files test-custom-ssl-cert test-non-default-workdir test-git-flags test-non-default-home-directory test-git-initial-commit test-git-merge-commit-push test-log-level test-use-find-and-ignore-gitignored-files test-linters-expect-failure-log-level-notice test-bash-exec-library-expect-success test-bash-exec-library-expect-failure test-save-super-linter-output test-save-super-linter-output-custom-path test-save-super-linter-custom-summary test-custom-gitleaks-log-level test-dont-save-super-linter-log-file test-dont-save-super-linter-output test-linters test-linters-fix-mode ## Run the test suite +test: info validate-container-image-labels docker-build-check docker-dev-container-build-check test-lib inspec lint-codebase fix-codebase test-default-config-files test-actions-runner-debug test-actions-steps-debug test-runner-debug test-find lint-subset-files test-custom-ssl-cert test-non-default-workdir test-git-flags test-non-default-home-directory test-git-initial-commit test-git-merge-commit-push test-git-merge-commit-push-tag test-log-level test-use-find-and-ignore-gitignored-files test-linters-expect-failure-log-level-notice test-bash-exec-library-expect-success test-bash-exec-library-expect-failure test-save-super-linter-output test-save-super-linter-output-custom-path test-save-super-linter-custom-summary test-custom-gitleaks-log-level test-dont-save-super-linter-log-file test-dont-save-super-linter-output test-linters test-linters-fix-mode ## Run the test suite # if this session isn't interactive, then we don't want to allocate a # TTY, which would fail, but if it is interactive, we do want to attach @@ -539,6 +539,13 @@ test-git-merge-commit-push: ## Run super-linter against a repository that has me "run_test_case_merge_commit_push" \ "$(IMAGE)" +.PHONY: test-git-merge-commit-push-tag +test-git-merge-commit-push-tag: ## Run super-linter against a repository that has merge commits and pushed a tag + $(CURDIR)/test/run-super-linter-tests.sh \ + $(SUPER_LINTER_TEST_CONTAINER_URL) \ + "run_test_case_merge_commit_push_tag" \ + "$(IMAGE)" + .PHONY: test-use-find-and-ignore-gitignored-files test-use-find-and-ignore-gitignored-files: ## Run super-linter with USE_FIND_ALGORITHM=true and IGNORE_GITIGNORED_FILES=true $(CURDIR)/test/run-super-linter-tests.sh \ diff --git a/lib/functions/githubEvent.sh b/lib/functions/githubEvent.sh index aea09357..8c0a4271 100755 --- a/lib/functions/githubEvent.sh +++ b/lib/functions/githubEvent.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +# Push event payload ref: https://docs.github.com/en/webhooks/webhook-events-and-payloads#push + function GetGithubPushEventCommitCount() { local GITHUB_EVENT_FILE_PATH GITHUB_EVENT_FILE_PATH="${1}" diff --git a/lib/linter.sh b/lib/linter.sh index 1b457fa4..bc6f88d8 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -270,7 +270,7 @@ GetGitHubVars() { fatal "Failed to get GITHUB_EVENT_PATH: ${GITHUB_EVENT_PATH}]" else info "Successfully found GITHUB_EVENT_PATH: ${GITHUB_EVENT_PATH}]" - debug "${GITHUB_EVENT_PATH} contents: $(cat "${GITHUB_EVENT_PATH}")" + debug "${GITHUB_EVENT_PATH} contents:\n$(cat "${GITHUB_EVENT_PATH}")" fi if [ -z "${GITHUB_SHA:-}" ]; then @@ -315,7 +315,7 @@ GetGitHubVars() { info "Successfully found GITHUB_PUSH_COMMIT_COUNT: ${GITHUB_PUSH_COMMIT_COUNT}" # Ref: https://docs.github.com/en/actions/learn-github-actions/contexts#github-context - debug "Get the hash of the commit to start the diff from from Git because the GitHub push event payload may not contain references to base_ref or previous commit." + debug "Get the hash of the commit to start the diff from Git because the GitHub push event payload may not contain references to base_ref or previous commit." debug "Check if the commit is a merge commit by checking if it has more than one parent" local GIT_COMMIT_PARENTS_COUNT @@ -656,12 +656,18 @@ cleanup() { fi if [ "${SAVE_SUPER_LINTER_OUTPUT}" = "true" ]; then - if [ -e "${SUPER_LINTER_OUTPUT_DIRECTORY_PATH}" ]; then - debug "${SUPER_LINTER_OUTPUT_DIRECTORY_PATH} already exists. Deleting it before moving the new output directory there." - rm -fr "${SUPER_LINTER_OUTPUT_DIRECTORY_PATH}" + debug "Super-linter output directory path is set to ${SUPER_LINTER_OUTPUT_DIRECTORY_PATH:-"not set"}" + if [[ -n "${SUPER_LINTER_OUTPUT_DIRECTORY_PATH:-}" ]]; then + debug "Super-linter output directory path is set to ${SUPER_LINTER_OUTPUT_DIRECTORY_PATH}" + if [ -e "${SUPER_LINTER_OUTPUT_DIRECTORY_PATH}" ]; then + debug "${SUPER_LINTER_OUTPUT_DIRECTORY_PATH} already exists. Deleting it before moving the new output directory there." + rm -fr "${SUPER_LINTER_OUTPUT_DIRECTORY_PATH}" + fi + debug "Moving Super-linter output from ${SUPER_LINTER_PRIVATE_OUTPUT_DIRECTORY_PATH} to ${SUPER_LINTER_OUTPUT_DIRECTORY_PATH}" + mv "${SUPER_LINTER_PRIVATE_OUTPUT_DIRECTORY_PATH}" "${SUPER_LINTER_OUTPUT_DIRECTORY_PATH}" + else + debug "Skip moving the private Super-linter output directory (${SUPER_LINTER_PRIVATE_OUTPUT_DIRECTORY_PATH}) to the output directory because the Super-linter output destination directory path is not initialized yet" fi - debug "Moving Super-linter output from ${SUPER_LINTER_PRIVATE_OUTPUT_DIRECTORY_PATH} to ${SUPER_LINTER_OUTPUT_DIRECTORY_PATH}" - mv "${SUPER_LINTER_PRIVATE_OUTPUT_DIRECTORY_PATH}" "${SUPER_LINTER_OUTPUT_DIRECTORY_PATH}" else debug "Skip moving the private Super-linter output directory (${SUPER_LINTER_PRIVATE_OUTPUT_DIRECTORY_PATH}) to the output directory (${SUPER_LINTER_OUTPUT_DIRECTORY_PATH:-"not initialized yet"})" fi diff --git a/test/data/github-event/github-event-push-tag-merge-commit.json b/test/data/github-event/github-event-push-tag-merge-commit.json new file mode 100644 index 00000000..3afa5175 --- /dev/null +++ b/test/data/github-event/github-event-push-tag-merge-commit.json @@ -0,0 +1,172 @@ +{ + "after": "e8fd3808e35b28ac12c507c1951ff0618a86b29f", + "base_ref": "refs/heads/master", + "before": "0000000000000000000000000000000000000000", + "commits": [], + "compare": "https://github.com/xxxs/xxx-rails/compare/v1.0.1-beta", + "created": true, + "deleted": false, + "forced": false, + "head_commit": { + "author": { + "email": "jandres.rodriguezg@gmail.com", + "name": "Name", + "username": "xxxxxxxxx" + }, + "committer": { + "email": "noreply@github.com", + "name": "GitHub", + "username": "web-flow" + }, + "distinct": true, + "id": "e8fd3808e35b28ac12c507c1951ff0618a86b29f", + "message": "Merge pull request #473 from xxxs/staging\nStaging into Master", + "timestamp": "2024-09-26T15:03:27-03:00", + "tree_id": "351ac4e0681695ab1148ae31e1afda410575acfa", + "url": "https://github.com/xxxs/xxx-rails/commit/e8fd3808e35b28ac12c507c1951ff0618a86b29f" + }, + "organization": { + "avatar_url": "https://avatars.githubusercontent.com/u/47795042?v=4", + "description": "", + "events_url": "https://api.github.com/orgs/xxxs/events", + "hooks_url": "https://api.github.com/orgs/xxxs/hooks", + "id": 47795042, + "issues_url": "https://api.github.com/orgs/xxxs/issues", + "login": "xxxs", + "members_url": "https://api.github.com/orgs/xxxs/members{/member}", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjQ3Nzk1MDQy", + "public_members_url": "https://api.github.com/orgs/xxxs/public_members{/member}", + "repos_url": "https://api.github.com/orgs/xxxs/repos", + "url": "https://api.github.com/orgs/xxxs" + }, + "pusher": { + "email": "blah@gmail.com", + "name": "xxxxxx" + }, + "ref": "refs/tags/v1.0.1-beta", + "repository": { + "allow_forking": false, + "archive_url": "https://api.github.com/repos/xxxs/xxx-rails/{archive_format}{/ref}", + "archived": false, + "assignees_url": "https://api.github.com/repos/xxxs/xxx-rails/assignees{/user}", + "blobs_url": "https://api.github.com/repos/xxxs/xxx-rails/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/xxxs/xxx-rails/branches{/branch}", + "clone_url": "https://github.com/xxxs/xxx-rails.git", + "collaborators_url": "https://api.github.com/repos/xxxs/xxx-rails/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/xxxs/xxx-rails/comments{/number}", + "commits_url": "https://api.github.com/repos/xxxs/xxx-rails/commits{/sha}", + "compare_url": "https://api.github.com/repos/xxxs/xxx-rails/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/xxxs/xxx-rails/contents/{+path}", + "contributors_url": "https://api.github.com/repos/xxxs/xxx-rails/contributors", + "created_at": 1700572951, + "custom_properties": {}, + "default_branch": "develop", + "deployments_url": "https://api.github.com/repos/xxxs/xxx-rails/deployments", + "description": null, + "disabled": false, + "downloads_url": "https://api.github.com/repos/xxxs/xxx-rails/downloads", + "events_url": "https://api.github.com/repos/xxxs/xxx-rails/events", + "fork": false, + "forks": 0, + "forks_count": 0, + "forks_url": "https://api.github.com/repos/xxxs/xxx-rails/forks", + "full_name": "xxxs/xxx-rails", + "git_commits_url": "https://api.github.com/repos/xxxs/xxx-rails/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/xxxs/xxx-rails/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/xxxs/xxx-rails/git/tags{/sha}", + "git_url": "git://github.com/xxxs/xxx-rails.git", + "has_discussions": false, + "has_downloads": true, + "has_issues": true, + "has_pages": false, + "has_projects": true, + "has_wiki": false, + "homepage": null, + "hooks_url": "https://api.github.com/repos/xxxs/xxx-rails/hooks", + "html_url": "https://github.com/xxxs/xxx-rails", + "id": 721637957, + "is_template": false, + "issue_comment_url": "https://api.github.com/repos/xxxs/xxx-rails/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/xxxs/xxx-rails/issues/events{/number}", + "issues_url": "https://api.github.com/repos/xxxs/xxx-rails/issues{/number}", + "keys_url": "https://api.github.com/repos/xxxs/xxx-rails/keys{/key_id}", + "labels_url": "https://api.github.com/repos/xxxs/xxx-rails/labels{/name}", + "language": "Ruby", + "languages_url": "https://api.github.com/repos/xxxs/xxx-rails/languages", + "license": null, + "master_branch": "develop", + "merges_url": "https://api.github.com/repos/xxxs/xxx-rails/merges", + "milestones_url": "https://api.github.com/repos/xxxs/xxx-rails/milestones{/number}", + "mirror_url": null, + "name": "xxx-rails", + "node_id": "R_kgDOKwNSRQ", + "notifications_url": "https://api.github.com/repos/xxxs/xxx-rails/notifications{?since,all,participating}", + "open_issues": 0, + "open_issues_count": 0, + "organization": "xxxs", + "owner": { + "avatar_url": "https://avatars.githubusercontent.com/u/47795042?v=4", + "email": null, + "events_url": "https://api.github.com/users/xxxs/events{/privacy}", + "followers_url": "https://api.github.com/users/xxxs/followers", + "following_url": "https://api.github.com/users/xxxs/following{/other_user}", + "gists_url": "https://api.github.com/users/xxxs/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/xxxs", + "id": 47795042, + "login": "xxxs", + "name": "xxxs", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjQ3Nzk1MDQy", + "organizations_url": "https://api.github.com/users/xxxs/orgs", + "received_events_url": "https://api.github.com/users/xxxs/received_events", + "repos_url": "https://api.github.com/users/xxxs/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/xxxs/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/xxxs/subscriptions", + "type": "Organization", + "url": "https://api.github.com/users/xxxs" + }, + "private": true, + "pulls_url": "https://api.github.com/repos/xxxs/xxx-rails/pulls{/number}", + "pushed_at": 1727373921, + "releases_url": "https://api.github.com/repos/xxxs/xxx-rails/releases{/id}", + "size": 4290, + "ssh_url": "git@github.com:xxxs/xxx-rails.git", + "stargazers": 0, + "stargazers_count": 0, + "stargazers_url": "https://api.github.com/repos/xxxs/xxx-rails/stargazers", + "statuses_url": "https://api.github.com/repos/xxxs/xxx-rails/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/xxxs/xxx-rails/subscribers", + "subscription_url": "https://api.github.com/repos/xxxs/xxx-rails/subscription", + "svn_url": "https://github.com/xxxs/xxx-rails", + "tags_url": "https://api.github.com/repos/xxxs/xxx-rails/tags", + "teams_url": "https://api.github.com/repos/xxxs/xxx-rails/teams", + "topics": [], + "trees_url": "https://api.github.com/repos/xxxs/xxx-rails/git/trees{/sha}", + "updated_at": "2024-09-26T15:01:21Z", + "url": "https://github.com/xxxs/xxx-rails", + "visibility": "private", + "watchers": 0, + "watchers_count": 0, + "web_commit_signoff_required": false + }, + "sender": { + "avatar_url": "https://avatars.githubusercontent.com/u/9254546?v=4", + "events_url": "https://api.github.com/users/jandresrodriguez/events{/privacy}", + "followers_url": "https://api.github.com/users/jandresrodriguez/followers", + "following_url": "https://api.github.com/users/jandresrodriguez/following{/other_user}", + "gists_url": "https://api.github.com/users/jandresrodriguez/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/jandresrodriguez", + "login": "xxxxxxxxxxx", + "node_id": "MDQ6VXNlcjkyNTQ1NDY=", + "organizations_url": "https://api.github.com/users/jandresrodriguez/orgs", + "received_events_url": "https://api.github.com/users/jandresrodriguez/received_events", + "repos_url": "https://api.github.com/users/jandresrodriguez/repos", + "site_admin": false, + "starred_url": "https://api.github.com/users/jandresrodriguez/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/jandresrodriguez/subscriptions", + "type": "User", + "url": "https://api.github.com/users/jandresrodriguez" + } +} diff --git a/test/lib/validationTest.sh b/test/lib/validationTest.sh index f36bbd99..268dc6b1 100755 --- a/test/lib/validationTest.sh +++ b/test/lib/validationTest.sh @@ -10,25 +10,24 @@ source "test/testUtils.sh" # shellcheck source=/dev/null source "lib/functions/validation.sh" -function IsUnsignedIntegerSuccessTest() { +IsUnsignedIntegerTest() { local FUNCTION_NAME FUNCTION_NAME="${FUNCNAME[0]}" info "${FUNCTION_NAME} start" - if ! IsUnsignedInteger 1; then - fatal "${FUNCTION_NAME} failed" + local INPUT=1 + if ! IsUnsignedInteger ${INPUT}; then + fatal "${FUNCTION_NAME} should have succeeded when checking ${INPUT}" fi - notice "${FUNCTION_NAME} PASS" -} + INPUT="test" + if IsUnsignedInteger "${INPUT}"; then + fatal "${FUNCTION_NAME} should have failed when checking ${INPUT}" + fi -function IsUnsignedIntegerFailureTest() { - local FUNCTION_NAME - FUNCTION_NAME="${FUNCNAME[0]}" - info "${FUNCTION_NAME} start" - - if IsUnsignedInteger "test"; then - fatal "${FUNCTION_NAME} failed" + INPUT=-1 + if IsUnsignedInteger ${INPUT}; then + fatal "${FUNCTION_NAME} should have failed when checking ${INPUT}" fi notice "${FUNCTION_NAME} PASS" @@ -561,8 +560,7 @@ ValidateCommitlintConfigurationTest() { notice "${FUNCTION_NAME} PASS" } -IsUnsignedIntegerSuccessTest -IsUnsignedIntegerFailureTest +IsUnsignedIntegerTest ValidateDeprecatedVariablesTest ValidateGitHubUrlsTest ValidateSuperLinterSummaryOutputPathTest diff --git a/test/run-super-linter-tests.sh b/test/run-super-linter-tests.sh index 033b19c7..3125b81a 100755 --- a/test/run-super-linter-tests.sh +++ b/test/run-super-linter-tests.sh @@ -116,6 +116,35 @@ initialize_git_repository_and_test_args() { COMMAND_TO_RUN+=(-e VALIDATE_ALL_CODEBASE=false) } +initialize_git_repository_and_test_args_merge_commit() { + local GIT_REPOSITORY_PATH="${1}" + local GITHUB_EVENT_FILE_PATH="${2}" + + initialize_git_repository_and_test_args "${GIT_REPOSITORY_PATH}" "${GITHUB_EVENT_FILE_PATH}" + + local NEW_BRANCH_NAME="branch-1" + git -C "${GIT_REPOSITORY_PATH}" switch --create "${NEW_BRANCH_NAME}" + cp -v "test/data/github-event/github-event-push-merge-commit.json" "${GIT_REPOSITORY_PATH}/new-file-1.json" + git -C "${GIT_REPOSITORY_PATH}" add . + git -C "${GIT_REPOSITORY_PATH}" commit -m "feat: add new file 1" + cp -v "test/data/github-event/github-event-push-merge-commit.json" "${GIT_REPOSITORY_PATH}/new-file-2.json" + git -C "${GIT_REPOSITORY_PATH}" add . + git -C "${GIT_REPOSITORY_PATH}" commit -m "feat: add new file 2" + cp -v "test/data/github-event/github-event-push-merge-commit.json" "${GIT_REPOSITORY_PATH}/new-file-3.json" + git -C "${GIT_REPOSITORY_PATH}" add . + git -C "${GIT_REPOSITORY_PATH}" commit -m "feat: add new file 3" + git -C "${GIT_REPOSITORY_PATH}" switch "${DEFAULT_BRANCH}" + # Force the creation of a merge commit + git -C "${GIT_REPOSITORY_PATH}" merge \ + -m "Merge commit" \ + --no-ff \ + "${NEW_BRANCH_NAME}" + git -C "${GIT_REPOSITORY_PATH}" branch -d "${NEW_BRANCH_NAME}" + + initialize_github_sha "${GIT_REPOSITORY_PATH}" + COMMAND_TO_RUN+=(-e VALIDATE_JSON="true") +} + initialize_github_sha() { local GIT_REPOSITORY_PATH="${1}" local TEST_GITHUB_SHA @@ -140,31 +169,17 @@ run_test_case_merge_commit_push() { local GIT_REPOSITORY_PATH GIT_REPOSITORY_PATH="$(mktemp -d)" - initialize_git_repository_and_test_args "${GIT_REPOSITORY_PATH}" "test/data/github-event/github-event-push-merge-commit.json" + initialize_git_repository_and_test_args_merge_commit "${GIT_REPOSITORY_PATH}" "test/data/github-event/github-event-push-merge-commit.json" + git_log_graph "${GIT_REPOSITORY_PATH}" +} - local NEW_BRANCH_NAME="branch-1" - git -C "${GIT_REPOSITORY_PATH}" switch --create "${NEW_BRANCH_NAME}" - cp -v "test/data/github-event/github-event-push-merge-commit.json" "${GIT_REPOSITORY_PATH}/new-file-1.json" - git -C "${GIT_REPOSITORY_PATH}" add . - git -C "${GIT_REPOSITORY_PATH}" commit -m "feat: add new file 1" - cp -v "test/data/github-event/github-event-push-merge-commit.json" "${GIT_REPOSITORY_PATH}/new-file-2.json" - git -C "${GIT_REPOSITORY_PATH}" add . - git -C "${GIT_REPOSITORY_PATH}" commit -m "feat: add new file 2" - cp -v "test/data/github-event/github-event-push-merge-commit.json" "${GIT_REPOSITORY_PATH}/new-file-3.json" - git -C "${GIT_REPOSITORY_PATH}" add . - git -C "${GIT_REPOSITORY_PATH}" commit -m "feat: add new file 3" - git -C "${GIT_REPOSITORY_PATH}" switch "${DEFAULT_BRANCH}" - # Force the creation of a merge commit - git -C "${GIT_REPOSITORY_PATH}" merge \ - -m "Merge commit" \ - --no-ff \ - "${NEW_BRANCH_NAME}" - git -C "${GIT_REPOSITORY_PATH}" branch -d "${NEW_BRANCH_NAME}" +run_test_case_merge_commit_push_tag() { + local GIT_REPOSITORY_PATH + GIT_REPOSITORY_PATH="$(mktemp -d)" - git -C "${GIT_REPOSITORY_PATH}" log --all --graph --abbrev-commit --decorate --format=oneline - - initialize_github_sha "${GIT_REPOSITORY_PATH}" - COMMAND_TO_RUN+=(-e VALIDATE_JSON="true") + initialize_git_repository_and_test_args_merge_commit "${GIT_REPOSITORY_PATH}" "test/data/github-event/github-event-push-tag-merge-commit.json" + git -C "${GIT_REPOSITORY_PATH}" tag "v1.0.1-beta" + git_log_graph "${GIT_REPOSITORY_PATH}" } run_test_case_use_find_and_ignore_gitignored_files() { diff --git a/test/testUtils.sh b/test/testUtils.sh index 46953714..c01bc370 100755 --- a/test/testUtils.sh +++ b/test/testUtils.sh @@ -240,3 +240,14 @@ initialize_git_repository() { git -C "${GIT_REPOSITORY_PATH}" config user.name "Super-linter Test" git -C "${GIT_REPOSITORY_PATH}" config user.email "super-linter-test@example.com" } + +git_log_graph() { + local GIT_REPOSITORY_PATH="${1}" + + git -C "${GIT_REPOSITORY_PATH}" log \ + --abbrev-commit \ + --all \ + --decorate \ + --format=oneline \ + --graph +}