Vinzent03 / obsidian-git

Integrate Git version control with automatic backup and other advanced features in Obsidian.md
MIT License
6.78k stars 288 forks source link

[Bug]: Git filters don't run on files with “ (“) characters in their contents #221

Open slnc opened 2 years ago

slnc commented 2 years ago

Describe the bug

I have a git clean filter set up for my Obsidian vault repo. When I use commandline git to commit changes the filter is always applied regardless of the file contents, but when I'm using Obsidian Git and I run Obsidian Git: Create Backup, a git commit is created but the configured git filter doesn't run for any files with a (&ldquo) character in them.

From the little digging I've done it might be that either Obsidian Git or SimpleGit aren't properly escaping a string somewhere. It's possible that there is also an issue with other characters like \”

Relevant errors (if available)

No response

Steps to reproduce

Should work on both Mac and Linux.

First set everything up:

mkdir /tmp/test
cd /tmp/test
git init .
echo "*.md filter=lastmod_updater" | cat > .gitattributes
git add .gitattributes
git commit -m "add .gitattributes"
git config --local filter.lastmod_updater.clean /tmp/lastmod_updater

cat > /tmp/lastmod_updater <<- EOM
#!/usr/bin/ruby
# These 2 lines added to determine if the hook is being called at all.
require 'fileutils'
FileUtils.touch('/tmp/lastmod_updater_called'+Time.now.to_i.to_s)

require 'time'
data = STDIN.read
last_date = \`/usr/bin/git log --pretty=format:"%ad" -1\`
puts data.gsub(/^lastmod:.+$/, 'lastmod: '+Time.now.iso8601)
EOM

chmod u+x /tmp/lastmod_updater

echo "lastmod: foo“" | cat > cmd.md
echo "lastmod: foo“" | cat > obsidian1.md
echo "lastmod: foo" | cat > obsidian2.md

Now verify that the git filter setup works when running in the commandline:

git add cmd.md
git commit -m "cmd commit"

# We clone the repository to verify HEAD contents because git 
# filters don't modify the worktree and you won't see the modified
# files unless you rm them and check them out and I thought that
# cloning was clearer.
cd ..
git clone test test2
grep lastmod test2/*.md

Which should show foo replaced with a timestamp:

lastmod: 2022-04-23T19:05:25+02:00

Now do this:

  1. If you're on Mac you will need to open Finder and add /tmp/test to the sidebar so that you can select it on the "Choose folder" Obsidian window.
  2. Open Obsidian
  3. Open another vault > Open folder as vault and choose /tmp/test
  4. Install Obsidian Git & enable it
  5. Open Command Palette and Run Obsidian Git: Create Backup
  6. Run the following on the commandline to confirm that the filter didn't get applied to obsidian.md:
cd /tmp
git clone -q test test3
grep lastmod test3/obsidian*.md

Which should show something like this:

test3/obsidian1.md:lastmod: foo“
test3/obsidian2.md:lastmod: 2022-04-23T19:33:32+02:00

Expected Behavior

test3/obsidian1.md should have foo“ replaced with a timestamp, in other words, it should behave exactly like commandline git.

Addition context

No response

Operating system

macOS

Plugin version

1.25.1

JohnPaton commented 3 months ago

Wow I was having issues with filters not being applied to a subset of files and I guess this was the reason! Good digging. But unfortunate :( I will just use the command line I guess.