Có thể định cấu hình Git để sử dụng difftool được định cấu hình của mình với git add --patch
không?git add --patch với difftool
Tôi muốn chọn các thay đổi để thêm vào chỉ mục thông qua difftool của riêng tôi.
Có thể định cấu hình Git để sử dụng difftool được định cấu hình của mình với git add --patch
không?git add --patch với difftool
Tôi muốn chọn các thay đổi để thêm vào chỉ mục thông qua difftool của riêng tôi.
Không, thật không may.
Tôi cho rằng tôi có thể thấy rằng hoạt động - Git tạo tệp tạm thời dựa trên những gì hiện có trong chỉ mục, đưa nó đến difftool cùng với bản sao của phiên bản cây công việc hiện tại (để bảo vệ bạn không thực hiện thêm thay đổi), cho phép bạn sử dụng difftool để di chuyển một số thay đổi cho phiên bản chỉ mục, sau đó khi bạn lưu và thoát, các giai đoạn bất kỳ nội dung nào nằm trong phiên bản chỉ mục đã sửa đổi đó. Lưu ý rằng điều này sẽ yêu cầu difftool cũng là một chút của một trình soạn thảo, và không phải tất cả các difftools hợp lệ là; một số người trong số họ chỉ để xem diffs. Cũng lưu ý rằng điều này về cơ bản là bỏ qua tất cả của git add -p
. Bạn sẽ không có bất kỳ giao diện bình thường nào từ nó để di chuyển giữa các khối, tách các khối, v.v. Các difftool sẽ hoàn toàn chịu trách nhiệm cho tất cả điều đó.
Nếu difftool của bạn có đầy đủ tính năng đủ để làm điều này, thì tôi cho rằng bạn có thể viết một kịch bản để làm điều đó. Đường viền, không thực sự có bất kỳ lỗi bảo vệ nào, xử lý các trường hợp đặc biệt (tệp nhị phân?) Và hoàn toàn chưa được kiểm tra:
#!/bin/bash
tmpdir=$(mktemp -d)
git diff --name-only |
while read file; do
cp "$file" $tmpdir
# this has your changes in it
work_tree_version="$tmpdir/$file"
# this has the pristine version
index_version=$(git checkout-index --temp "$file")
# and now you bring changes from the work tree version into the index version,
# within the difftool, and save the index version and quit when done
my_difftool "$work_tree_version" "$index_version"
# swap files around to run git add
mv "$file" "$work_tree_version"
mv "$index_version" "$file"
git add "$file"
mv "$work_tree_version" "$file"
# you could also do this by calculating the diff and applying it directly to the index
# git diff --no-index -- "$file" "$original_index_version" | git apply --cached
rm -r $tmpdir
Có thể là nhiều cách để cải thiện điều đó; xin lỗi tôi không có thời gian để cẩn thận và kỹ lưỡng với nó ngay bây giờ.
Tôi nghĩ có lẽ tôi đã hỏi sai. Tôi có thể sử dụng difftool của tôi (Chúng giống nhau đối với tôi) không? Bằng cách này tôi có thể chọn tất cả các thay đổi mà tôi muốn thêm vào chỉ mục. Tôi sẽ cập nhật câu hỏi. – HaxElit
Đó là một ý tưởng thực sự tuyệt vời. Tôi có thể làm điều này một kịch bản và sau đó thêm một bí danh git 'git diffadd' hoặc một cái gì đó. Tôi sẽ thử làm sạch mã của bạn một chút và làm cho nó mạnh mẽ hơn một chút. Cảm ơn! – HaxElit
@ HaxElit: Nếu bạn nghĩ ra một thứ gì đó chắc chắn, vui lòng chỉnh sửa nó vào câu trả lời của tôi hoặc đăng bài của riêng bạn! – Cascabel
Thật không may là không.
Giao diện duy nhất tôi biết tại thời điểm này là một phần của git-gui khi gọi như
git gui citool
Giao diện khác là giao diện điều khiển giao diện người dùng tương tác khi gọi như
git add -i
git difftool phép một số tùy chọn công cụ khác, nhưng không phải là giao diện thêm.
Tôi không chắc chắn Tôi thấy sự liên quan của điều này; OP đang hỏi về 'git add --patch | -p', cho phép bạn chọn lọc các khối của miếng vá đến giai đoạn. 'git gui citool' chắc chắn không làm điều đó, vì vậy nó không liên quan. Và 'git add -i' có khả năng gọi' git add -p', do đó, nó là một cách vòng xoay để làm những gì OP đã biết, và ngược lại không làm những gì anh ta muốn. Vì vậy, các chất của câu trả lời của bạn là "không", mà tôi cảm thấy tôi khá tốt được bảo hiểm. – Cascabel
Đây là my script cho mục này, mở ra kdiff3
để bạn thực hiện quá trình hợp nhất 2 tệp. Nếu bạn không thích kdiff3
, hãy cung cấp các giá trị của riêng bạn cho MERGETOOL
và MERGECMD
(nhưng bạn sẽ bị điên không thích kdiff3
).
Để tránh những điều bất ngờ, tập lệnh này cố gắng bắt chước git add -p
đến mức đối số và mã lỗi. (Nó xử lý cả hai danh sách các tập tin và thư mục.)
Thêm vào đó, nó đúng cách xử lý các trường hợp góc khác nhau, bao gồm:
Ctrl+C
trước khi kết thúc (bỏ đầu)sử dụng Ví dụ:
$ ## With kdiff3 (default):
$ add-with-mergetool myfile1.txt
$ add-with-mergetool some-directory
$ ## ...or with custom mergetool:
$ export MERGETOOL='opendiff'
$ export MERGECMD='$LOCAL $REMOTE -merge $MERGED'
$ add-with-mergetool some-directory/*.py
#!/bin/bash
#
# add-with-mergetool
# Author: Stuart Berg (http://github.com/stuarteberg)
#
# This little script is like 'git add --patch', except that
# it launches a merge-tool to perform the merge.
# TODO: For now, this script hard-codes MERGETOOL and MERGECMD for kdiff3.
# Modify those variables for your own tool if you wish.
# In the future, it would be nice if we could somehow read
# MERGETOOL and MERGECMD from the user's git-config.
# Configure for kdiff3
# (and hide warnings on about modalSession, from kdiff3 on OSX)
MERGETOOL=${MERGETOOL-kdiff3}
MERGECMD=${MERGECMD-'"${MERGETOOL}" "${LOCAL}" "${REMOTE}" -o "${MERGED}"'\
2>&1 | grep -iv modalSession}
main() {
check_for_errors "[email protected]"
process_all "[email protected]"
}
check_for_errors() {
which "${MERGETOOL}" > /dev/null
if [[ $? == 1 ]]; then
echo "Error: Can't find mergetool: '${MERGETOOL}'" 1>&2
exit 1
fi
if [[ "$1" == "-h" ]]; then
echo "Usage: $(basename $0) [<pathspec>...]" 1>&2
exit 0
fi
# Exit early if we're not in a git repo
git status > /dev/null || exit $?
}
process_all() {
repo_toplevel=$(git rev-parse --show-toplevel)
# If no args given, add everything (like 'git add -p')
if [[ $# == 0 ]]; then
set -- "$repo_toplevel"
fi
# For each given file/directory...
args=("[email protected]")
for arg in "${args[@]}"
do
# Find the modified file(s)
changed_files=($(git diff --name-only -- "$arg"))
(
# Switch to toplevel, to easily handle 'git diff' output
cd "$repo_toplevel"
# For each modified file...
for f in "${changed_files[@]}"
do
if [[ $startmsg_shown != "yes" ]]; then
echo "Starting $(basename $0). Use Ctrl+C to stop early."
echo "To skip a file, quit ${MERGETOOL} without saving."
echo
startmsg_shown="yes"
fi
# This is where the magic happens.
patch_file_and_add "$f"
done
) || exit $? # exit early if loop body failed
done
}
# This helper function launches the mergetool for a single file,
# and then adds it to the git index (if the user saved the new file).
patch_file_and_add() {
f="$1"
git show :"$f" > "$f.from_index" # Copy from the index
(
set -e
trap "echo && exit 130" INT # Ctrl+C should trigger abnormal exit
# Execute 2-file merge
echo "Launching ${MERGETOOL} for '$f'."
LOCAL="$f.from_index"
REMOTE="$f"
MERGED="$f.to_add"
eval "${MERGECMD}"
if [[ -e "$f.to_add" ]]; then
mv "$f" "$f.from_working" # Backup original from working-tree
mv "$f.to_add" "$f" # Replace with patched version
git add "$f" # Add to the index
mv "$f.from_working" "$f" # Restore the working-tree version
fi
)
status=$?
rm "$f.from_index" # Discard the old index version
if [ $status == 130 ]; then
echo "User interrupted." 1>&2
exit $status
elif [ $status != 0 ]; then
echo "Error: Interactive add-patch stopped early!" 1>&2
exit $status
fi
}
main "[email protected]"
là Git thậm chí bao phủ trên StackOverflow? Tôi nghĩ đây sẽ là một câu hỏi hay hơn cho [SuperUser] (http://superuser.com/). – qJake
Bạn có thể đúng. Có nút di chuyển để di chuyển nó không? – HaxElit
Không, hãy để một mod làm điều đó, hoặc chỉ hỏi lại nếu bạn không muốn chờ đợi. – qJake