2010-03-05 6 views
7

Я использую Mercurial (в частности TortoiseHg для Windows) для управления версиями кода VBA. Любой, кто это пробовал, знает, что VBA изменяет случай каждой переменной во всем проекте всякий раз, когда любое объявление этой переменной изменяется в любом месте проекта (независимо от области действия). Это делает контроль версий кошмаром.Нечувствительность к регистру в Mercurial

Я хотел бы игнорировать регистр меняется в моем исходном коде при выполнении различий. Каков самый простой способ сделать это? (некоторая опция для diff, которую мне не хватает, внешняя утилита для сравнения, что-то еще?)

ПРИМЕЧАНИЕ: Я не говорю о том, чтобы иметь дело с «именами без учета регистра» (да, я говорю с вами в Google. ..)

+0

Мы снова встречаемся с моим другом! Вы когда-нибудь находили решение или, возможно, VCS, который мог бы делать разницы, нечувствительные к регистру? – RubberDuck

+1

@ RubberDuck: Ты вдохновил меня, наконец, опубликовать подход, который я использовал в течение последних нескольких лет. Я не полностью решил проблему, но я избавился от боли. В принципе, я игнорирую файлы, где только изменения относятся к корпусу. Если у файла есть законные изменения, я все еще смотрю, как меняется регистр, но он (много) лучше, чем ничего. – mwolfe02

ответ

7

Вы можете сделать это, когда будете отличаться для использования на экране, используя ExtDiff Extension.

[extensions] 
    hgext.extdiff = 

    [extdiff] 
    # add new command that runs GNU diff(1) in case-insensitive mode 
    cmd.mydiff = diff 
    opts.mydiff = -i 

Тогда вы бы запустить hg mydiff из командной строки. Это, конечно, требует, чтобы вы установили diff-бинар, будь то gnu или другой.

Однако, это не будет так полезно, как вам хотелось бы, потому что внутренне, конечно, Mercurial не может игнорировать случай - он берет криптографический хэш содержимого файла, и это не позволяет использовать комнату для маневра , Поэтому, если вы получите эту настройку, вы сделаете hg mydiff и не увидите никаких изменений, а затем выполните hg commit и увидите изменения повсюду.

Таким образом, вы можете сделать эту работу на экране, но не в принципе.

Один из вариантов заключается в том, чтобы найти визуальный базовый очиститель кода, аналогичный indent для C-подобных языков, который нормализует регистр переменной и запускает его в крюке с фиксацией. Тогда, по крайней мере, весь код, входящий в исходный контроль, будет согласован, и вы можете точно различать изменения.

+0

Похоже, что мой код-очиститель будет моим единственным вариантом. Спасибо за вашу помощь. – mwolfe02

2

Если у вас все в порядке с вашим кодом во всех нижних регистрах, скажем, тогда вы можете использовать encode/decode hooks для этого. Она будет работать следующим образом:

[encode] 
*.vba = tr A-Z a-z 

Это закодировать содержимое файла в нижнем регистре, когда вы фиксации. Диффы также вычисляются на основе кодированной (репозитории) версии файлов.

Рассмотрим файл, который содержит

hello 

Изменение его в рабочей копии

Hello World 

даст диф из

% hg diff 
diff --git a/a.txt b/a.txt 
--- a/a.txt 
+++ b/a.txt 
@@ -1,1 +1,1 @@ 
-hello 
+hello world 

Обратите внимание, как столица "H" и «W» игнорируется.

Я ничего не знаю о коде VBA, поэтому я не уверен на 100%, что это решение работает для вас. Но я надеюсь, что это может быть отправной точкой.

Недостатком является то, что вам необходимо установить это правило кодирования для всех ваших репозиториев. Расширение reposettings может помочь вам здесь.

+0

В этом случае это не работает для меня, но это отличный совет, который я постараюсь запомнить на будущее. Спасибо за помощь. – mwolfe02

2

Вот решение, на котором я остановился. Это далеко не идеально, но лучше, чем другие альтернативы, которые я рассмотрел.

Я создал сценарий AutoHotkey, который делает следующее:

  • возвращается файлов MS Access в хранилище с выявленными изменениями (для .orig файлов)
  • читает в .orig файл (один с изменения)
  • читает в существующий файл (один уже в хранилище)
  • преобразует текст обоих файлов в нижний регистр
  • сравнивает более низкое содержание тематических файлов
  • Если файлы по-прежнему отличаются, файл .orig восстанавливается, поэтому он может быть привязан к репозиторию
  • , если файлы являются одинаковыми (то есть они отличаются только в том случае, если файл .orig удален, потому что мы надеваем не заботьтесь об этих изменениях)

