Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I ended up having to do this in a several stage process.</p> <p>First, I got a list of all the files paths that were ever found in the repository:</p> <pre><code>git log --pretty=format: --name-only --diff-filter=A | sort -u </code></pre> <p>Using that, I was able to determine where the files I wanted to keep had resided at one point or another. In my case, they had resided in four separate directories in the repository throughout their lifetimes. I used this information to manually create a regex, such as <code>(?:^foo|^bar/baz|^qux/(?:moo|woof))</code>. This matches the directories I wanted to keep.</p> <p>I then created a perl script to preserve those pathnames AND any parent pathnames that contained them. </p> <pre><code>use Path::Class; if(scalar(@ARGV) &lt; 1) { die "no regex"; } my $regex = qr/$ARGV[0]/; my @want; my @remove; my $last = undef; my $lastrm = undef; while(&lt;STDIN&gt;) { chomp; my $d = $_; if( $d =~ $regex ) { if( ! defined($last) || ! dir($last)-&gt;subsumes(dir($d)) ) { $last = $d; push @want, $d; } } else { if( ! defined($last) || ! dir($last)-&gt;subsumes(dir($d)) ) { push @remove, $d; } } } foreach $rm (@remove) { my $no_rm = 0; if( defined($lastrm) &amp;&amp; dir($lastrm)-&gt;subsumes($rm) ) { $no_rm++; } else { foreach $keep (@want) { if( dir($rm)-&gt;subsumes(dir($keep)) ) { $no_rm++; } } } if( $no_rm == 0 ) { print "$rm\n"; $lastrm = $rm; } } </code></pre> <p>Finally, I used git filter-branch to use my new filter with my regex to keep the paths that I wanted.</p> <pre><code>git filter-branch --prune-empty --index filter ' git ls-tree -d -r -t --name-only --full-tree $GIT_COMMIT | sort | /path/to/filter.pl "(?:regex|of|paths)" | xargs -n 50 git rm -rf --cached --ignore-unmatch' -- --all </code></pre> <p>The sort is necessary as it ensures the perl script gets the directories in their proper hierarchy.</p> <p>I hope this helps someone, as it took me many, many hours to come up with this. :)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload