The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

gitwrap - Git wrapper script

VERSION

This document describes version 0.007 of gitwrap (from Perl distribution App-gitwrap), released on 2020-10-10.

SYNOPSIS

Use like you would git:

 % gitwrap commit -m ...
 ...

To use the name git, in your Unix shell:

 alias git=gitwrap

then this will call gitwrap instead.

 % git commit -m ...
 ...

DESCRIPTION

gitwrap is a script that runs the git binary. But before it does that, it can do some things first. And after that, it can also do some other things.

It will first search for configuration file gitwrap.conf in one of these locations: ~/.config, ~, or /etc. It then will execute various commands as described in the configuration, e.g. "before_commit_cmd". See "CONFIGURATION".

It will then run the git binary as specified in the configuration git_path or just use git.

Then it will run various commands as described in the configuration, e.g. "after_commit_cmd".

Lastly it will exit with the exit code of git command executed earlier.

Some examples of how I use this script:

  • Fix user and email dynamically before commit

    Suppose that instead of putting the user/email manually on each .git/config, you want to set/fix user and email dynamically using a set of rules right before commit.

    Doing this in pre-commit hook is too late as git already decides the user/email, so if you use pre-commit hook for this the best you can do is fix user/email then exit non-zero so the commit is aborted. Then you commit again.

    With this wrapper, this extra step is unnecessary. You can set before_commit_cmd in gitwrap.conf to the command necessary to munge the user/email in .git/config, for example:

     before_commit_cmd = perl -e'($user, $email) = ...; system "git", "config", "user.name", $user; system "git", "config", "user.email", $email'

    or, if you already have a pre-commit hook that does this, you can call the pre-commit hook instead.

     before_commit_cmd = ".git/hooks/pre-commit; exit 0"

    The difference is that even if the hook exits non-zero, gitwrap will continue executing git (due to exit 0 clause). But if the hook fails again during actual pre-commit phase in git, the commit will be aborted.

  • Touch last commit/status timestamp

    I update a record in a database whenever a repository is committed into or status-ed. The first can be done with a post-commit hook, but for the second there is no hook provided by git. I do this to speed up or prioritize repositories that are more recently modified/accessed in Git::Bunch: When there are hundreds/thousand+ git repositories in a gitbunch, and only a few of them need to be synchronized, using these timestamps can dramatically shorten the amount of time to determine which repositories need to be included, because we avoid having to 'git status' every single repository.

    To do this, in gitwrap.conf:

     before_commit_cmd = reposdb touch --commit-time
     before_status_cmd = reposdb touch --status-time

    Note: see also reposdb.

  • Setup hooks

    Sometimes I copy repositories to other computers simply by using cp or rsync. I also have scripts in .git/hooks/ directory inside the repository as symlinks to the actual scripts. When copying to other computers, the paths are not exactly alike so the symlinks get broken. We can use before_commit_cmd or other before*cmd to correct these symlinks first.

CONFIGURATION

git_path

before_commit_cmd

Command to run before git commit. Can be specified multiple times. Will abort execution if any of the commands fails.

before_status_cmd

Command to run before git status. Can be specified multiple times. Will abort execution if any of the commands fails.

before_pull_cmd

Command to run before git pull. Can be specified multiple times. Will abort execution if any of the commands fails.

before_push_cmd

Command to run before git push. Can be specified multiple times. Will abort execution if any of the commands fails.

after_commit_cmd

Command to run after git commit. Can be specified multiple times.

after_status_cmd

Command to run after git status. Can be specified multiple times.

after_pull_cmd

Command to run after git pull. Can be specified multiple times.

after_push_cmd

Command to run after git push. Can be specified multiple times.

FAQ

Truncated command?

I put this configuration:

 before_commit_cmd = perl -e'foo; bar; if ($baz eq "qux") { ... }'

but when I run git, I get:

 sh: 1: Syntax error: Unterminated quoted string
 system(perl -e'foo) failed: 512 (exited with code 2) at ...

Why is the command truncated?

Answer: the configuration (in IOD format) regards semicolon (;) and hash character (#) as a comment starter, including after the parameter value. To see quickly how a configuration file gets loaded, you can use dump-iod utility which will display the configuration as JSON data, e.g.:

 % dump-iod ~/gitwrap.conf
 {
   "GLOBAL" : {
     "before_commit_cmd" : "perl -e'foo"
   }
 }

To prevent this, you can use JSON string: you quote the whole parameter value in a double quote (and escape the double quotes inside with bacslashes). Example:

 before_commit_cmd = "perl -e'foo; bar; if ($baz eq \"qux\") { ... }'"

So now your configuration will become (in JSON):

 {
    "GLOBAL" : {
      "before_commit_cmd" : "perl -e'foo; bar; if ($baz eq \"qux\") { ... }'"
    }
 }

Continuing after error?

I want to execute a command in before_commit_cmd (or before_status_cmd, etc) but I want to continue even though the command exits with a non-zero status. How do I do that?

Answer:

 before_commit_cmd = "your-command; exit 0"

Remember to quote the parameter value with a double quote (see previous FAQ entry for more details).

HOMEPAGE

Please visit the project's homepage at https://metacpan.org/release/App-gitwrap.

SOURCE

Source repository is at https://github.com/perlancar/perl-App-gitwrap.

BUGS

Please report any bugs or feature requests on the bugtracker website https://rt.cpan.org/Public/Dist/Display.html?Name=App-gitwrap

When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature.

SEE ALSO

git

AUTHOR

perlancar <perlancar@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2020, 2017, 2016 by perlancar@cpan.org.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.