Для файлов, которые имеют реальные изменения, которые нам очень нравятся, я по-прежнему вижу изменения дела, которые были сделаны. Если это приводит к большому количеству шума, я открываю файл в инструменте сравнения, который позволяет сравнивать регистр, нечувствительный к регистру (например, kdiff).

Это не идеальное решение, но оно снимает около 90% разочарования для меня.

Вот мой сценарий. Обратите внимание, что сценарий включает в себя еще один сценарий Autohotkey, ConsoleApp.ahk, который предоставляет функцию с именем, ConsoleApp_RunWait(). Это сторонний скрипт, который больше не работает с 64-битным AHK, поэтому я не включаю его в качестве части моего ответа. Любая функция AHK, которая выполняет командную строку и возвращает результат в виде строки, будет достаточной.

; This script checks an MS Access source directory and reverts all files whose only modifications are to the 
; case of the characters within the file. 

#Include %A_ScriptDir%\ConsoleApp.ahk 
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. 
SendMode Input ; Recommended for new scripts due to its superior speed and reliability. 
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. 

; Allow for custom path to hg (support for moving to TortoiseHg 2.0) 
IniRead hg, %A_ScriptDir%\LocalSettings\Settings.cfg, TortoiseHg, hg_path, hg 

if 0 < 1 ; The left side of a non-expression if-statement is always the name of a variable. 
{ 
    MsgBox Usage:`n`HgIgnoreCase DirectoryWithFilesToScrub 
    ExitApp 
} 

SrcDir = %1% 
StringReplace SrcDir, SrcDir, ", , All 

StringRight test, SrcDir, 1 ; add trailing slash if necessary 
ifnotequal test, \ 
    SrcDir = %SrcDir%\ 

RestoreOriginals(SrcDir) 
RevertCaseChangeModifiedFiles(SrcDir) 

RevertCaseChangeModifiedFiles(SrcDir) { 
global hg 
    includes = -I "*.form" -I "*.bas" -I "*.report" -I "*.table" 
    cmdline = %hg% revert --all %includes% 

    ;Don't revert items that have been removed completely 
    Loop 3 
    { 
     Result := ConsoleApp_RunWait(hg . " status -nrd " . includes, SrcDir) 
     If (Result) 
      Break 
    } 
    Loop parse, Result, `n, `r 
    { 
     if (A_LoopField) 
      cmdline = %cmdline% -X "%A_LoopField%" 
    } 
    Result = 
    ;msgbox %cmdline% 
    ;revert all modified forms, reports, and code modules 
    Loop 3 
    { 

     Result := ConsoleApp_RunWait(cmdline, SrcDir) 
     If (Result) 
      Break 
    } 
    ;MsgBox %Result% 

    Loop parse, Result, `n, `r 
    { 
     StringLeft FileStatus, A_LoopField, 9 
     If (FileStatus = "reverting") 
     { 
      StringMid FName, A_LoopField, 11 
      FullPath = %SrcDir%%FName% 
      ToolTip Checking %FullPath% 
      RestoreIfNotEqual(FullPath, FullPath . ".orig") 
     } 
    } 
    ToolTip 
} 

RestoreIfNotEqual(FName, FNameOrig) { 
    FileRead File1, %FName% 
    FileRead File2, %FNameOrig% 

    StringLower File1, File1 
    StringLower File2, File2 
    ;MsgBox %FName%`n%FNameOrig% 
    If (File1 = File2) 
     FileDelete %FNameOrig% 
    Else 
     FileMove %FNameOrig%, %FName%, 1 
} 

RestoreOriginals(SrcDir) { 
    Loop %SrcDir%*.orig 
    { 
     ;MsgBox %A_LoopFileLongPath%`n%NewName% 
     NewName := SubStr(A_LoopFileLongPath, 1, -5) 
     FileMove %A_LoopFileLongPath%, %NewName%, 1 
    } 
    while FileExist(SrcDir . "*.orig") 
     Sleep 10 
} 
+0

Спасибо за подтверждение того, что это полезный подход. Я думал о чем-то подобном. – RubberDuck

Смежные вопросы