git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: git smudge filter fails

From
Stephen Morton <stephen.c.morton@gmail.com>
Date
Mar 15, 2016, 16:17 UTC
Message-ID
<CAH8BJxHvg1cnzdsnVsHLYm2BAoqNxp8-mNyVxRy4CHqv0rgN6g@mail.gmail.com>
In-Reply-To
<xmqqtwkec7lk.fsf@gitster.mtv.corp.google.com>
On Thu, Mar 10, 2016 at 5:04 PM, Junio C Hamano <gitster@pobox.com> wrote:
Show 46 quoted lines
> Jeff King <peff@peff.net> writes:
>
>> On Thu, Mar 10, 2016 at 09:45:19AM -0500, Stephen Morton wrote:
>>
>>> I am a bit confused because this is basically the example used in
>>> ProGit [1] and it is fundamentally broken. In fact, if I understand
>>> correctly, this means that smudge filters cannot be relied upon to
>>> provide any 'keyword expansion' type tasks because they will all by
>>> nature have to query the file with 'git log'.
>>
>> Interesting. Perhaps I am missing something (I am far from an expert in
>> clean/smudge filters, which I do not generally use myself), but the
>> example in ProGit looks kind of bogus to me. I don't think it ever would
>> have worked reliably, under any version of git.
>>
>>> (Note that although in my example I used 'git checkout', with an only
>>> slightly more complicated example I can make it fail on 'git pull'
>>> which is perhaps a much more realistic use case. That was probably
>>> implied in your answer, I just wanted to mention it.)
>>
>> Yeah, I think the issue is basically the same for several commands which
>> update the worktree and the HEAD. Most of them are going to do the
>> worktree first.
>
> You can have a pair of branches A and B that have forked long time
> ago, and have a path F that has been changed identically since they
> forked, perhaps by cherry-picking the same change.  This happens all
> the time.
>
> If there were some mechanism that modifies the checked out version
> of F with information that depends on the history that leads to A
> (e.g. "which commit that is an ancestor of A last modified F?")
> when you check out branch A, it will become invalid when you do "git
> checkout B", because the path F will not change because they are the
> same between the branches.  In short, CVS $Id$-style substitutions
> that depend on the history fundamentally does not work, unless you
> are willing to always rewrite the whole working tree every time you
> switch branches.
>
> The smudge and clean filters are given _only_ the blob contents and
> nothing else, not "which commit (or tree) the blob is taken from",
> not "which path this blob sits in that tree-ish", not "what branch
> am I on" and this is a very much deliberate design decision made in
> order to avoid leading people to a misguided attempt to mimick CVS
> $Id$-style substitutions.
>
I will raise an Issue with ProGit.

It's perhaps beyond the scope of my original question, but for situations where I need a "last change date" embedded in a file (e.g. because a protocol standard requires it), is there any recommended way to do so? We've the hard way that hardcoding makes merging/cherry-picking a bit of a nightmare and should be avoided. Is a post-checkout hook the way to go? I've actually found the smudge filter to be very slow for this application as each file is processed in series; a post-commit hook that could operate on files in parallel would likely be substantially faster.

Stephen

(Sorry about the earlier top-posting. I didn't realize what gmail was doing until after it had happened.)

Previous: Junio C HamanoNext: Junio C Hamano
Message 6 of 7 in “git smudge filter fails”
  1. Stephen MortonMar 9, 2016
  2. Jeff KingMar 10, 2016
  3. Stephen MortonMar 10, 2016
  4. Jeff KingMar 10, 2016
  5. Junio C HamanoMar 10, 2016
  6. Stephen MortonMar 15, 2016
  7. Junio C HamanoMar 15, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.