시맨틱 차이 유틸리티 [닫힘]


105

시맨틱 차이 / 병합 유틸리티의 좋은 예를 찾으려고합니다. 소스 코드 파일을 비교하는 전통적인 패러다임은 줄과 문자를 비교하는 방식으로 작동합니다. 그러나 파일을 비교할 때 실제로 코드 의 구조 를 고려하는 유틸리티 (모든 언어)가 있습니까?

예를 들어, 기존의 diff 프로그램은 "125 행의 문자 2에서 차이가 발견되었습니다. 파일 x에 void가 포함되어 있으며 여기서 파일 y에 bool이 포함되어 있습니다"를보고합니다. 특수 도구는 "void에서 bool로 변경된 doSomething () 메서드의 반환 유형"을보고 할 수 있어야합니다.

이러한 유형의 의미 정보는 실제로 사용자가 코드를 비교할 때 찾고있는 것이며 차세대 프로그램 도구의 목표가되어야한다고 주장합니다. 사용 가능한 도구에 이에 대한 예가 있습니까?


3
트리 편집 거리에 대한 연구가 수행 된 것 같습니다. 그것을 AST에 적용하는 것이 가장 먼저 시도 할 것 같습니다. (누군가가 이런 종류의 글을 쓰고 싶다면.)
Jay Kominek

2
정말 유용한 지 모르겠습니다. 언급 한 것과 같은 차이점은 읽는 것보다 더 쉽게 볼 수 있습니다. 특히 선 내의 차이점을 강조하는 도구가있는 경우 더욱 그렇습니다 . 일부 코드가 변경되지 않고 이동되었는지 여부를 인식하는 기능이 더 쉽고 유용 할 것입니다. imho!
UncleZeiv

2
@UncleZeiv 기능이 도구의 특성에서 자연스럽게 따르기를 바랍니다. 또한 누군가가 중괄호 나 들여 쓰기 스타일을 변경하거나 파일을 재 배열하여 정적 메서드를 그룹화하는 등의 경우 변경 사항이 없음을 감지 할 수 있습니다.
jasonmray

8
지금 Visual Studio에서 필요합니다. 팀 내의 개발자가 동일한 형식화 구조를 사용하여 diff를 용이하게하는 것은 역설적입니다. 코드는 체크인시 표준 형식으로 지정해야하며 개발자가 파일을 열 때마다 원하는 형식으로 지정해야합니다. 나는 이런 종류의 생각이이 시점에서 더 널리 퍼지지 않는다는 것에 놀랐다.
Langdon

3
IMHO 이것은 SO에게 좋은 주제입니다. 동의하는 경우 "재 개설"에 투표하십시오
Ira Baxter

답변:


37

우리는이 시나리오를 정확하게 처리 할 수있는 도구를 개발했습니다. http://www.semanticmerge.com 확인

텍스트 기반 알고리즘을 사용하지 않고 코드 구조를 기반으로 병합 (및 diff)하므로 기본적으로 강력한 리팩터링과 관련된 다음과 같은 경우를 처리 할 수 ​​있습니다. 또한 아래에서 볼 수 있듯이 차이점과 병합 충돌을 모두 렌더링 할 수 있습니다.

여기에 이미지 설명 입력

그리고 이동되는 텍스트 블록과 혼동되는 대신 먼저 구문 분석하기 때문에 메서드별로 (사실 요소별로) 충돌을 표시 할 수 있습니다. 이전과 같은 케이스는 해결해야 할 수동 충돌도 없습니다.

여기에 이미지 설명 입력

그것은 언어 인식 병합 도구이며 마침내이 질문에 답할 수있어서 좋았습니다 :-)


SVN과 통합 할 수 있습니까?
이전

1
그러나 Linux 및 Mac 버전은 오래되었습니다.
Michael Piefel

29

Eclipse 는 오랫동안이 기능을 가지고 있습니다. "구조 비교"라고하는데 아주 좋습니다. 다음은 Java 용 샘플 스크린 샷과 XML 파일 용 스크린 샷입니다.

(상단 창에있는 메소드의 빼기 및 더하기 아이콘에 유의하십시오.)

Eclipse의 Java 구조 비교기 Eclipse의 XML 구조 비교기


3
구조 비교를 사용하면 다른 소스 제어 병합 편집기처럼 변경 사항을 병합 할 수 있습니까? 즉,이 방법을이 버전에서 다른 버전으로 복사합니다.
Jonathan Parker

