Czy można skonfigurować Git, aby używać mojego skonfigurowanego difftool z git add --patch
?git add --pakiet z difftoolem
Chciałbym wybrać zmiany, aby dodać do indeksu za pośrednictwem mojego własnego pliku difftool.
Czy można skonfigurować Git, aby używać mojego skonfigurowanego difftool z git add --patch
?git add --pakiet z difftoolem
Chciałbym wybrać zmiany, aby dodać do indeksu za pośrednictwem mojego własnego pliku difftool.
Nie, niestety.
Przypuszczam, że widzę, że działa - Git generuje plik tymczasowy oparty na tym, co aktualnie znajduje się w indeksie, przekazuje go do difftool wraz z kopią aktualnej wersji drzewa pracy (aby zabezpieczyć się przed wprowadzaniem dalszych zmian), pozwala użyć difftoola do przeniesienia niektórych zmian do wersji indeksu, a następnie po zapisaniu i zamknięciu następuje etapy dowolnej zawartości w zmodyfikowanej wersji indeksu. Zauważ, że wymagałoby to, aby difftool był również edytorem, a nie wszystkie poprawne difftoole; niektóre z nich służą tylko do przeglądania różnic. Zauważ również, że zasadniczo omijasz wszystkie z git add -p
. Nie miałbyś normalnego interfejsu do przechodzenia między porcjami, dzielenia bryłek i tak dalej. Difftool byłby całkowicie odpowiedzialny za to wszystko.
Jeśli twój dyftool jest w pełni wyposażony, aby robić tego rodzaju rzeczy, to przypuszczam, że możesz napisać skrypt, aby to zrobić. Zarys, naprawdę bez jakiejkolwiek ochrony błędów, obsługa szczególnych przypadkach i całkowicie niesprawdzone:
#!/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
Prawdopodobnie wiele sposobów poprawy tego; (pliki binarne?) przepraszam, nie mam czasu, aby być ostrożnym i dokładnym z tym teraz.
Myślę, że może spytałem o to źle. Czy mogę używać mojego difftoola (są dla mnie takie same)? W ten sposób mogę wybrać wszystkie zmiany, które chcę dodać do indeksu. Zaktualizuję pytanie. – HaxElit
To naprawdę świetny pomysł. Mogę zrobić ten skrypt, a następnie dodać alias git 'git diffadd' lub coś podobnego. Spróbuję trochę wyczyścić twój kod i uczynić go nieco bardziej wytrzymałym. Dzięki! – HaxElit
@HaxElit: Jeśli wymyślisz coś solidnego, możesz edytować je w mojej odpowiedzi lub zamieścić własne! – Cascabel
Niestety nie.
Jedynym UI znam w tej chwili jest częścią git-gui przy wywołaniu jako
git gui citool
The drugiej UI jest interaktywny interfejs konsoli przy wywołaniu jako
git add -i
git difftool pozwala niektóre różne opcje narzędzi, ale nie interfejs dodawania.
Nie jestem pewien Widzę znaczenie tego; OP pyta o 'git add --patch | -p', które pozwala ci wybiórczo wybrać porcje łatki do etapu. 'git gui citool' zdecydowanie tego nie robi, więc nie ma to znaczenia. I 'git add -i' jest w stanie wywoływać' git add -p', więc jest to okrężny sposób robienia tego, o czym OP już wie, a poza tym nie robi tego, co chce. Tak więc istotą twojej odpowiedzi jest "nie", co, jak sądzę, jestem całkiem dobrze zakryty. – Cascabel
Oto my script do tego, który otwiera kdiff3
, aby wykonać scalenie 2 plików. Jeśli nie podoba ci się kdiff3
, podaj swoje własne wartości dla MERGETOOL
i MERGECMD
(ale będziesz szalony, aby nie lubić kdiff3
).
Aby uniknąć niespodzianek, ten skrypt próbuje naśladować kod git add -p
, jeśli chodzi o argumenty i kody błędów. (Obsługuje obie listy plików i katalogów.)
Plus, to właściwie obsługuje różne przypadki narożne, w tym:
Ctrl+C
przed zakończeniem (rzucić wcześnie)Przykład użycia:
$ ## 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]"
Czy Git nawet pokryte na StackOverflow? Myślę, że byłoby to lepsze pytanie dla [SuperUser] (http://superuser.com/). – qJake
Może masz rację. Czy istnieje przycisk migracji, aby go przenieść? – HaxElit
Nie, pozwól modowi to zrobić, lub po prostu zapytaj ponownie, jeśli nie masz ochoty czekać. – qJake