{"record":{"id":"9935a76217b64085","repo":"Tencent/tinker","slug":"can-t-get-git-rev-you-should-add-git-to-system-pa","errorCode":null,"errorMessage":"can't get git rev, you should add git to system path or just input test value, such as 'testTinkerId'","messagePattern":"can't get git rev, you should add git to system path or just input test value, such as 'testTinkerId'","errorType":"exception","errorClass":"GradleException","httpStatus":null,"severity":"error","filePath":"tinker-sample-android/app/build.gradle","lineNumber":41,"sourceCode":"        testCompile 'junit:junit:4.12'\n        compile \"androidx.appcompat:appcompat:1.1.0\"\n        compile(\"com.tencent.tinker:tinker-android-lib:${TINKER_VERSION}\") { changing = true }\n        provided(\"com.tencent.tinker:tinker-android-anno:${TINKER_VERSION}\") { changing = true }\n        provided(\"com.tencent.tinker:tinker-android-anno-support:${TINKER_VERSION}\") { changing = true }\n\n        compile \"androidx.multidex:multidex:2.0.1\"\n\n        //use to test multiDex\n//    compile group: 'com.google.guava', name: 'guava', version: '19.0'\n//    compile \"org.scala-lang:scala-library:2.11.7\"\n    }\n}\n\ndef gitSha() {\n    try {\n        String gitRev = 'git rev-parse --short HEAD'.execute(null, project.rootDir).text.trim()\n        if (gitRev == null) {\n            throw new GradleException(\"can't get git rev, you should add git to system path or just input test value, such as 'testTinkerId'\")\n        }\n        return gitRev\n    } catch (Exception e) {\n        throw new GradleException(\"can't get git rev, you should add git to system path or just input test value, such as 'testTinkerId'\")\n    }\n}\n\ndef javaVersion = JavaVersion.VERSION_1_7\n\nandroid {\n    compileSdkVersion 28\n    buildToolsVersion '28.0.3'\n\n    compileOptions {\n        sourceCompatibility javaVersion\n        targetCompatibility javaVersion\n    }\n    //recommend","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/tinker-sample-android/app/build.gradle#L23-L59","documentation":"Thrown by the gitSha() helper in tinker-sample-android/app/build.gradle (line 41, the null-check branch). It executes 'git rev-parse --short HEAD' in project.rootDir via Groovy's String.execute(); if the returned text is null (process produced no output), it raises this GradleException telling you git is unavailable or unusable. The result feeds tinkerId, which Tinker uses to match a patch to the base APK's build.","triggerScenarios":"Building tinker-sample-android when: (a) git is not installed or not on the system PATH, so execute() cannot resolve the executable or the command errors; (b) project.rootDir is not a git repository (source downloaded as a ZIP from GitHub) so 'git rev-parse HEAD' fails; (c) the repository has no commits yet (fresh init, HEAD unborn).","commonSituations":"Downloading the Tinker repo as a zip instead of git clone on a CI agent or fresh machine without git; minimal Docker/CI images that omit git; a contributor who cloned only the sample folder; the very first build after git init before any commit.","solutions":["Install git and ensure it is on PATH (verify with 'git --version' in the same shell/agent that runs Gradle).","If the project came from a zip, run 'git init && git add -A && git commit -m init' in the repo root so 'git rev-parse --short HEAD' succeeds.","For a quick local test build, replace the gitSha() call with a fixed value, e.g. tinkerId = \"testTinkerId\", exactly as the message suggests — but the same id must be used for both base package and patch builds.","On CI, check out with full git history (shallow clones still work since HEAD exists, but zip archives do not)."],"exampleFix":"// before\ntinkerId = \"${gitSha()}\"\n\n// after (local test only; keep identical for base and patch builds)\ntinkerId = \"testTinkerId\"","handlingStrategy":"fallback","validationCode":"// configuration-time guard before calling gitSha()\ndef hasGit = 'git --version'.execute().waitFor() == 0\ndef isRepo = new File(project.rootDir, '.git').exists()\nassert hasGit && isRepo : 'git unavailable or not a repo — use a fixed tinkerId'","typeGuard":null,"tryCatchPattern":"def gitSha() {\n    try {\n        def r = 'git rev-parse --short HEAD'.execute(null, project.rootDir).text.trim()\n        return r ?: 'testTinkerId'   // fallback instead of throwing\n    } catch (Exception e) {\n        return 'testTinkerId'\n    }\n}","preventionTips":["Ensure git is installed and on PATH in every build environment (CI images, Docker).","git clone the project rather than downloading a zip, so rootDir is a real work tree.","Commit before building; an unborn HEAD has no rev to parse.","Use the same tinkerId for the base APK and the patch, or Tinker will refuse to load it."],"tags":["gradle","git","environment","sample-app","tinker-id"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}