From 174e546a1e9572e760834d87a4dc68b6547838d1 Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Sun, 22 Mar 2020 09:27:09 -0700 Subject: fix annex-drop-files-deleted-by-commit --- bin/annex-drop-files-deleted-by-commit | 59 +++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 23 deletions(-) (limited to 'bin/annex-drop-files-deleted-by-commit') diff --git a/bin/annex-drop-files-deleted-by-commit b/bin/annex-drop-files-deleted-by-commit index 367f4872..b8079091 100755 --- a/bin/annex-drop-files-deleted-by-commit +++ b/bin/annex-drop-files-deleted-by-commit @@ -32,46 +32,59 @@ use Git::Wrapper; use Try::Tiny; use Local::ScriptStatus; use Local::Interactive qw(prompt_yn); +use File::chdir; +use Cwd; -# git wrapper setup -my $git = Git::Wrapper->new("."); +my $git = Git::Wrapper->new(getcwd); +#<<< try { $git->rev_parse({ git_dir => 1 }); -} -catch { +} catch { die "pwd doesn't look like a git repository ..\n"; }; +#>>> -# process command line -# TODO support --from so can drop from special remotes too -my @drop_args = (); -if ($ARGV[0] eq '--force') { - push @drop_args, "--force"; - shift @ARGV; -} - -# go for it -my $temp = tempdir(CLEANUP => 1); +my $temp = tempdir CLEANUP => 1; chmod 0700, $temp; $git->worktree("add", { force => 1, no_checkout => 1, detach => 1 }, $temp); my $worktree = Git::Wrapper->new($temp); for (@ARGV) { + local $CWD = $temp; + my ($commit) = $git->rev_parse($_); - my @deleted_files - = $git->diff({ name_only => 1, diff_filter => 'D' }, - "$commit~1..$commit"); + my @deleted_files = $git->RUN( + qw(-c core.quotePath=false diff), + { name_only => 1, diff_filter => 'D' }, + "$commit~1..$commit" + ); $worktree->checkout("$commit~1"); - say_spaced_bullet("Will drop" - . (grep(/\A--force\z/, @drop_args) ? " with --force:" : ":")); + # We ought to be able to just `ga drop` the files here, but the + # symlinks might be broken if the repo is bare and has + # .git/annex/objects organised differently. And 'lookupkey' + # doesn't work in bare repos either. So, extract the key from the + # symlink + my @deleted_keys; + for (@deleted_files) { + readlink =~ /SHA256E-s[0-9]+--[0-9a-f]+\.[a-zA-Z0-9]+$/; + $& or die "couldn't determine key of $_"; + push @deleted_keys, $&; + } + + # using dropkey is like passing --force to `git annex drop` + say_spaced_bullet "Will drop with --force:"; + # for (my $i = 0 ; $i < @deleted_files ; $i++) { + # say "$deleted_files[$i] $deleted_keys[$i]"; + # } say for @deleted_files; say ''; - # bypass Git::Wrapper so output goes to terminal - system('git', '-C', $temp, 'annex', 'drop', @drop_args, @deleted_files) - if prompt_yn("Go ahead with this?"); + + if (prompt_yn "Go ahead with this?") { + say for $git->annex(qw|dropkey --force|, @deleted_keys); + } } # we can't use `git worktree remove` because the way git-annex # worktree support works breaks that command: git-annex replaces the # .git worktree file with a symlink -rmtree($temp); +rmtree $temp; $git->worktree("prune"); -- cgit v1.2.3