From: "Robert P. J. Day" <rpjday@crashcourse.ca>
To: Jeff King <peff@peff.net>
Cc: Git Mailing list <git@vger.kernel.org>
Subject: Re: how to remove from history just *one* version of a file/dir?
Date: Fri, 15 Sep 2017 07:06:43 -0400 (EDT) [thread overview]
Message-ID: <alpine.LFD.2.21.1709150701010.4944@localhost.localdomain> (raw)
In-Reply-To: <20170914122338.4vlgx2rjr4mk62rh@sigill.intra.peff.net>
On Thu, 14 Sep 2017, Jeff King wrote:
> On Thu, Sep 14, 2017 at 07:32:11AM -0400, Robert P. J. Day wrote:
>
> > [is this the right place to ask questions about git usage? or is
> > there a different forum where one can submit possibly
> > embarrassingly silly questions?]
>
> No, this is the right place for embarrassing questions. :)
>
> > say, early on, one commits a sizable directory of content, call
> > it /mydir. that directory sits there for a while until it becomes
> > obvious it's out of date and worthless and should never have been
> > committed. the obvious solution would seem to be:
> >
> > $ git filter-branch --tree-filter 'rm -rf /mydir' HEAD
> >
> > correct?
>
> That would work, though note that using an --index-filter would be
> more efficient (since it avoids checking out each tree as it walks
> the history).
i'm just digging into --index-filter as we speak, i realize it's
noticeably faster.
> > however, say one version of that directory was committed early
> > on, then later tossed for being useless with "git rm", and
> > subsequently replaced by newer content under exactly the same
> > name. now i'd like to go back and delete the history related to
> > that early version of /mydir, but not the second.
>
> Makes sense as a goal.
>
> > obviously, i can't use the above command as it would delete both
> > versions. so it appears the solution would be a trivial
> > application of the "--commit-filter" option:
> >
> > git filter-branch --commit-filter '
> > if [ "$GIT_COMMIT" = "<commit-id>" ] ; then
> > skip_commit "$@";
> > else
> > git commit-tree "$@";
> > fi' HEAD
> >
> > where <commit-id> is the commit that introduced the first verrsion of
> > /mydir. do i have that right? is there a simpler way to do this?
>
> No, this won't work. Filter-branch is not walking the history and
> applying the changes to each commit, like rebase does. It's
> literally operating on each commit object, and recall that each
> commit object points to a tree that is a snapshot of the repository
> contents.
>
> So if you skip a commit, that commit itself goes away. But the
> commit after it (which didn't touch the unwanted contents) will
> still mention those contents in its tree.
ah, of course, duh.
> I think you want to stick with a --tree-filter (or an
> --index-filter), but just selectively decide when to do the
> deletion. For example, if you can tell the difference between the
> two states based on the presence of some file, then perhaps:
>
> git filter-branch --prune-empty --index-filter '
> if git rev-parse --verify :dir/sentinel >/dev/null 2>&1
> then
> git rm --cached -rf dir
> fi
> ' HEAD
>
> The "--prune-empty" is optional, but will drop commits that become
> empty because they _only_ touched that directory.
>
> We use ":dir/sentinel" to see if the entry is in the index, because
> the index filter won't have the tree checked out. Likewise, we need
> to use "rm --cached" to just touch the index.
got it. one last query -- i note that there is no "else" clause in
that code for "--index-filter". am i assuming correctly that if i was
using "--tree-filter" instead, i really would need if/then/else along
the lines of:
if blah ; then
skip_commit "$@"
else
git commit-tree "$@"
fi
thank you kindly.
rday
--
========================================================================
Robert P. J. Day Ottawa, Ontario, CANADA
http://crashcourse.ca
Twitter: http://twitter.com/rpjday
LinkedIn: http://ca.linkedin.com/in/rpjday
========================================================================
next prev parent reply other threads:[~2017-09-15 11:06 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-14 11:32 how to remove from history just *one* version of a file/dir? Robert P. J. Day
2017-09-14 12:23 ` Jeff King
2017-09-15 11:06 ` Robert P. J. Day [this message]
2017-09-15 11:35 ` Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.LFD.2.21.1709150701010.4944@localhost.localdomain \
--to=rpjday@crashcourse.ca \
--cc=git@vger.kernel.org \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).