#!/usr/bin/env raku sub USAGE() { print Q:c:to/EOH/; Pull uncommited changes from a remote copy of this repository into your index. Usage: {$*PROGRAM-NAME} : EOH } ## Run a command on a remote and hide stderr from the user sub cmd_on_remote($remote, $path, @cmd) returns Int { my $p = run 'ssh', "$remote", "cd $path; $(@cmd)", :out, :err; $p.out.slurp: :close; # Consume stdout nom nom nom $p.err.slurp: :close; # Consume stderr nom nom nom $p.exitcode } ## Prepare the environment by cleaning up .git/hypergit sub prepare_env($remote, $path) { say 'Prepare environment...'; my $dirty = cmd_on_remote($remote, $path, [ 'stat', '.git/hyperpull' ]); if $dirty { say 'Cleaning up previous .git/hyperpull state directory...'; cmd_on_remote($remote, $path, [ 'rm', '-rf', '.git/hyperpull' ]); } } ## Generate a patch and store sub generate_patch($remote, $path) { say 'Generating patch...'; cmd_on_remote $remote, $path, [ 'git', 'add', '-A' ]; cmd_on_remote $remote, $path, [ 'git', 'commit', '-m', "'generated by git-hyperpull'" ]; cmd_on_remote $remote, $path, [ 'git', 'format-patch', 'HEAD~', '-o', '.git/hyperpull' ]; cmd_on_remote $remote, $path, [ 'git', 'reset', 'HEAD^' ]; } ## Pull the generated patch files sub pull_patch($remote, $path) { say 'Pulling patch...'; my $p = run 'scp', "$remote:$path/.git/hyperpull/0001-generated-by-git-hyperpull.patch", '.', :err; $p.err.slurp: :close; # Consume stderr nom nom nom } ## Check that we are in the root of the repository sub check_directory { my $p = run 'stat', '.git', :out, :err; $p.out.slurp: :close; $p.err.slurp: :close; if $p.exitcode { say 'You must run git-hyperpull from the repository root!'; exit 1; } } ## Main function hook that runs when the user provides enough parameters sub MAIN($remote_path) { check_directory(); # Split argument along the : - hopefully some shells can auto-complete this easier my ($host, $path) = split(":", $remote_path); # Make sure we have a clean .git/hyperpull directory to work with prepare_env $host, $path; # Generate the remote patch generate_patch $host, $path; # Pull and apply patch locally pull_patch $host, $path; # Apply local patch say 'Applying patch...'; run 'git', 'apply', '-3', '--index', '--intent-to-add', './0001-generated-by-git-hyperpull.patch'; # Delete local patch say 'Deleting patch...'; run 'rm', './0001-generated-by-git-hyperpull.patch'; # Clean up remote .git/hyperpull directory say 'Cleaning up remote...'; cmd_on_remote $host, $path, [ 'rm', '-rf', '.git/hyperpull' ]; }