TransWikia.com

How to ignore/revert changes of case in file-content?

Stack Overflow Asked by slartidan on November 2, 2020

I am versioning Microsoft Access VBA code, which is in general case insensitive. However changes the case of variable names happen every now in then (by the Access compiler or by the developer). This often leads to huge change set in my git workspace.

How can I revert or ignore changes, that only concern upper- or lowercase of file contents?

An example:

git init
echo "public sub example()nend sub" > mdlExample.ACM
#                ^-- lower e
git add --all
git commit --all --message "Initial Commit"
echo "public sub Example()nend sub" > mdlExample.ACM
#                ^-- upper E

I would love something like:

git restore --only-case-changes # not working

And then:

git status
> On branch master
> nothing to commit, working tree clean

3 Answers

Have you considered the answer from this StackOverflow question:

How to perform case insensitive diff in Git

Maybe you can write a script to go and do the diff comparison for each commit and then add those commits to your branch. It may not be as simple as you like but maybe it will simplify the display of the changes to allow you to get to the case insensitive changes quicker?

Answered by Joseph Ishak on November 2, 2020

Consider changing example="example" to Example="Example". How do you propose Git could decide which case change to ignore here? Now consider code snippets in comments, or stored as strings for code generators. I get wanting Git to make an annoying chore go away, but I think if you try to imagine telling Git exactly what you want you'll understand the context of your question a little better.

How can I revert or ignore changes, that only concern upper- or lowercase of file contents

When you want to temporarily ignore changes, when you want to do a diff or a blame without seeing those changes, you can use a "textconv" filter that normalizes the text you diff. I use those to do things like strip embedded timestamps out of generated html when diffing, quickest to hand atm is

[diff "doc-html"]
    textconv = "sed  's,<span class="version">Factorio [0-9.]*</span>,,;s,<[^/>][^>]*>,\n&,g'"
    wordRegex = "<[^>]*\>|[^< \t\n]*"

in .git/config, and

doc-html/*.html diff=doc-html
*.cfg -diff

in .git/info/attributes.

so my what-changed diffs don't show me things I don't care about.

If you want to see the results of a diff ignoring case, try

[diff "nocase"]
        textconv="tr A-Z a-z"

and drop * diff=nocase (or maybe*.vba diff=nocase) into .git/info/attributes. When you're done, take it out.

but for merging, my leadoff example should convince you that Git automatically and silently making case changes in repo content, even just in the text that looks like identifiers, is a Bad Idea. When there's a conflict, not just a one-sided change but two different changes, it's still going to take some human judgement to decide what the result should be. Fortunately, with any decent merge tool, resolving simple conflicts is down around subsecond range each.

Answered by jthill on November 2, 2020

You don't have to git restore anything: You could setup a clean content filter driver as illustrated here, which will automatically convert those cases on git diff/git commit.
That means:

  • you won't even see there is a diff
  • you won't add /commit anything because of that content filter driver.

https://git-scm.com/book/en/v2/images/clean.png Image from "Keyword Expansion" section of the "ProGit book"

This is done through:

  • a .gitattributes filter declaration, which means you can associate it only to certain files (through, for instance, their extension)
    *.ACM filter=ignoreCase
    
  • a local git config filter.<driver>.clean to declare the actual script (which should be in your PATH)
    git config filter.ignoreCase.clean ignoreCase.sh
    
    # that give a .git/config file with:
    
    [filter "ignoreCase"]
      clean = ignoreCase.sh
    

The trick is:

Can you write a script which takes the content of an ACM file as input and produces the same ACM file as output, but with its strings converted?
You can have the filename in those scripts so you can do a diff and detect if said difference has to be adjusted, but you still need to write the right command to replace only "xxx" strings when their case changes in ACM files.

Note: jthill suggests in the comments to set the merge.renormalize config settings to tell Git that canonical representation of files in the repository has changed over time.

Answered by VonC on November 2, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP