Có cách nào để sử dụng Winmerge bên trong git để thực hiện Diffs không?
Có cách nào để sử dụng Winmerge bên trong git để thực hiện Diffs không?
Câu trả lời:
Cập nhật tháng 6 năm 2015, 6 năm sau:
Như đã trình bày chi tiết trong " git mergetool winmerge ", một cách đơn giản git config diff.tool winmerge
là đủ.
Git 2.5+ (Quý 2, 2015) hiện đã biết Winmerge như một công cụ khác biệt hoặc hợp nhất!
Câu trả lời gốc (2009-2012)
(msysgit, 1.6.5, phiên DOS)
Phần đầu tiên (sử dụng winmerge) được mô tả trong " Làm cách nào để xem đầu ra 'git diff' với chương trình visual diff? "
C:\myGitRepo>git config --replace --global diff.tool winmerge
C:\myGitRepo>git config --replace --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\""
C:\myGitRepo>git config --replace --global difftool.prompt false
Với winmerge.sh
được lưu trữ trong một phần thư mục của PATH
:
#!/bin/sh
echo Launching WinMergeU.exe: $1 $2
"$PROGRAMFILES/WinMerge/WinMergeU.exe" -e -u -dl "Local" -dr "Remote" "$1" "$2"
(xem Tùy chọn dòng lệnh WinMerge )
git difftool
bây giờ sẽ khởi chạy WinMerge.
Nếu bạn muốn git diff
khởi chạy WinMerge, chỉ cần đặt:
set GIT_EXTERNAL_DIFF=winmerge.sh
Nhưng giá trị gia tăng thực sự đến từ khả năng sử dụng cùng một công cụ khác biệt đó để trình bày tất cả các khác biệt trong một lô thay vì trình bày chúng tuần tự, buộc bạn phải đóng cửa sổ công cụ khác biệt từng tệp một.
Cập nhật tháng 6 năm 2012 (2 năm rưỡi sau):
Tính năng so sánh thư mục thay vì từng tệp sẽ sớm khả dụng:
Xem [ANNOUNCE] Git 1.7.11.rc1 :
"
git difftool
" đã học được--dir-diff
tùy chọn "" để tạo ra các công cụ khác biệt bên ngoài có thể so sánh hai cấu trúc phân cấp thư mục tại một thời điểm sau khi điền hai thư mục tạm thời, thay vì chạy một phiên bản của công cụ bên ngoài một lần cho mỗi cặp tệp .
Xem "Bản vá difftool
: dạy difftool
cách xử lý các điểm khác biệt thư mục " và câu trả lời " So sánh thư mục của các nhánh Git " để biết thêm chi tiết.
Bản gốc difftool của thư mục script (tháng 12 năm 2009)
Như Seba Illingworth đã đề cập trong câu trả lời của mình , một script git-diffall.sh (cũng được đặt trong đường dẫn) có thể làm điều đó:
#!/bin/sh
git diff --name-only "$@" | while read filename; do
git difftool "$@" --no-prompt "$filename" &
done
Nhưng điều đó chỉ hoạt động bằng cách mở n cửa sổ cho n tệp (nếu bạn cố gắng sử dụng -s
tùy chọn của WinMerge, nó sẽ không hoạt động vì tệp tạm thời bị xóa bởi bộ khuếch tán quá sớm)
Đó là lý do tại sao tôi thích cách tiếp cận của GitDiff.bat - power-diffing với GI , cho phép bạn xem lại danh sách các tệp có sự khác biệt, trước khi chọn một tệp để kiểm tra sự khác biệt bên trong của nó.
Tôi đã điều chỉnh nó để chỉ sử dụng các lệnh DOS
@echo off
setlocal
if "%1" == "-?" (
echo GitDiff - enables diffing of file lists, instead of having to serially
echo diff files without being able to go back to a previous file.
echo Command-line options are passed through to git diff.
echo If GIT_FOLDER_DIFF is set, it is used to diff the file lists. Default is windff.
goto END
)
if "%GIT_DIFF_COPY_FILES%"=="" (
rd /s /q %TEMP%\GitDiff
mkdir %TEMP%\GitDiff
mkdir %TEMP%\GitDiff\old
mkdir %TEMP%\GitDiff\new
REM This batch file will be called by git diff. This env var indicates whether it is
REM being called directly, or inside git diff
set GIT_DIFF_COPY_FILES=1
set GIT_DIFF_OLD_FILES=%TEMP%\GitDiff\old
set GIT_DIFF_NEW_FILES=%TEMP%\GitDiff\new
set GIT_EXTERNAL_DIFF=%~dp0\GitDiff.bat
echo Please wait and press q when you see "(END)" printed in reverse color...
call git diff %*
if defined GIT_FOLDER_DIFF (
REM This command using GIT_FOLDER_DIFF just does not work for some reason.
%GIT_FOLDER_DIFF% %TEMP%\GitDiff\old %TEMP%\GitDiff\new
goto END
)
if exist "%ProgramFiles%\Beyond Compare 2\BC2.exe" (
set GIT_FOLDER_DIFF="%ProgramFiles%\Beyond Compare 2\BC2.exe"
"%ProgramFiles%\Beyond Compare 2\BC2.exe" %TEMP%\GitDiff\old %TEMP%\GitDiff\new
goto END
)
"%ProgramFiles(x86)%\WinMerge\WinMergeU.exe" -r -e -dl "Local" -dr "Remote" %TEMP%\GitDiff\old %TEMP%\GitDiff\new
goto END
)
REM diff is called by git with 7 parameters:
REM path old-file old-hex old-mode new-file new-hex new-mode
copy %TEMP%\%~nx2 %GIT_DIFF_OLD_FILES%\%1
copy %5 %GIT_DIFF_NEW_FILES%
:END
Nó không đủ mạnh để xử lý các tệp có cùng tên trong các thư mục khác nhau, nhưng nó cung cấp cho bạn một ý tưởng chung về những gì có thể:
Ở đây chỉ có một WinMerge sẽ mở ra, với danh sách các tệp có sự khác biệt nội bộ. Bạn có thể nhấp vào những cái bạn muốn kiểm tra, sau đó một thao tác đơn giản ESCsẽ đóng tất cả WinMerge-diff
phiên.
git diff
?
-ub
, hãy xem Câu hỏi thường gặp về WinMerge : nó giống như vậy -u
: nó yêu cầu WinMerge không thêm tệp vào MRU.
c:\Temp\GitDiff\old
và c:\Temp\GitDiff\new
không phải là /tmp
''. Bạn có chắc chắn đang thực thi chương trình DOS này từ một phiên DOS (chứ không phải phiên bash) không?
""
trong trường hợp của tôi (thực hiện git config
lệnh từ Windows CMD. Nhưng bạn nói đúng: nó sẽ đánh giá ""
nếu được thực thi từ bash shell.
Tôi đã gặp sự cố khi sử dụng phần đầu tiên ở 2 nơi và đã sửa nó như sau
Lệnh thứ hai để thiết lập winmerge.cmd yêu cầu thêm một dấu gạch chéo trên cmdline (trước $ LOCAL và $ REMOTE), nếu không cygwin đang thay thế biến trong cmdline
C:\myGitRepo>git config --replace --global difftool.winmerge.cmd "winmerge.sh \"\$LOCAL\" \"\$REMOTE\""
đã thay đổi tệp winmerge.sh thành (không có tệp này, nhận được lỗi đường dẫn bên phải-không hợp lệ)
#!/bin/sh
echo Launching WinMergeU.exe: "$(cygpath -aw "$1")" "$(cygpath -aw "$2")"
"$PROGRAMFILES/WinMerge/WinMergeU.exe" -e -ub -dl "Base" -dr "Mine" "$(cygpath -aw "$1")" "$(cygpath -aw "$2")"
Vì luồng đang trở nên khó hiểu và phân nhánh, đây là hướng dẫn tổng hợp cho phương pháp WinMerge "--dir-diff" của Danh sách thư mục dành cho msysgit Git Windows.
Bước 1 - Tạo một tệp có tên winmerge.sh tại một vị trí có thể truy cập vào đường dẫn của bạn (chẳng hạn như /home/bin/winmerge.sh) với nội dung sau.
#!/bin/sh
echo Launching WinMergeU.exe: $1 $2
"$PROGRAMFILES/WinMerge/WinMergeU.exe" -r -ub -dl "Remote" -dr "Local" "$1" "$2"
Bước 2 - Nhập các lệnh sau vào Git Bash để hướng dẫn git sử dụng winmerge.sh làm difftool (các tùy chọn này được lưu trữ trong /home/.gitconfig):
git config --replace --global diff.tool winmerge
git config --replace --global difftool.winmerge.cmd "winmerge.sh \"$LOCAL\" \"$REMOTE\""
git config --replace --global difftool.prompt false
Bước 3 - Bây giờ bạn có thể kiểm tra bằng cách gõ lệnh sau vào Git Bash để bắt đầu khác biệt WinMerge của bạn:
git difftool --dir-diff
Bước 4 - Để truy cập nhanh hơn, hãy tạo bí danh cho lệnh này bằng cách thêm dòng này vào .bashrc trong thư mục chính của bạn (hoặc tạo tệp .bashrc với dòng này nếu tệp chưa tồn tại):
alias diffdir='git difftool --dir-diff'
Bước 5 - Bây giờ bạn có thể nhanh chóng thấy sự khác biệt trong WinMerge chỉ bằng cách gõ lệnh sau vào Git Bash
diffdir
$LOCAL
và $REMOTE
.
Tôi có một tập lệnh sẽ đặt các công cụ Diff và Merge trong cấu hình Git với các tham số thích hợp không yêu cầu tồn tại tệp .sh riêng biệt. Nó dường như đang hoạt động tốt cho tôi.
git config --global diff.tool winmerge
git config --global difftool.prompt false
git config --global difftool.winmerge.cmd "\"\$PROGRAMFILES\"/WinMerge/WinMergeU.exe -r -u -e -dl \"Local\" -dr \"Remote\" \"\$LOCAL\" \"\$REMOTE\""
git config --global merge.tool winmerge
git config --global mergetool.prompt false
git config --global mergetool.winmerge.trustExitCode true
git config --global mergetool.winmerge.cmd "\"\$PROGRAMFILES\"/WinMerge/WinMergeU.exe -r -u -e -dl \"Local\" -dr \"Remote\" \"\$LOCAL\" \"\$REMOTE\" \"\$BASE\" \"\$MERGED\""
Lưu ý - toàn bộ phần .cmd được trích dẫn để các tham số sẽ được liệt kê trong .gitconfig đúng cách
git config --global difftool.winmerge.cmd "\"\$PROGRAMFILES\"/WinMerge/WinMergeU.exe -r -u -e -dl \"Local\" -dr \"Remote\" \"\$LOCAL\" \"\$REMOTE\""
Lưu ý: Lệnh này phải được chạy từ dấu nhắc lệnh chứ không phải từ quyền hạn. Việc thêm thủ công phần sau vào [difftool "winmerge"]
phần .gitconfig của tôi đã mang lại hiệu quả cho tôi: cmd = 'C:/Program Files (x86)/WinMerge/WinMergeU.exe' -r -u -e -dl \"Local\" -dr \"Remote\" \"$LOCAL\" \"$REMOTE\"
git config --global mergetool.winmerge.cmd "\"C:\Program Files (x86)\WinMerge\WinMergeU.exe\" -r -u -e -dl \"Local\" -dr \"Remote\" \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$MERGED\""
. Có một vài chuỗi thoát không chính xác (lưu ý một vài dấu gạch chéo ngược không mong muốn bổ sung ở đó ngay trước $
- Tôi đoán $
không cần phải thoát). Ngoài ra, nó đã thiếu một kết thúc "
sau đó WinMergeU?.exe
. Chạy git config --get mergetool.winmerge.cmd
để xem những gì đã thực sự được thiết lập. Dù sao, cảm ơn cho .sh
phiên bản không phải : +1!
Trên windows, bạn có thể thực hiện theo cách này:
1) Mở tệp .gitconfig. Nó nằm trong thư mục chính của bạn: c: \ users \ username.gitconfig
2) Thêm các dòng bên dưới. Hãy chú ý đến các dấu ngoặc kép bao quanh đường dẫn đến winmerge:
[diff]
tool = winmerge
[difftool "winmerge"]
cmd = "'C:/Program Files (x86)/WinMerge/WinMergeU.exe'" -e "$LOCAL" "$REMOTE"
[difftool]
prompt = false
[merge]
tool = winmerge
[mergetool "winmerge"]
cmd = "'C:/Program Files (x86)/WinMerge/WinMergeU.exe'" \"$MERGED\" \"$REMOTE\"
[mergetool]
keepBackup = false
trustExitCode = false
Không có cấu hình:
git difftool --tool winmerge
Giả định:
Tôi đã nhầm lẫn về lý do tại sao giải pháp được trình bày dưới dạng tệp lô DOS, vì cài đặt Git của tôi đi kèm với trình bao bash. Tôi cũng không thể tải ngữ cảnh DOS chạy từ bash, vì vậy tôi đã cố gắng điều chỉnh những gì đã được chia sẻ trước đó trong ngữ cảnh bash.
Từ git diff
dường như chạy lệnh được chỉ định một lần cho mỗi tệp, tôi chia giải pháp của mình thành hai tập lệnh bash:
Đầu tiên, hãy cấu hình gitprepdiff.sh
để trở thành bộ khuếch tán như đã đề cập trước đó
#!/bin/sh
#echo ...gitprepdiff.sh
cp -v $1 "$TMP/GitDiff/old/$2"
cp -v $2 "$TMP/GitDiff/new"
Tôi cũng lưu ý rằng kết quả của các git configure
lệnh có thể được tìm thấy và chỉnh sửa trực tiếp trongC:\Users\<username>\.gitconfigure
gitdiff.sh
sau đó chạy ở dòng lệnh mà bạn thường gọi git diff
#!/bin/sh
#echo Running gitdiff.sh...
DIFFTEMP=$TMP/GitDiff
echo Deleting and re-creating $DIFFTEMP...
rm -rf $DIFFTEMP;
mkdir $DIFFTEMP;
echo Creating $DIFFTEMP/old...
mkdir $DIFFTEMP/old;
echo Creating $DIFFTEMP/new...
mkdir $DIFFTEMP/new;
git diff --name-only "$@" | while read filename; do
git difftool "$@" --no-prompt "$filename";
done
"$PROGRAMFILES\WinMerge\WinMergeU.exe" -r -e -dl "Repository" -dr "Working" $LOCALAPPDATA\\Temp\\1\\GitDiff\\old $LOCALAPPDATA\\Temp\\1\\GitDiff\\new
Cũng cần lưu ý rằng, trên cài đặt của tôi, /tmp
(trong bash) được ánh xạ tới %LOCALAPPDATA%\Temp\1\
(trong Windows), vì vậy đó là lý do tại sao tôi sử dụng cái sau trong cuộc gọi tới WinMerge.
gitprepdiff.sh
vì #!/bin/sh #echo ...gitprepdiff.sh mkdir -vp "$TMP/GitDiff/old/$(dirname $2)" cp -v $1 "$TMP/GitDiff/old/$2" cp -v --parents $2 "$TMP/GitDiff/new"
Thank You!
git config --global diff.tool winmerge
git config --global difftool.winmerge.cmd "\"$PROGRAMFILES\\WinMerge\\WinMergeU.exe\" -u -dl \"Local\" -dr \"Remote\" \"\$LOCAL\" \"\$REMOTE\""
git config --global difftool.prompt false
Theo hướng dẫn sử dụng dòng lệnh WinMerge : "Các tham số được bắt đầu bằng ký tự dấu gạch chéo (/) hoặc dấu gạch ngang (-)"