Show git last commit hash and current branch/tag in flutter app
Asked Answered
C

5

8

How can I access the last git commit hash, current branch and last tag from the source directory, when building a flutter app? I want to display this in a "About version" dialog.

There is https://pub.dev/packages/package_info but it has no information about git.

Are there any other packages that may provide this information?

Colloidal answered 14/9, 2020 at 17:6 Comment(3)
so if i understand this correctly, are you trying to display the app version?Patrilineal
@Patrilineal No, I want to show something like "This version was built from git commit a8b07e02 (branch: master), 8 commits behind tag 'release-0.8-rc1'".Colloidal
not exactly sure how to approach this but i suggest writing an webhook / API to get the commit hash?Patrilineal
D
16

It may not be the best solution, but here's how I did it.

1. Add the necessary files to assets

flutter:
  assets:
    - .git/HEAD         # This file points out the current branch of the project.
    - .git/ORIG_HEAD    # This file points to the commit id at origin (last commit id of the remote repository).
    - .git/refs/heads/  # This directory includes files for each branch that points to the last commit id (local repo).

Default Gradle configuration excludes .git folder from builds, therefore this rule must be removed. To do this, add the following to your settings.graddle:

import org.apache.tools.ant.DirectoryScanner

DirectoryScanner.removeDefaultExclude('**/.git')
DirectoryScanner.removeDefaultExclude('**/.git/**')

2. Consume it from your .dart code

Future<String> getGitInfo() async {
  final _head = await rootBundle.loadString('.git/HEAD');
  final commitId = await rootBundle.loadString('.git/ORIG_HEAD');

  final branch = _head.split('/').last;

  print("Branch: $branch");
  print("Commit ID: $commitId");

  return "Branch: $branch,  Commit ID: $commitId";
}

3. Display it in your flutter app if needed

FutureBuilder<String>(
  future: getGitInfo(),
  builder: (context, snapshot) {
    return Text(snapshot.data ?? "");
  },
)

Expected output:

enter image description here

Note that hot reload works also for assets, so it should show changes.

Deepfry answered 13/2, 2021 at 2:23 Comment(3)
This is working for iOS but not Android. What could be the issue?Novak
Not sure, I remember testing this on android and posting the output screenshot. It should work on any platform in the same way, as it's only depended on the asset files, and asset files are not platform specific.Deepfry
@MohdShahid See this answer for solution.Outgeneral
J
4

My method that doesn't need other packages, env vars, or adding and reading assets. And supports flutter project being in any child directory. Just directly write a .dart file with the post-commit git hook:

# post-commit
FILE="app/lib/such/a/deep/tree/settings/git.dart"
echo "// AUTO GENERATED FILE BY GIT HOOK post-commit" > $FILE
echo "const String GIT_COMMIT = '$(git rev-parse HEAD)';" >> $FILE
echo "const String GIT_BRANCH = '$(git rev-parse --abbrev-ref HEAD)';" >> $FILE

Then:

import 'package:fluffy-squirrel/settings/git.dart';

print(GIT_BRANCH);

This is how I ensure my Sentry instance always has the right release.

Jolson answered 19/12, 2021 at 7:17 Comment(0)
L
2

The Answer from Rithvik Nishad worked for me but with small modifications. I have to make a new answer because i cannot comment due to reputation.

The changes are needed because

  • our App is built in the CI (which does not have the ORIG_HEAD-file in the .git/ folder)
  • we wanted the currently checked out commit hash to be displayed and not the most recent remote one (which is what ORIG_HEAD actually resembles)

So here are the changes:

  1. Do not import .git/ORIG_HEAD in pubspec.yaml, the rest can stay
  2. Use this modified function to get the commit of the currently checked out head:
Future<String> getGitInfo() async {

  // Get the current head
  final head = await rootBundle.loadString('.git/HEAD');

  // Extract the branch name if needed

  if (head.startsWith('ref: ')) {
    // checked out branch name
    final branchName = head.split('ref: refs/heads/').last.trim();
    return await rootBundle.loadString('.git/refs/heads/${branchName}');
  } else {
    // HEAD points to a specific commit
    return head;
  }
}

  1. Then access it from wherever you need it.
Loraleeloralie answered 4/11, 2023 at 14:50 Comment(0)
D
0

Rithvik Nishad's answer does not work for me, because my flutter project is a child project and cannot access .git/ directory. For example:

root/
|__.git/
|__client/
|_____flutter project/  <== can not access to .git/ from here

So my solution is using a small script to get git info and save into the .env file

#!/bin/bash
set -e

branch=`git rev-parse --abbrev-ref HEAD`
escaped_branch=$(printf '%s\n' "$branch" | sed -e 's/[\/&]/\\&/g')
commit=`git rev-parse --short HEAD`

# branch
if grep -q 'GIT_BRANCH=' .env; then
    sed -i '' "s/^GIT_BRANCH.*/GIT_BRANCH=$escaped_branch/g" .env
else
    echo "GIT_BRANCH=$branch" >> .env
fi

# commit hash
if grep -q 'GIT_COMMIT=' .env; then
    sed -i '' "s/^GIT_COMMIT.*/GIT_COMMIT=$commit/g" .env
else
    echo "GIT_COMMIT=$commit" >> .env
fi

then read the .env file to get git branch/hash, ... (i'm using dotenv to read the file)

final gitBranch = dotenv.env['GIT_BRANCH'] ?? ''; // => features/change-logo
final gitCommit = dotenv.env['GIT_COMMIT'] ?? ''; // => 45a97d3

Here is my result:

Git info

Dozy answered 5/9, 2021 at 2:27 Comment(0)
H
0

If we adjust Anton's Answer, by also adding pubspec.yaml to the asset bundle, we can generate an app version ID like 1.2.3+4-a1b2c3d4:

Future<String> getVersion() async {
  String gitVersion;
  final pubspecVersion =
      loadYaml(await rootBundle.loadString("pubspec.yaml"))["version"];
  var head = await rootBundle.loadString('.git/HEAD');
  if (head.startsWith('ref: ')) {
    final branchName = head.split('ref: refs/heads/').last.trim();
    gitVersion = await rootBundle.loadString('.git/refs/heads/$branchName');
  } else {
    gitVersion = head;
  }
  return "$pubspecVersion-${gitVersion.substring(0, 8)}";
}
Harlow answered 6/9 at 20:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.