Alex Verbitski
Alex Verbitski

Reputation: 609

Can't add an asset from a .git folder

I'd like to retrieve and use commit hash that's stored in a .git folder (inside ORIG_HEAD file). To do this I registered my asset in pubspec.yaml file:

flutter:
  uses-material-design: true

  assets:
    - assets/strings/
    - assets/images/
    - .git/ORIG_HEAD

and used

await rootBundle.loadString('.git/ORIG_HEAD');

to get the value from that file.

The iOS app works fine, but the android one throws an "Unable to load asset" error

I tried to duplicate the .git folder and remove a dot from the beginning. And it seems to be working (git file has been added as an asset - flutter_assets in android apk). But this solution isn't a suitable one, because I'd like to have the relevant commit hash in place without any additional manipulations. Are there any workaround of such issue? Or it can be solved by adding pre-build scripts only?

Upvotes: 2

Views: 1420

Answers (4)

Alex Verbitski
Alex Verbitski

Reputation: 609

Probably somebody may be interested in additional script that stores latest commit hash (first 7 chars)

success="\033[32mThe latest commit hash has been successfully stored in
enter code hereassets:"
error="\033[31mError during saving latest commit hash in assets, the app might not work properly"
outputFile=assets/build-info/commit-hash

(
  head=$(<.git/HEAD) &&
  ref=$(echo $head | cut -d' ' -f2) &&
  hash=$(<.git/$ref) &&
  echo ${hash:0:7} > $outputFile &&
  echo -e "$success $(<$outputFile)"
) || echo -e $error

Save this code under the .sh file and execute it before running "run" or "build". The file with commit hash will be stored under "outputFile" path

Upvotes: 0

Rexios
Rexios

Reputation: 552

Gradle has default exclusions that include the .git directory. In order to fix this you must update your settings.gradle file:

import org.apache.tools.ant.DirectoryScanner

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

I also updated the documentation for my package git_info to include this.

Upvotes: 5

Peter Pointer
Peter Pointer

Reputation: 4170

The .git directory should not be accessed from builds. The directory is not meant to be part of the release, as it is the repository itself.

You can use a pre-build script as you mentioned.
There is also a package that can help you with information about your git repository:
git_info

From the git_info example page:

import 'package:flutter/material.dart';
import 'package:git_info/git_info.dart';

void main() {
  runApp(MyApp());
}

// This will not work unless you create a git repo in the example folder
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('git_info_example'),
        ),
        body: FutureBuilder<GitInformation>(
          future: GitInfo.get(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text('Branch: ${snapshot.data!.branch}'),
                    Text('Hash: ${snapshot.data!.hash}'),
                  ],
                ),
              );
            } else {
              return SizedBox.shrink();
            }
          },
        ),
      ),
    );
  }
}

Upvotes: 0

torek
torek

Reputation: 489173

Files inside a .git directory cannot be stored in a Git repository. The reason is that the files inside a .git directory are a Git repository, or part of one, and no part of any Git repository can be stored inside a Git repository.1

The solution to your actual problem is simple: store the hash somewhere else. You won't be able to have Git automatically update it, the way .git/ORIG_HEAD is automatically updated by Git commands that "change HEAD in a violent way" as it were, but you can choose when to update it manually yourself. This is going to be a better idea anyway, because by choosing when you want the hash ID updated, you stop having it updated at any times you consider wrong ones. It's possible that your idea of when it should be updated will exactly match Git's idea, now and forever, but that seems unlikely.


1Git enforces this by name, so if you rename a .git directory to some other name, you can start storing these files. However, Git won't then use the .git directory as a repository—this is what made it safe for Git to store these files—so you'll need to create a new .git directory, which will be the actual repository, and now you're storing files that aren't part of a repository. It's turtles all the way down.

Upvotes: 1

Related Questions