Trawling

OmniDiff, Git 변경을 코드 구문과 파일 내용 단위로 비교합니다

OmniDiff는 Git의 파일 변경사항을 코드에는 구문 구조로, 이미지·압축파일·폰트 등에는 내부 내용 단위로 비교해 보여줍니다. 대화형 Git difftool에서는 터미널 화면을 열고, `git diff`와 `git log -p`에서는 pager에 맞춘 텍스트 결과를 출력합니다. 지원하지 않는 코드 문법은 줄 단위로 비교하고 다른 바이너리는 파일이 다르다는 안내만 표시합니다.

본문

OmniDiff는 두 파일의 변경사항을 비교해 터미널에 보여주는 Rust 기반 도구입니다. 파일마다 한 가지 비교법을 적용하지 않고, 확장자나 바이트 내용으로 형식을 판별한 뒤 코드 구조나 파일 내부의 의미 있는 단위를 비교합니다. 직접 omnidiff BEFORE AFTER로 실행하거나 Git의 difftool로 연결해 씁니다.

코드 파일은 확장자로 언어를 판별합니다. README가 열거한 25개 언어는 Tree-sitter 문법으로 파싱한 뒤 구문 구조를 기준으로 비교합니다. 반면 Bazel, Dart, Emacs Lisp, Markdown, Protocol Buffers, SQL은 확장자를 알아보더라도 컴파일된 파서 문법이 없어 줄 단위 텍스트로 처리합니다. 알 수 없는 확장자도 줄 단위로 비교하므로 파일을 거부하지는 않지만, 이 경우 구조를 기준으로 한 비교는 적용되지 않습니다.

비텍스트 파일은 파일 이름이 아니라 바이트 내용을 살펴 형식을 판별합니다. 이미지에서는 픽셀 단위로 변경된 정도와 위치를 비교하고 애니메이션은 프레임별로 다룹니다. 압축파일은 내부 파일을 살피며 중첩된 압축파일도 처리합니다. 폰트는 글리프와 이름·메트릭을, 커서는 크기와 프레임을, 메시지 카탈로그는 메시지를 비교합니다. PDF는 페이지별로 그려 비교합니다. 따라서 압축파일이나 폰트 안에서 바뀐 항목을 골라 확인하는 흐름이 가능합니다.

OmniDiff는 변경 정도도 구분해 표시합니다. 이미지나 글리프의 차이는 invisible, imperceptible, artifacts, edited, redrawn, replaced 단계로 분류하고, 텍스트에는 whitespace, formatting, rewritten 같은 표현을 씁니다. 컨테이너에서는 바뀐 글리프나 그림을 한꺼번에 보거나 항목 하나를 열 수 있고, 텍스트 항목은 전체 diff 화면에서 확인할 수 있습니다.

그림을 화면에 표시할 때는 터미널이 kitty, sixel, iTerm2 그래픽 프로토콜을 지원하면 그 방식을 사용합니다. 지원하지 않는 터미널에서는 유니코드 반블록으로 대신 그리며, b 키로 두 표시 방식을 바꿀 수 있습니다. 이처럼 이미지 비교 결과는 터미널의 그래픽 지원 여부에 따라 표시 방식이 달라집니다.

Git에서는 omnidiff git configure로 전역 또는 현재 저장소에 설정한 뒤 git difftool --tool=omnidiff를 실행하면 대화형 TUI를 엽니다. git diff와 git log -p는 pager에 출력을 보내므로 전체 화면 TUI 대신 일반 텍스트를 사용합니다. 설정 없이 Git의 외부 diff 경로에 연결하려면 GIT_EXTERNAL_DIFF=omnidiff git diff를 실행하면 됩니다. OmniDiff가 다루지 않는 다른 바이너리는 Binary file <path> differs라는 한 줄 안내를 받으며, 형식별 내부 비교는 제공되지 않습니다.

저장소는 AGPL-3.0으로 공개합니다. 조직 내부에서 소스 공개 의무 없이 사용하는 경우를 위한 별도 상용 라이선스도 월 구독 형태로 안내합니다.

자료: OmniDiff GitHub 저장소 README / 정리·해설: Trawling

참고 자료

오류 제보