parent
2f62e3a718
commit
72a5277b1b
@ -0,0 +1 @@ |
||||
../../../licenses/GPL-3.0 |
@ -0,0 +1,42 @@ |
||||
# git-hyperpull |
||||
|
||||
Pull uncommited changes from a remote copy of this repository into your index. |
||||
|
||||
## How to use |
||||
|
||||
To run git-hyperpull you need to be in the root of your repository. |
||||
Under the hood, git-hyperpull simply runs `ssh ...` commands, so you |
||||
can rely on alias entries in your ssh config file. |
||||
|
||||
```console |
||||
$ git hyperpull myremote:~/myproject |
||||
Prepare environment... |
||||
Generating patch... |
||||
Pulling patch... |
||||
0001-generated-by-git-hyperpull.patch 100% 40KB 450.9KB/s 00:00 |
||||
Applying patch... |
||||
Deleting patch... |
||||
Cleaning up remote... |
||||
|
||||
$ git status |
||||
On branch main |
||||
Your branch is up to date with 'origin/main'. |
||||
|
||||
Changes to be committed: |
||||
(use "git restore --staged <file>..." to unstage) |
||||
new file: development/tools/git-hyperpull/.projectile |
||||
new file: development/tools/git-hyperpull/git-hyperpull.raku |
||||
new file: development/tools/git-hyperpull/shell.nix |
||||
``` |
||||
|
||||
## How to install |
||||
|
||||
TBD |
||||
|
||||
|
||||
## License |
||||
|
||||
`git-hyperpull` is free software, licensed under the GNU General |
||||
Public License 3.0 (or later). See the LICENSE file for a full copy |
||||
of the license. |
||||
|
@ -0,0 +1,91 @@ |
||||
#!/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' ]; |
||||
} |
@ -0,0 +1,6 @@ |
||||
with (import <nixpkgs> {}); |
||||
(import <nom/raku.nix>).overrideAttrs ({ ... }: |
||||
{ |
||||
name = "git-hyperpull"; |
||||
LD_LIBRARY_PATH = lib.makeLibraryPath [ pkgs.libssh ]; |
||||
}) |
Loading…
Reference in new issue