Post

VSCode Beyond compare 연동 (with WSL)

목차


VSCode Beyond compare 연동 (with WSL)


WSL2 설치 및 ssh 외부접속이 되지 않을 경우 사전 세팅이 필요

아래 링크 참조

WSL - Windows Subsystem for Linux

기본적인 동작 방법은

  1. Meld Diff가 Diff 커맨드가 담긴 bash script + Diff File 1 + Diff File 2를 쉘로 실행한다.
  2. bash script 안에는 diff file 1과 diff file 2 경로를 sftp 주소로 바꿔주는 내용과 ssh로 wsl에 원격으로 명령을 실행시키는 내용이 존재한다.
    1. sftp://remote_user @ remote_ip : remote_port / diff_file_path
    2. 이후 ssh 커맨드 실행하여 wsl로 내용 전송
  3. Diff 커맨드는 ssh wsluser @ wsl ip -p wsl port "beyondcompare path diff file1 diff file 2 형태로 진행된다.
  4. 이렇게 진행할 경우 wsl에서 명령을 받아 beyondcompare 바이너리가 실행되며 diff file1 diff file2 의 내용을 비교하여 결과를 표시해준다.

따라서 필자의 방법대로 세팅하더라도 원격지와 WSL간의 연결이 되지 않을 시 본 방법대로는 작동이 불가능하다. 는 제약 사항이 존재한다.


윈도우 로컬을 기준으로 설명

  1. VSCode 확장 Meld Diff 설치필요

    image

  2. settings.json 설정 - 아래내용 추가
    1. meld-diff.diffCommand에 BeyondCompare 경로를 추가한다.
    1
    
     "meld-diff.diffCommand": "C:\\Program Files\\Beyond Compare 4\\BComp.exe",
    
  3. 파일 하나를 선택해 Select for meld compare 클릭
  4. 이후 또다른 파일 하나를 선택해 Compare with selected for meld compare 클릭

    image

  5. 비교 내용이 Beyond Compare로 열린다.