1
예, 변경 사항 또는 차이점 (상단 또는 하단 창)을 선택하면 도구 모음 버튼 (스크린 샷에 표시됨)을 사용하여 변경 사항을 왼쪽에서 오른쪽으로 또는 그 반대로 복사 할 수 있습니다.
Hosam Aly

1
안타깝게도 스크린 샷은 더 이상 (최다 찬성 및 수락 됨!) 답변에 표시되지 않습니다. 다시 제출해 주시겠습니까?
blubb 2013

@blubb 알려 주셔서 감사합니다. Java Comparer 이미지의 오류를 수정했습니다. 곧 XML 구조 비교기에 대한 스크린 샷을 추가하려고합니다.
Hosam Aly 2013

1
Java 이외의 언어에서도 작동합니까?
einpoklum

14

"의미 적 비교"를 잘 수행하려면 언어의 구문 트리를 비교하고 기호의 의미를 고려해야합니다. 정말 좋은 의미 차이는 언어 의미를 이해하고 한 코드 블록이 다른 코드 블록과 기능면에서 동등하다는 것을 깨달을 것입니다. 여기까지 가려면 정리 증명자가 필요하며 매우 귀엽지 만 실제 도구에는 현재 실용적이지 않습니다.

이에 대한 실행 가능한 근사치는 단순히 구문 트리를 비교하고 삽입, 삭제, 이동 또는 변경된 구조 측면에서 변경 사항을보고하는 것입니다. "의미 적 비교"에 다소 가까워지면 코드 블록에서 식별자가 일관되게 변경 될 때보고 할 수 있습니다.

위의 근사를 수행하는 여러 언어에서 작동하는 구문 트리 기반 비교 엔진은 http://www.semanticdesigns.com/Products/SmartDifferencer/index.html 을 참조하십시오 .

2010 년 1 월 편집 : C ++, C #, Java, PHP 및 COBOL에 사용할 수있는 버전. 웹 사이트는 이들 대부분에 대한 구체적인 예를 보여줍니다.

2010 년 5 월 편집 : Python 및 JavaScript가 추가되었습니다.

2010 년 10 월 편집 : EGL이 추가되었습니다.

2010 년 11 월 편집 : VB6, VBScript, VB.net 추가


2
안녕 Ira, diff 알고리즘에 대한 논문을 발표 했습니까? 트리 편집 거리 차이 문헌을 찾는 데 문제가 있습니다. 고마워, 테렌스
Terence Parr

더 구체적으로 말하면, 일반 diff2가 아닌 diff3를 찾고 있습니다.
Terence Parr

2
@Terence : diff 알고리즘에 대한 출판물이 없습니다. 동일한 하위 트리를 식별하기 위해 접미사 트리를 사용하는 Levenstein 최소 거리 계산이며 이름 바꾸기를 처리하는 일부 휴어 스틱이 있습니다. IIRC, Yang은 Software Practice and Experience에서 이에 대한 논문을 작성했습니다. 우리와 양은 diff3이 아니라 diff2입니다.
Ira Baxter

@IraBaxter 현재 링크가 끊어졌으며 Google 링크에서 열 때 사이트가 다운 된 것 같습니다.
Răzvan Flavius ​​Panda

사이트가 백업되었습니다. 링크는 정상이어야합니다.
Ira Baxter

12

당신이 모색하는 것은 "나무 차이"입니다. 이것은 단순히 두 개의 플랫 시퀀스를 비교하는 단순한 라인 중심의 텍스트 차이보다 훨씬 더 잘 수행하기 어렵다는 것이 밝혀졌습니다.

" 세분화 된 XML 구조 비교 접근 방식 "은 부분적으로 다음과 같이 결론을 내립니다.

우리의 이론적 연구와 실험적 평가는 제안 된 방법이 동일한 시간 복잡도 (O (N ^ 2))를 가지 면서 기존 대안에 비해 향상된 구조적 유사성 결과를 산출한다는 것을 보여주었습니다.

(강조 내)

실제로 트리 차이에 대한 더 많은 예제를 찾고 있다면 XML에 초점을 맞추는 것이 좋습니다. XML이 그 영역에서 실질적인 발전을 주도하고 있기 때문입니다.


링크 주셔서 감사합니다. sematic diff 도구를 구현하기위한 몇 가지 다른 접근 방식을 생각할 수 있으며 맞습니다. 대부분은 "tree diff"로 추상화 할 수 있습니다. 더 복잡한 상황은 "그래프 차이"로 추상화해야 할 수도 있습니다.
jasonmray

