В документации git команды blame
говорится (выделено мое):
C []
Дополнительно-M, обнаруживать строки, перемещенные или скопированные из других файлов, которые были изменены в том же коммите.Это полезно, когда вы реорганизуете свою программу и перемещаете код между файлами. Когда эта опция задана дважды, команда дополнительно ищет копии из других файлов в коммите, который создает файл. Когда эта опция дается три раза, команда дополнительно ищет копии из других файлов в любом коммите,[...]
Прежде всего, что означает «другие файлы в коммите, который создает файл»?Ищет ли он файлы, которые были изменены в том же коммите, в котором был добавлен файл?Или он ищет все файлы, которые просто присутствуют в дереве коммита, в который был добавлен файл?
Я попробовал пример, в котором я создаю непустой файл (с именем source
)и пустой файл (имя dest
) в том же коммите.В следующем коммите я делаю что-то неуместное.В третьем и последнем коммите я копирую несколько строк от source
до dest
.Результат показан ниже (содержание довольно большое, чтобы попытаться не путать алгоритм git, извиняюсь за это):
$ git init
$ cat source
--incremental Show blame entries as we find them, incrementally
-b Show blank SHA-1 for boundary commits (Default: off)
--root Do not treat root commits as boundaries (Default: off)
--show-stats Show work cost statistics
--score-debug Show output score for blame entries
-f, --show-name Show original filename (Default: auto)
-n, --show-number Show original linenumber (Default: off)
-p, --porcelain Show in a format designed for machine consumption
--line-porcelain Show porcelain format with per-line commit information
-c Use the same output mode as git-annotate (Default: off)
-t Show raw timestamp (Default: off)
-l Show long commit SHA1 (Default: off)
-s Suppress author name and timestamp (Default: off)
-e, --show-email Show author email instead of name (Default: off)
-w Ignore whitespace differences
--minimal Spend extra cycles to find better match
-S <file> Use revisions from <file> instead of calling git-rev-list
--contents <file> Use <file>'s contents as the final image
-C[<score>] Find line copies within and across files
-M[<score>] Find line movements within and across files
-L <n,m> Process only line range n,m, counting from 1
--abbrev[=<n>] use <n> digits to display SHA-1s
$ cat dest
first initial line in dest
second initial line in dest
$ git add source dest
$ git commit -m "Add source and dest files"
$ touch new-file
$ git add new-file
$ git commit -m "Add irrelevant file"
$ (copy some lines from source to dest)
$ cat dest
first initial line in dest
--show-stats Show work cost statistics
--score-debug Show output score for blame entries
-f, --show-name Show original filename (Default: auto)
-n, --show-number Show original linenumber (Default: off)
-p, --porcelain Show in a format designed for machine consumption
--line-porcelain Show porcelain format with per-line commit information
-c Use the same output mode as git-annotate (Default: off)
-t Show raw timestamp (Default: off)
-l Show long commit SHA1 (Default: off)
-s Suppress author name and timestamp (Default: off)
-e, --show-email Show author email instead of name (Default: off)
-w Ignore whitespace differences
--minimal Spend extra cycles to find better match
-S <file> Use revisions from <file> instead of calling git-rev-list
--contents <file> Use <file>'s contents as the final image
second initial line in dest
$ git add dest
$ git commit -m "Copy lines from source to dest"
$ git log --pretty=oneline
6b0f18daaf83ec83d3f53b4a43f4188de3ce87e6 copy lines from source to dest
f1d66ad3dacb8e589747ed02b42d9135081b3704 Add irrelevant file
2b8275dc73ffd88d7adb6f90a2050ef14088019a Add source and dest files
$ git blame dest
^2b8275d - 1) first initial line in dest
6b0f18da - 2) --show-stats Show work cost statistics
6b0f18da - 3) --score-debug Show output score for blame entries
6b0f18da - 4) -f, --show-name Show original filename (Default: auto)
6b0f18da - 5) -n, --show-number Show original linenumber (Default: off)
6b0f18da - 6) -p, --porcelain Show in a format designed for machine consumption
6b0f18da - 7) --line-porcelain Show porcelain format with per-line commit information
6b0f18da - 8) -c Use the same output mode as git-annotate (Default: off)
6b0f18da - 9) -t Show raw timestamp (Default: off)
6b0f18da - 10) -l Show long commit SHA1 (Default: off)
6b0f18da - 11) -s Suppress author name and timestamp (Default: off)
6b0f18da - 12) -e, --show-email Show author email instead of name (Default: off)
6b0f18da - 13) -w Ignore whitespace differences
6b0f18da - 14) --minimal Spend extra cycles to find better match
6b0f18da - 15) -S <file> Use revisions from <file> instead of calling git-rev-list
6b0f18da - 16) --contents <file> Use <file>'s contents as the final image
^2b8275d - 17) second initial line in dest
$ git blame -C dest
^2b8275d - 1) first initial line in dest
6b0f18da - 2) --show-stats Show work cost statistics
6b0f18da - 3) --score-debug Show output score for blame entries
6b0f18da - 4) -f, --show-name Show original filename (Default: auto)
6b0f18da - 5) -n, --show-number Show original linenumber (Default: off)
6b0f18da - 6) -p, --porcelain Show in a format designed for machine consumption
6b0f18da - 7) --line-porcelain Show porcelain format with per-line commit information
6b0f18da - 8) -c Use the same output mode as git-annotate (Default: off)
6b0f18da - 9) -t Show raw timestamp (Default: off)
6b0f18da - 10) -l Show long commit SHA1 (Default: off)
6b0f18da - 11) -s Suppress author name and timestamp (Default: off)
6b0f18da - 12) -e, --show-email Show author email instead of name (Default: off)
6b0f18da - 13) -w Ignore whitespace differences
6b0f18da - 14) --minimal Spend extra cycles to find better match
6b0f18da - 15) -S <file> Use revisions from <file> instead of calling git-rev-list
6b0f18da - 16) --contents <file> Use <file>'s contents as the final image
^2b8275d - 17) second initial line in dest
$ git blame -C -C dest
^2b8275d - 1) first initial line in dest
6b0f18da - 2) --show-stats Show work cost statistics
6b0f18da - 3) --score-debug Show output score for blame entries
6b0f18da - 4) -f, --show-name Show original filename (Default: auto)
6b0f18da - 5) -n, --show-number Show original linenumber (Default: off)
6b0f18da - 6) -p, --porcelain Show in a format designed for machine consumption
6b0f18da - 7) --line-porcelain Show porcelain format with per-line commit information
6b0f18da - 8) -c Use the same output mode as git-annotate (Default: off)
6b0f18da - 9) -t Show raw timestamp (Default: off)
6b0f18da - 10) -l Show long commit SHA1 (Default: off)
6b0f18da - 11) -s Suppress author name and timestamp (Default: off)
6b0f18da - 12) -e, --show-email Show author email instead of name (Default: off)
6b0f18da - 13) -w Ignore whitespace differences
6b0f18da - 14) --minimal Spend extra cycles to find better match
6b0f18da - 15) -S <file> Use revisions from <file> instead of calling git-rev-list
6b0f18da - 16) --contents <file> Use <file>'s contents as the final image
^2b8275d - 17) second initial line in dest
$ git blame -C -C -C dest
^2b8275d dest - 1) first initial line in dest
^2b8275d source - 2) --show-stats Show work cost statistics
^2b8275d source - 3) --score-debug Show output score for blame entries
^2b8275d source - 4) -f, --show-name Show original filename (Default: auto)
^2b8275d source - 5) -n, --show-number Show original linenumber (Default: off)
^2b8275d source - 6) -p, --porcelain Show in a format designed for machine consumption
^2b8275d source - 7) --line-porcelain Show porcelain format with per-line commit information
^2b8275d source - 8) -c Use the same output mode as git-annotate (Default: off)
^2b8275d source - 9) -t Show raw timestamp (Default: off)
^2b8275d source - 10) -l Show long commit SHA1 (Default: off)
^2b8275d source - 11) -s Suppress author name and timestamp (Default: off)
^2b8275d source - 12) -e, --show-email Show author email instead of name (Default: off)
^2b8275d source - 13) -w Ignore whitespace differences
^2b8275d source - 14) --minimal Spend extra cycles to find better match
^2b8275d source - 15) -S <file> Use revisions from <file> instead of calling git-rev-list
^2b8275d source - 16) --contents <file> Use <file>'s contents as the final image
^2b8275d dest - 17) second initial line in dest
Как видно, git blame -C -C dest
не понимает, что новыйстроки в dest
происходят из source
, файла, который создается с этими строками в том же коммите, что и dest
.Однако git blame -C -C -C dest
дает ожидаемый результат.
Я что-то не так делаю?
Спасибо.
РЕДАКТИРОВАТЬ:
Я считаю,
[...] Когда эта опция задана дважды, команда дополнительно ищет копии из других файлов в коммите, который создает файл.[...]
означает, что git
будет искать копии строк (из других файлов), которые произошли только в коммите, который фактически создал файл, а не в том, что онбудет искать копии строк из других файлов (файлов, которые присутствовали в коммите, который создал файл).Это недоразумение связано с моим первым вопросом.