You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.7 KiB
91 lines
2.7 KiB
#!/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} <remote>:<path>
|
|
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' ];
|
|
}
|
|
|