네. IBM의 Rational Modeler (eclipse 기반)는 UML 모델 (두 모델 간의 차이점을 그래픽으로 표시)으로이를 수행하려고합니다. 나는 그것을 많이 사용하지 않기 때문에 결과의 유용성에 대해 언급 할 수 없습니다.
bendin

XML이 시작하기에 좋은 곳이라는 데 동의합니다. 다른 구조 (예 : Java 코드)를 나타내는 스키마를 생각해 내고 XML 기반 트리 차이를 사용하여 코드 차이를 구현할 수 있기 때문입니다.
jasonmray

"do this"=> "그래프 차이"와 유사한 것을하십시오.
bendin

1
여러 언어에서 작동하는 구문 트리 기반 비교 엔진 은 semdesigns.com/Products/SmartDifferencer/index.html 을 참조하십시오 .
Ira Baxter


2

이에 대한 해결책은 언어 단위입니다. 즉, 코드를 트리로 파싱하고 언어 별 플러그인에 대한 의미 비교를 연기하는 플러그인 아키텍처로 설계되지 않은 경우 여러 언어를 지원하기가 매우 어려울 것입니다. 이러한 도구를 사용하는 데 관심이있는 언어는 무엇입니까? 개인적으로 나는 C #을 좋아합니다.

C #의 경우 Reflector에 대한 어셈블리 diff 추가 기능이 있지만 C #이 아닌 IL에서만 diff를 수행합니다.

여기 [zip] 에서 diff 추가 기능을 다운로드 하거나 여기 에서 codeplex 사이트의 프로젝트로 이동할 수 있습니다 .


1
정확한 언어 플러그인 스타일을 사용하여 여러 언어에서 작동하는 구문 트리 기반 비교 엔진 은 semdesigns.com/Products/SmartDifferencer/index.html 을 참조하십시오 . 아직 출시되지 않았지만 C # 버전은 매우 가깝습니다.
Ira Baxter

2010 년 1 월 : C # Smart Differencer가 출시되었습니다.
Ira Baxter

2

Zynamics라는 회사는 이진 수준의 의미 차이 도구를 제공합니다. REIL이라는 메타 어셈블리 언어를 사용하여 2 개의 바이너리 버전에 대한 그래프 이론적 분석을 수행하고 두 버전 간의 차이점을 설명하기 위해 색상 코드 그래프를 생성합니다. 가격은 확실하지 않지만 무료인지는 모르겠습니다.


바이너리 수준의 의미 DIFF 링크 : zynamics.com/bindiff.html
emallove

2

http://prettydiff.com/

Pretty Diff는 각 입력을 최소화하여 주석과 불필요한 공백을 제거한 다음 diff 알고리즘 이전에 코드를 아름답게 만듭니다. 나는 어쨌든 이것보다 더 많은 코드 의미가 될 것이라고 생각할 수 없다. 그리고 작성된 JavaScript는 브라우저에서 직접 실행됩니다.


5
그렇다면 당신은 제한된 상상력을 가지고 있습니다! 파일에서 두 메서드의 위치를 ​​바꾸지 않고 그대로 두는 것은 어떻습니까? 리팩토링은 어떻습니까?
Robin Green

(이 방법으로 Java에서 데이터 선언을 바꿀 수는 없지만 이니셜 라이저로 인해 여전히 동등성이 있습니다. C #에 유사한 문제가 있다고 가정합니다.) 순수한 의미 차이를 찾으면 Turing 기계 동등성을 해결하려고합니다. 순수한 텍스트 매칭보다 더 잘하고 Turing 불가능한 것보다 더 나쁜 일을 할 수있는 많은 범위가 있습니다.
Ira Baxter

@IraBaxter이 도구는 개념적으로 실제로 동등한 것으로 만 표시됩니다. 올바르게 코딩 된 경우 언급 한 문제 유형이 없습니다.
Răzvan Flavius ​​Panda

"올바르게 코딩 된"이란 궁극적 인 도구를 원할 경우 알고리즘 동등성을 입증하는 것을 의미합니다. 알고리즘 동등성 증명은 일반적으로 Turing-hard이므로 실제로 그러한 도구를 얻지 못할 것입니다. 당신이 얻을 수있는 것은 구문 변경 이외의 일부 동등성 을 처리하는 도구입니다 . 지금까지 아무도 그러한 도구를 만들려는 시도를 본 적이 없습니다.
Ira Baxter
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.