2010-06-23 12 views
8

Mam repozytorium git (obejmujące mniej więcej historię projektu) i oddzielne źródła (tylko archiwum z kilkoma plikami), które rozwinęły się jakiś czas temu (a właściwie gdzieś w 2004 lub 2005 roku).Znaleźć źródło rozgałęzione od git

Źródła z tarball przeszły sporo zmian, z których chciałbym włączyć niektóre. Teraz pytanie brzmi: jak dowiedzieć się, co właściwie było punktem rozgałęzienia dla zmienionych źródeł, aby uzyskać minimalne różnice w tym, co się tam wydarzyło.

To, czego zasadniczo chcę, to znaleźć miejsce w historii git, gdzie kod jest najbardziej podobny do zbioru źródeł, które mam. I nie chcę tego robić ręcznie.

Warto również wspomnieć, że zmienione źródła zawierają tylko podzbiór plików i podzieliły niektóre pliki na więcej. Jednak kod, który tam jest, wydaje się otrzymywać tylko niewielkie modyfikacje i kilka dodatków.

Jeśli chcesz grać z tym sam, tarballa ze źródłami jest here i Git jest hostowany na Gitorious: git://gitorious.org/gammu/mainline.git

+1

Zauważyłem, że najstarsze pliki w tej smoły zostały zmodyfikowane w dniu 31/10/2006 12: 57. Zacznę tam moje poszukiwania. – Douglas

+0

Jak wspomniano w oryginalnym poście, z grubsza wiem, że rozwidliły się gdzieś w sezonie 2004/2005, ale to zbyt wiele, aby zbadać je ręcznie. –

Odpowiedz

4

W ogólnym przypadku, musisz sprawdzić każdy pojedynczy commit, ponieważ nie masz możliwości dowiedzenia się, czy możesz mieć dużą różnicę w jednym, małym diff w następnym, potem w innym dużym różnicie, to w medium diff ...

Najlepszym wyjściem będzie prawdopodobnie ograniczenie się do określonych plików. Jeśli rozważasz tylko jeden plik, nie powinieneś długo szukać kolejnych wersji tego pliku (użyj git rev-list <path>, aby uzyskać listę, więc nie musisz testować każdego zatwierdzenia). Dla każdego zatwierdzenia, które zmodyfikowało plik, możesz sprawdzić jego rozmiar i dość szybko znaleźć minimum. Zrób to dla kilku plików, mam nadzieję, że się zgodzą!

Najlepszym sposobem na przygotowanie się do rozpowszechniania jest tymczasowe zatwierdzenie poprzez skopiowanie do archiwum, aby można było porównać gałąź z numerem tarball. W ten sposób, można to zrobić:

git rev-list path/to/file | while read hash; do echo -n "$hash "; git diff --numstat tarball $hash path/to/file; done 

aby uzyskać ładny listę wszystkich zatwierdzeń z ich wielkości dyferencjału (pierwsze trzy kolumny będą SHA1, liczba linii dodanej, a liczba linii usuwane).Potem możesz go po prostu podłączyć do awk '{print $1,$2+$3}' | sort -n -k 2, a będziesz mieć posortowaną listę zatwierdzeń i ich rozmiary różnic!

Jeśli nie możesz ograniczyć się do niewielkiej garści plików do przetestowania, może będę miał ochotę ręcznie wdrożyć coś podobnego do git-bisect - po prostu spróbuj zawęzić swoją drogę do małej różnicy, przyjmując założenie, że w wszystkie prawdopodobieństwo, zobowiązuje się w pobliżu twojego najlepszego przypadku, będzie miało również mniejsze różnice, a zatwierdzenia z dala od niego będą miały większe różnice. (Gdzieś pomiędzy metodą Newtona i pełny na binarnego wyszukiwania/GRID, prawdopodobnie?)

Edit: Inną możliwością, zasugerował w Douglas' answer, jeśli uważasz, że niektóre pliki mogą być identyczne do tych w niektórych popełnić, jest hash je przy użyciu git-hash-object, a następnie zobacz, co popełnia w Twojej historii ten blob. Jest question with some excellent answers o tym, jak to zrobić. Jeśli zrobisz to za pomocą kilku plików - najlepiej tych, które często się zmieniają - możesz dość szybko zawęzić celowe zatwierdzenie.

+0

Myślę, że dobrym miejscem do rozpoczęcia ograniczania zestawu plików, który patrzysz, są prawdopodobnie pliki wspólne dla obu, ale nie zmieniające się od dłuższego czasu lub rzadko zmieniające się w jednym (lub jeszcze lepszym) drzewie . Pliki nagłówków mogą być dobrymi kandydatami, o ile nie zawierają zbyt wielu szalonych warunkowych warunków wstępnych. Znacznie łatwiej jest zmierzyć zmiany w różnicach długiej linii '# define's niż rzeczywistego kodu. – nategoose

+0

To wydaje się być najlepszym podejściem. Zmieniłem tylko to, aby nie używać pojedynczego pliku, ale kompletną listę plików, które mam w zmienionym drzewie i ograniczoną listę poprawek do przedziału, które odgadłem z niektórych części kodu. Dzięki. –

+1

