friebetill/obsidian-file-diff

Same feature as Winmerge

imshenwei opened this issue · 1 comments

me is using syncthing for my obsidian markdown file sync too.
while i just write a python script for python-winmerge combined three way merge today.

that you need to download winmerge in windows system and change Staggered File Versioning in syncthing.

so the point is if obsidian-file-diff can perform as winmerge did, it would be great.

below is the python script for auto find out sync-conflicted file name. this script then auto find out the earlier and closer according to timestamp in ./.stversion/* as syncthing document describe under Staggered File Versioning.

# 找到并输出
import re
import os
import os
# Assuming stversions_files is a list of file names in the stversions directory
# stversions_files = [...]  # replace with actual list
def find_conflict_files(directories):
    conflict_files = []
    for directory in directories:
        for root, dirs, files in os.walk(directory):
            for file in files:
                if 'conflict' in file:
                    conflict_files.append(os.path.join(root, file))
    return conflict_files

directories = [".\\0-Note", ".\\日记\\日记归纳"]
conflict_files = find_conflict_files(directories)
conflict_files = [file for file in conflict_files if '.sync-conflict' in file]
cleaned_files = [file.split('.sync-conflict-')[0] + '.md' for file in conflict_files]
cleaned_files_onlyname = [os.path.basename(file) for file in cleaned_files]
wantedcommand=[]
cleaned_files_onlyname = [file.replace('.md', '') for file in cleaned_files_onlyname]
stversions_files = []
for root, dirs, files in os.walk('.stversions/'):
    for file in files:
        for cleaned_file in cleaned_files:
            cleaned_file_name = os.path.basename(cleaned_file)
            cleaned_file_name = cleaned_file_name.replace('.md', '')
            if re.match(f"{cleaned_file_name}~\d+-\d+.md", file):
                stversions_files.append(os.path.join(root, file))

for i, name in enumerate(cleaned_files_onlyname):
    common_files=[]
    for file in stversions_files:
        if name in file:
            common_files.append(file)
    # 在这对比conflict文件最近的.stversions文件
    # Assuming sa11 and sa1316 are defined and contain the strings with timestamps
    # sa11 = ...  # replace with actual string
    # sa1316 = ...  # replace with actual string
    conflictfile = conflict_files[i]
    # print(conflictfile)
    conlicttimestamp = re.search(r'\d{8}-\d{6}', conflictfile).group()
    timestampst=[]
    timestampst.append(conlicttimestamp)
    for stfile in common_files:
        # print(stfile)
        timestampst.append(re.search(r'\d{8}-\d{6}', stfile).group())

    # Compare the three timestamps to find the earliest one
    timestampst.sort()

    # Find the timestamp that is closest and earlier than timestampa1309
    index_conflict = timestampst.index(conlicttimestamp)
    if index_conflict == 0:
        print("There is no earlier timestamp than timestampconflict")
    else:
        earlier_timestamp = timestampst[index_conflict - 1]
        # print("The closest and earlier timestamp than conflict is:", earlier_timestamp)
        # Find the full path and filename from common_files using earlier_timestamp
        earlier_file = next((file for file in common_files if earlier_timestamp in file), None)
        # print("The full path and filename for the earlier timestamp is:", earlier_file)
    # Print the latest file, earlier_file and conflictfile
    # print("The latest file is:", cleaned_files[i])
    # print("The earlier file is:", earlier_file)
    # print("The conflict file is:", conflictfile)
    # print("git merge-file --zdiff3 \"",cleaned_files[i],"\""," \"",earlier_file,"\""," \"",conflictfile,"\"", sep='')
    # Get the absolute paths
    abs_cleaned_file = os.path.abspath(cleaned_files[i])
    abs_earlier_file = os.path.abspath(earlier_file)
    abs_conflictfile = os.path.abspath(conflictfile)
    wantedcommand.append(["WinMergeU  \""+ abs_cleaned_file+"\""+" \""+abs_earlier_file+"\""+" \""+abs_conflictfile+"\""])
    print("git merge-file \"", abs_cleaned_file, "\"", " \"", abs_earlier_file, "\"", " \"", abs_conflictfile, "\"", sep='')
    # print("WinMergeU  \"", abs_cleaned_file, "\"", " \"", abs_earlier_file, "\"", " \"", abs_conflictfile, "\"", sep='')
    
    # print("WinMergeU leftpath \"",cleaned_files[i],"\""," middlepath \"",earlier_file,"\""," rightpath \"",conflictfile,"\"", sep='')

for siglecommand in wantedcommand:
    os.system(siglecommand[0])
    delete = input("Do you want to delete the files? (yes/no): ")
    if delete.lower() == 'yes':
        os.remove(conflictfile)
        print(conflictfile,"Files have been deleted.")
    else:
        print("Files have not been deleted.")

Thank you for bringing this to my attention and for the script! At the moment, I haven't incorporated support for Syncthing's Staggered File Versioning into the obsidian-file-diff plugin, primarily because it's not a feature I've utilized in my Obsidian workflow. However, I'm always open to enhancing the plugin's capabilities. If anyone in the community is interested in developing this functionality, I'd be thrilled to see it implemented and would support their efforts.