Jak różnicować i łączyć dwa katalogi?

38

Wiem, że tryb różnicowy Vima ( vimdiff) pozwala nam porównać zawartość dwóch (lub więcej) plików.

Ale czy można porównywać zawartość wielu plików w różnych katalogach, aby rekursywnie scalać dwa katalogi (np. DiffMerge i podobne narzędzia)?

kenorb
źródło
Czy w Twoich folderach jest używany jakiś VCS? To otworzyłoby całą gamę odpowiedzi i wtyczek, które mogą nie być dostępne dla płaskich folderów.
Caleb

Odpowiedzi:

30

Istnieje wtyczka DirDiff.vim ( GitHub ) do różnicowania i scalania dwóch katalogów rekurencyjnie.

Wykonuje rekursywną różnicę w dwóch katalogach i generuje „okno” diff. W oparciu o to okno możesz wykonywać różne operacje różnicowe, takie jak otwieranie dwóch plików w trybie różnicowym Vima, kopiowanie pliku lub katalogu rekurencyjnie do drugiego lub usuwanie drzewa katalogów z katalogu źródłowego.

Stosowanie:

:DirDiff <dir1> <dir2>

Aby uzyskać więcej informacji / pomocy: :help dirdiff

Zobacz zrzut ekranu:

zrzut ekranu wlee

Zobacz też:

kenorb
źródło
link do bloga dedm jest zepsuty - raczej blog został usunięty.
drevicko
1
@drevicko Dzięki, zastąpiłem link zarchiwizowanym
kenorb
4

Używam skryptu opakowującego pythondo scalania plików (patrz poniżej). To jest uproszczona wersja tego, czego używam do scalenia moich ~/.vimkatalogów i tym podobnych.

Powinien działać w Pythonie 2 i 3; ale prawdopodobnie nie w bardzo starych wersjach Pythona dostarczanych z CentOS i innymi dystrybucjami.

Należy pamiętać, że niektóre kontrole (takie jak kontrola plików binarnych lub jeśli pliki są takie same) nie są bardzo szybkie (odczytuje cały plik); możesz je usunąć, jeśli chcesz.

Nie zgłasza także, czy a występuje tylko w jednym z katalogów ...

#!/usr/bin/env python
from __future__ import print_function
import hashlib, os, subprocess, sys

if len(sys.argv) < 3:
    print('Usage: {} dir1 dir2'.format(sys.argv[0]))
    sys.exit(1)

dir1 = os.path.realpath(sys.argv[1])
dir2 = os.path.realpath(sys.argv[2])

for root, dirs, files in os.walk(dir1):
    for f in files:
        f1 = '{}/{}'.format(root, f)
        f2 = f1.replace(dir1, dir2, 1)

        # Don't diff files over 1MiB
        if os.stat(f1).st_size > 1048576 or os.stat(f2).st_size > 1048576: continue

        # Check if files are the same; in which case a diff is useless
        h1 = hashlib.sha256(open(f1, 'rb').read()).hexdigest()
        h2 = hashlib.sha256(open(f2, 'rb').read()).hexdigest()
        if h1 == h2: continue

        # Don't diff binary files
        if open(f1, 'rb').read().find(b'\000') >= 0: continue

        subprocess.call(['vimdiff', f1, f2])
Martin Tournoij
źródło
3

Od jakiegoś czasu chciałem tego samego. Najlepszym rozwiązaniem, jakie znalazłem, było użycie vdwrap , który działa niesamowicie dobrze. Wszystko robi to okład git difftool --dir-diffna vimdiff. Nie wymaga żadnych wtyczek vim.

Wszystko, co musisz zrobić, to powiedzieć, git difftoolaby użyć vdwrap:

git config --global difftool.vdwrap.cmd '/full/path/vdwrap $LOCAL $REMOTE'
git config --global diff.tool vdwrap

Następnym razem, gdy użyjesz git difftool, otworzy Vima z osobnymi zakładkami Vima dla każdej pary plików.

Zastrzeżeniem jest to, że jest to skrypt Zsh. Przekształcenie go w skrypt bashowy powinno być dość proste, ale nie dałem rady.

akshay
źródło
powiązane: stackoverflow.com/questions/8156493/git-vimdiff-and-dirdiff
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
2

Jeśli chcesz po prostu użyć vimdiff bez instalowania czegokolwiek dodatkowego, następujące polecenie otworzy kolejno wszystkie różne pliki, pozwalając ci spojrzeć na zmiany w vimdiff:

    for files in $(diff -rq dir1 dir2|grep 'differ$'|sed "s/^Files //g;s/ differ$//g;s/ and /:/g"); do 
        vimdiff ${files%:*} ${files#*:}; 
    done
Jongab
źródło
1

Jest na to lekkie rozwiązanie:

  1. Skonfiguruj wtyczkę vimdiffext .
  2. Zrób diff dir1 dir2 | vim -R -w muszli.

Dodanie foldów i porównanie obok siebie dla zmienionych plików.

Jurij Erszow
źródło