To zadziałało bardzo dobrze dla mnie, jednak oferuję to ostrzeżenie: jeśli przenosisz pliki między * nix a Windows (lub Mac), * UWAŻAJ PASY *. Przekaż komendę dif -w opcji -w, więc zignoruje je, w przeciwnym razie możesz uzyskać ogromną różnicę, gdy naprawdę oba pliki są takie same, z wyjątkiem linii. –

0

jaki był widelec wykonany? czy był to klon, który ktoś zrobił, a potem wykonał własną pracę? jeśli tak, to jest to naprawdę łatwe. wszystko, co musisz zrobić, to stworzyć lokalny oddział, który pobiera kod z widelca. git zobaczy przodki rozgałęzionej gałęzi wskazujące na jedno z zatwierdzeń z twojego oryginalnego repozytorium i "połączy kropki", że tak powiem ... przywróci historię z twojego oryginalnego repozytorium do widelca.

powinieneś być w stanie to zrobić:

git remote add thefork git://wherever.it.lives/thefork.git 

git fetch thefork 

git branch -f thefork-branch thefork/branchname 

git checkout thefork-branch 

w tym momencie można uruchomić gitk i zobaczyć pełną historię rozwidloną gałęzi i lokalnym repozytorium, i zobaczyć, czy łączyć czy nie.

+0

Ah, nie było dla mnie jasne, że rozwidlone źródła to tylko archiwum, a właściwie repozytorium git. Zaktualizuje pytanie, aby było jasne. –

+0

ouch! tak ... to dla mnie nowość ... nie jestem pewna, czy potrafię poradzić sobie z tą sytuacją. –

2

Nie jest to świetne rozwiązanie, ale można się domyślić, które z wersji może to być: Załóżmy, że niektóre pliki w kuli tar nie zostały zmienione od czasu rozgałęzienia. Przeprowadź git hash object z każdym plikiem w kuli tar, a następnie wyszukaj te pliki w repozytorium za pomocą git show. Następnie spróbuj znaleźć zatwierdzenia, pod którymi pliki te zostały uwzględnione, prawdopodobnie używając git whatchanged. Odpowiedzią na twoje pytanie może być zatwierdzenie z najczęstszymi plikami, ale nadal będzie trochę chybione.

+0

To naprawdę świetny pomysł - napisałem swoją odpowiedź, zakładając, że wszystkie pliki będą miały małe różnice, a więc nie będziesz w stanie znaleźć dokładnej wersji w repozytorium. – Cascabel

+0

Świetny pomysł, niestety nie ma pliku bez zmian. –

+0

@Michal Čihař: Następnie przejdź do mojej odpowiedzi, która zawiera kilka podstawowych sposobów, aby spróbować znaleźć minimalną wersję diff! – Cascabel

0

importu że pliki w archiwum do rewizji git, na osobnej gałęzi lub zupełnie nowe: w pozycji na wykresie rewizyjnej nie jest ważne, po prostu chcemy to dostępne jako drzewa.

Teraz dla każdej zmiany w pana, tylko przeciwko temu diff drzewa/rewizji („importowanej”) i po prostu wyjścia, jak duży jest diff. Coś jak:

git rev-list master | while read rev; do patchsize=$(git diff $rev imported | wc -c); echo $rev $patchsize; done 

więc rewizja o najmniejszej wielkości plastra będzie „najbliżej”, o bardzo szorstkiej regułą. (W tej samej wersji pojawi się rozmiar poprawki wynoszący 0, a wszystko inne z pewnością będzie niezerowe, a im więcej się zmieni, tym większe).

+0

Niestety różnicowanie całego drzewa prowadzi zawsze do najstarszej wersji, ponieważ nie ma tak wielu dodatkowych plików. –

1

na podstawie tego, co araqnid wspomniany wymyśliłem 9c6c864426bf88429e77c7e22b5aa78e9295b97a (tylko poprosił o rzeczy między 0.61.0 head) to nie jest najlepszy, to prawdopodobnie) można zrobić lepiej z czymś jak

git rev-list --no-merges --all | while read rev; do patchsize=$(git diff $rev | wc -c); echo $patchsize $rev; done | sort -n | less 

zakładając” ve importowane archiwum do git i mieć, że rewizja wyrejestrowany (zrobiłem to przez untaring a następnie

git init 
git add . 
git commit -m "import tarball" 
git remote add origin git://gitorious.org/gammu/mainline.git 

Więc po to zrobić i bieg wyżej powinien wyjściu wielkość wszystkich dyferencjału w kolejności rosnącej patchsize (pierwszy będzie miał 0 ponieważ znajdzie aktualną głowę) zajmie to dużo czasu ... ale powinien znaleźć najmniejszą różnicę ...

0

Jeśli masz zgrubne wyobrażenie o tym, gdzie widelec się pojawił, zastanów się nad skorzystaniem z Will Manley's git meld. (Zobacz także: View differences of branches with meld?.)

Aby to zrobić, dodaj zawartość archiwum do swojego repozytorium (co i tak będziesz robił). Po zainstalowaniu meldunku i git-meld uruchom

git meld branch_from_tarball commit_to_check & 

na różnych zobowiązuje aż znajdziesz jedną z najmniejszych różnic. To polecenie otworzy się meld i wyświetli zmiany w drzewie katalogów pomiędzy określonymi zatwierdzeniami, z identycznymi plikami ukrytymi.Przykładowe screeny:

meldunku pokazując dwa bardzo różne zobowiązuje:
Very different

Pokazuje dwa podobne zobowiązuje: Similar