Co to jest heurystyka git dla przypisywania modyfikacji treści do ścieżek plików?
Krótka wersja:
nie można się nad tym zastanawiaćgit
kod źródłowy, gdzie mogę znaleźć pełny opis heurystykigit
używa do kojarzenia kawałków treści z konkretnymi śledzonymi nazwami?
Szczegółowa wersja:
W poniższej interakcji demo powłoki (Unix) znajdują się dwa pliki,a
ib
, są ”git-commit
„ted”, a następnie są modyfikowane, aby (efektywnie) przenieść większośća
zawartość dob
iw końcu oba pliki są ponownie zatwierdzane.
Kluczową sprawą jest to, że wyjście drugiegogit commit
kończy się linią
rename a => b (99%)
nawet jeśli nie zmieniła się nazwa plików (w zwykłym znaczeniu) (!?!).
Ten krótki opis przed pokazaniem wersji demonstracyjnej może ułatwić śledzenie.
Zawartość plikówa
ib
są generowane przez połączenie zawartości trzech plików pomocniczych,../A
, ../B
, i../C
. Symbolicznie, stanya
ib
może być reprezentowany jako
../A + ../C -> a
../B -> b
tuż przed pierwszym zatwierdzeniem i
../A -> a
../B + ../C -> b
tuż przed drugim.
OK, oto demo.
Najpierw wyświetlamy zawartość plików pomocniczych../A
, ../B
, i../C
:
head ../A ../B ../C
# ==> ../A <==
# ...
#
# ==> ../B <==
# ###
#
# ==> ../C <==
# =================================================================
# =================================================================
# =================================================================
# =================================================================
# =================================================================
# =================================================================
(Linie zaczynające się od#
odpowiadają wyjściu do terminala; rzeczywiste linie wyjściowe nie mają linii wiodącej#
.)
Następnie tworzymy plikia
ib
, wyświetl ich zawartość i zatwierdź je
cat ../A ../C > a
cat ../B > b
head a b
# ==> a <==
# ...
# =================================================================
# =================================================================
# =================================================================
# =================================================================
# =================================================================
# =================================================================
#
# ==> b <==
# ###
git add a b
git commit --allow-empty-message -m ''
# [master (root-commit) 3576df7]
# 2 files changed, 8 insertions(+)
# create mode 100644 a
# create mode 100644 b
Następnie modyfikujemy plikia
ib
i wyświetl ich nową zawartość:
cat ../A > a
cat ../B ../C > b
head a b
# ==> a <==
# ...
#
# ==> b <==
# ###
# =================================================================
# =================================================================
# =================================================================
# =================================================================
# =================================================================
# =================================================================
Na koniec zatwierdzamy zmodyfikowanea
ib
; zanotuj wyjściegit commit
:
git add a b
git commit --allow-empty-message -m ''
# [master 25b806f]
# 2 files changed, 2 insertions(+), 8 deletions(-)
# rewrite a (99%)
# rename a => b (99%)
Zracjonalizowałem to zachowanie w następujący sposób.
Tak jak rozumiem,git
traktuje informacje o strukturze katalogów (takie jak nazwy ścieżek śledzonych plików) jakowtórny informacje - lub metadane, jeśli chcesz - aby być powiązane zpodstawowa informacje, które śledzi, a mianowicie różne fragmenty treści.
Ponieważ zarówno zawartość, jak i nazwy (w tym nazwy ścieżek) plików mogą się zmieniać między zatwierdzeniami,git
musi używać heurystyk do powiązania nazw ścieżek z kawałkami treści. Jednak heurystyki z natury nie gwarantują 100% czasu pracy. Niepowodzenie takiej heurystyki przybiera tutaj postać historii, która nie wiernie reprezentuje to, co faktycznie się wydarzyło (np. Zgłasza zmianę nazwy pliku, nawet jeśli nazwa pliku nie została zmieniona, w zwykłym znaczeniu).
Kolejnym potwierdzeniem tej interpretacji (mianowicie, że niektóre heurystyki są w grze) jest to, że AFAICT, jeśli rozmiar przeniesionego fragmentu nie jest wystarczająco duży, wynikgit commit
nie będzie zawieraćrewrite/rename
kwestia. (Na końcu tego posta zamieszczam demonstrację tego przypadku, FWIW.)
Moje pytanie brzmi: brak przejazdugit
kod źródłowy, gdzie mogę znaleźć pełny opis heurystykigit
używa do kojarzenia kawałków treści z konkretnymi śledzonymi nazwami?
To drugie demo jest identyczne z pierwszym pod każdym względem, z wyjątkiem pliku pomocniczego../C
jest o jeden wiersz krótszy niż wcześniej.
head ../A ../B ../C
# ==> ../A <==
# ...
#
# ==> ../B <==
# ###
#
# ==> ../C <==
# =================================================================
# =================================================================
# =================================================================
# =================================================================
# =================================================================
cat ../A ../C > a
cat ../B > b
head a b
# ==> a <==
# ...
# =================================================================
# =================================================================
# =================================================================
# =================================================================
# =================================================================
#
# ==> b <==
# ###
git add .
git commit -a --allow-empty-message -m ''
# [master (root-commit) a06a689]
# 2 files changed, 7 insertions(+)
# create mode 100644 a
# create mode 100644 b
cat ../A > a
cat ../B ../C > b
head a b
# ==> a <==
# ...
#
# ==> b <==
# ###
# =================================================================
# =================================================================
# =================================================================
# =================================================================
# =================================================================
git add .
git commit -a --allow-empty-message -m ''
# [master 87415a1]
# 2 files changed, 5 insertions(+), 5 deletions(-)