Remote Development 사용 기준으로 설명

  1. VSCode 확장 Meld Diff 설치필요

    image

  2. 원격지 workspace (.code-workspace)의 settings 부분에 아래 내용 추가 (meld diff를 UI (local 확장)으로 실행 할 경우 remote development 에서 파일 비교를 시도할 경우 정상적으로 실행되지 않는 오류가 있다.)

    1
    2
    3
    4
    5
    6
    7
    8
    
     "remote.extensionKind": {
         "danielroedl.meld-diff": [ "workspace" ],
     },
     "meld-diff.diffArgumentsTwoWay": "\"$1\" \"$2\"",
     "meld-diff.diffArgumentsThreeWay": "\"$1\" \"$2\" \"$3\"",
     "meld-diff.diffCommand": "/<path>/.bcomp.sh",
     // 필자 설정
     // "meld-diff.diffCommand": "/home/username/.bcomp.sh",
    
  3. meld-diff.diffCommand 에 설정한 path에 .bcomp.sh 파일을 만든다. (필자는 홈 디렉토리에 생성하였다.)
    1. touch <path>/.bcomp.sh (주석 json대로 진행 시 : touch /home/username/.bcomp.sh)
    2. chmod 755 <path>/.bcomp.sh ( 주석 json대로 진행 시 : chmod 755 /home/username/.bcomp.sh)
  4. bcomp.sh에 아래와 같은 쉘 스크립트를 작성한다.
    1. 리눅스의 경우

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
      135
      136
      137
      138
      139
      140
      141
      142
      143
      144
      145
      146
      147
      148
      149
      150
      151
      152
      153
      154
      155
      156
      157
      158
      159
      160
      161
      162
      163
      164
      165
      166
      167
      168
      169
      170
      171
      172
      173
      174
      175
      176
      177
      178
      179
      180
      181
      182
      183
      184
      185
      186
      
       #!/bin/bash
      
       WIN_SSH=1
      
       # # WIN_SSH 값이 0 일 경우 아래 변수 사용
       #
       # WSL_IP=10.0.0.1
       # WSL_USER=test
       # WSL_PORT=22
       # REMOTE_IP=10.0.1.1
       # REMOTE_USER=test
       # REMOTE_PORT=22
       #
       # BCOMP_PATH="/mnt/c/Program\\ Files/Beyond\\ Compare\\ 4/BCompare.exe"
      
       # WIN_SSH 값이 1 일 경우 아래 변수 사용
      
       SSH_IP=10.0.0.1
       SSH_USER=test
       SSH_PORT=22
       REMOTE_IP=10.0.1.1
       REMOTE_USER=test
       REMOTE_PORT=22
      
       BCOMP_PATH="C:\Program Files\Beyond Compare 4\BCompare.exe"
      
       CP_PATH=/tmp/meldcp
      
       # CP_PATH clean up =================================
       if [ ! -d $CP_PATH ]; then
       	mkdir -p $CP_PATH
       fi
      
       file_count=`ls -l $CP_PATH | grep ^- | wc -l`
       # $file_count > 30
       if [ $file_count -gt 30 ]; then
       	rm -rf $CP_PATH
       	mkdir -p $CP_PATH
       fi
      
       dir_size=`du -shk $CP_PATH | awk -F ' ' ' { print $1 } '`
       # dir_size > 10M
       if [ $dir_size -gt 10240 ]; then
       	rm -rf $CP_PATH
       	mkdir -p $CP_PATH
       fi
       # ==================================================
       function sleep_rm()
       {
       	if [[ "$1" == "" ]]; then
       		return
       	fi
       	sleep 5
       	if [ -f $1 ]; then
       		rm -f $1
       	fi
       }
       # ==================================================
      
       if [ $WIN_SSH == 0 ]; then
       	if [[ $1 == "" ]]; then
       		exit 1
       	fi
      
       	D1=$1
       	if [[ ${D1:0} != "/" ]]; then
       		D1=`readlink -e "${1}"`
       	fi
      
       	DIFF_1="\"sftp://${REMOTE_USER}@${REMOTE_IP}:${REMOTE_PORT}/${D1}\""
       	DIFF_2=""
      
       	D2=""
       	if [[ $2 == "" ]]; then
       		DIFF_2="\"sftp://${REMOTE_USER}@${REMOTE_IP}:${REMOTE_PORT}/${D1}\""
       	else
       		D2=$2
       		if [[ ${D2:0} != "/" ]]; then
       			D2=`readlink -e "${2}"`
       		fi
       		if grep -q "/tmp/clipboard_" <<<"$D2"; then
       			cp -r $D2 $CP_PATH
       			d2_basename=`basename $D2`
       			rm -f $D2
       			D2=$CP_PATH/$d2_basename
       		fi
       		DIFF_2="\"sftp://${REMOTE_USER}@${REMOTE_IP}:${REMOTE_PORT}/${D2}\""
       	fi
      
       	if [[ "${DIFF_2}" == "" ]]; then
       		exit 1
       	fi
      
       	DIFF_3=""
       	DIFF_COMMAND=""
      
       	if [[ $# == 3 ]]; then
       		if [[ $3 == "" ]]; then
       			DIFF_COMMAND="${BCOMP_PATH} ${DIFF_1} ${DIFF_2}"
       		else
       			D3=$3
       			if [[ ${D3:0} != "/" ]]; then
       				D3=`readlink -e "${3}"`
       			fi
       			DIFF_3="\"sftp://${REMOTE_USER}@${REMOTE_IP}:${REMOTE_PORT}/${D3}\""
       			DIFF_COMMAND="${BCOMP_PATH} ${DIFF_1} ${DIFF_2} ${DIFF_3}"
       		fi
       	else
       		DIFF_COMMAND="${BCOMP_PATH} ${DIFF_1} ${DIFF_2}"
       	fi
      
       	# echo "${DIFF_COMMAND}"
       	if [[ "${DIFF_COMMAND}" == "" ]]; then
       		exit 1
       	fi
      
       	ssh ${WSL_USER}@${WSL_IP} -p ${WSL_PORT} "${DIFF_COMMAND}"
       	# sleep_rm $D2 &
      
       else
      
       	if [[ $1 == "" ]]; then
       		exit 1
       	fi
      
       	D1=$1
       	if [[ ${D1:0} != "/" ]]; then
       		D1=`readlink -e "${1}"`
       	fi
      
       	DIFF_1="\"sftp://${REMOTE_USER}@${REMOTE_IP}:${REMOTE_PORT}/${D1}\""
       	DIFF_2=""
      
       	D2=""
       	if [[ $2 == "" ]]; then
       		DIFF_2="\"sftp://${REMOTE_USER}@${REMOTE_IP}:${REMOTE_PORT}/${D1}\""
       	else
       		D2=$2
       		if [[ ${D2:0} != "/" ]]; then
       			D2=`readlink -e "${2}"`
       		fi
       		if grep -q "/tmp/clipboard_" <<<"$D2"; then
       			cp -r $D2 $CP_PATH
       			d2_basename=`basename $D2`
       			rm -f $D2
       			D2=$CP_PATH/$d2_basename
       		fi
       		DIFF_2="\"sftp://${REMOTE_USER}@${REMOTE_IP}:${REMOTE_PORT}/${D2}\""
       	fi
      
       	if [[ "${DIFF_2}" == "" ]]; then
       		exit 1
       	fi
      
       	DIFF_3=""
       	DIFF_COMMAND=""
      
       	if [[ $# == 3 ]]; then
       		if [[ $3 == "" ]]; then
       			DIFF_COMMAND="${BCOMP_PATH} ${DIFF_1} ${DIFF_2}"
       		else
       			D3=$3
       			if [[ ${D3:0} != "/" ]]; then
       				D3=`readlink -e "${3}"`
       			fi
       			DIFF_3="\"sftp://${REMOTE_USER}@${REMOTE_IP}:${REMOTE_PORT}/${D3}\""
       			DIFF_COMMAND="\"${BCOMP_PATH}\" ${DIFF_1} ${DIFF_2} ${DIFF_3}"
       		fi
       	else
       		DIFF_COMMAND="\"${BCOMP_PATH}\" ${DIFF_1} ${DIFF_2}"
       	fi
      
       	# echo "${DIFF_COMMAND}"
       	if [[ "${DIFF_COMMAND}" == "" ]]; then
       		exit 1
       	fi
      
       	SESS_ID=`ssh ${SSH_USER}@${SSH_IP} -p ${SSH_PORT} "query session | FIND \"${SSH_USER}\"" | awk -F ' ' '{ print $3 }'`
       	if [[ "${SESS_ID}" == "" ]]; then
       		exit 1
       	fi
      
       	ssh ${SSH_USER}@${SSH_IP} -p ${SSH_PORT} "psexec -s -i ${SESS_ID} ${DIFF_COMMAND}"
       	# sleep_rm $D2 &
      
       fi
      
    2. wsl의 경우

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      
       #!/bin/bash
      
       # BEYOND COMPARE DEFAULT PATH
       BCOMP_PATH="/mnt/c/Program\ Files/Beyond\ Compare\ 4/BComp.exe"
      
       if [[ $1 == "" ]]; then
           exit 1
       fi
      
       # 파일의 절대경로 얻는 법
       # $(dirname $(realpath $0))
       # readlink -e $0
       D1=$1
       if [[ ${D1:0} != "/" ]]; then
       	D1=`readlink -e "${1}"`
       fi
      
       DIFF_1="\"${D1:1}\""
       DIFF_2=""
      
       if [[ $2 == "" ]]; then
           DIFF_2="\"${D1:1}\""
       else
       	D2=$2
       	if [[ ${D2:0} != "/" ]]; then
       		D2=`readlink -e "${2}"`
       	fi
           DIFF_2="\"${D2:1}\""
       fi
      
       if [[ "${DIFF_2}" == "" ]]; then
           exit 1
       fi
      
       DIFF_3=""
       DIFF_COMMAND=""
      
       if [[ $# == 3 ]]; then
           if [[ $3 == "" ]]; then
               DIFF_COMMAND="${DIFF_1} ${DIFF_2}"
           else
       		D3=$3
       		if [[ ${D3:0} != "/" ]]; then
       			D3=`readlink -e "${3}"`
       		fi
               DIFF_3="\"${D3:1}\""
               DIFF_COMMAND="${DIFF_1} ${DIFF_2} ${DIFF_3}"
           fi
       else
           DIFF_COMMAND="${DIFF_1} ${DIFF_2}"
       fi
      
       # echo "${DIFF_COMMAND}"
       if [[ "${DIFF_COMMAND}" == "" ]]; then
           exit 1
       fi
      
       cd / >> /dev/null
       /mnt/c/Program\ Files/Beyond\ Compare\ 4/BComp.exe ${DIFF_COMMAND}
      
  5. ssh 연결 시 패스워드를 묻지 않도록 WSL에 키 등록을 진행해준다.
    1. wsl 접속 후 authorized_keys를 만들어 remote 대상의 id_rsa.pub의 내용을 붙여넣는다.
  6. beyond compare의 remote 패스워드/키 등록을 진행해준다.
    1. beyond compare를 열고
    2. Tools > Profiles

      image

    3. 우측 아래의 + 버튼 클릭 > FTP Profile 선택

      image

    4. Protocol: SFTP (SSH2) 선택 Host, Port, Username, Password 또는 SSH private key file (접속주소의 .ssh/id_rsa 내용)을 넣어 접속 정보를 저장해준다.

      image

    5. 이후 Save > Close 버튼을 눌러 저장 후 창을 닫는다.

모든 세팅이 완료되면 diff 시 정상적으로 beyond compare가 열린다.

image

  1. 스크린샷 예시 : a.c 파일 우클릭 Select for meld compare 선택
  2. 스크린샷 예시 : b.c 파일 우클릭 Compare with selected for meld compare 선택
  3. beyond compare가 열리며 자동으로 diff됨.

    image

  4. ssh 연결로 비교 진행하기에 beyond compare에서 내용을 수정하면 원격지에서도 수정이 되는 것을 확인할 수 있음.

키 바인딩 추가 (키 세팅의 경우 사용자의 입맛에 따라 변경하면 된다.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 첫번째 diff 내용 select
{
    "key": "shift+alt+d shift+alt+a",
    "command": "meld-diff.diffFromFileListSelect"
},
// 두번째 diff 내용 select  비교
{
    "key": "shift+alt+d shift+alt+s",
    "command": "meld-diff.diffFromFileList"
},
// 현재 파일을 클립보드의 내용과 비교
{
    "key": "shift+alt+d shift+alt+w",
    "command": "meld-diff.diffWithClipboard"
},

alias로 등록해 커맨드에서도 사용이 가능할 것 같다.

1
alias diffb='<path>/.bcomp.sh'

이후 diffb diff_file1 diff_file2 시 비욘드 컴페어로 파일이 열린다!

image

This post is licensed under CC BY 4.0 by the author.