Может ли Git определить, являются ли два исходных файла копиями друг друга?
Извините, если это не по теме, но у вас есть шанс уменьшить количество "домашних заданий" на этом сайте:-)
Я преподаю класс программирования C, где студенты работают над небольшой библиотекой числовых подпрограмм на C. В этом году исходные файлы из нескольких групп студентов содержали значительное количество дублирующегося кода.
(Вплоть до одинаково с ошибками printf
отладочные заявления. Я имею в виду, насколько глупым ты можешь быть.)
Я знаю, что Git может определять, когда два исходных файла похожи друг на друга за определенное пороговое значение, но я никогда не смог заставить его работать с двумя исходными файлами, которых нет в репозитории Git.
Имейте в виду, что это не особенно искушенные ученики. Маловероятно, что они столкнутся с проблемой изменения имен переменных / функций.
Есть ли способ, которым я могу использовать Git для обнаружения значительного и буквального дублирования кода, известного как плагиат? Или есть какой-то другой инструмент, который вы могли бы порекомендовать для этого
5 ответов
Зачем вообще использовать git? Простой, но эффективный метод состоит в том, чтобы сравнить размеры различий между всеми различными представлениями, а затем вручную проверить и сравнить их с наименьшими различиями.
Мосс - это инструмент, разработанный проф. Я думаю, что они используют это там же. Это как diff для исходного кода.
Вы могли бы использовать diff
и проверьте, похожи ли эти два файла:
diff -iEZbwB -U 0 file1.cpp file2.cpp
Эти варианты говорят diff
игнорировать изменения пробелов и сделать git
-лайк diff
файл. Попробуйте это на двух примерах.
Добавляя к другим ответам, вы можете использовать diff
- но я не думаю, что ответы будут настолько полезны сами по себе. То, что вы хотите, это количество совпадающих строк, минус количество непустых строк, и чтобы получить это автоматически, вам нужно сделать немного магии с wc -l
а также grep
чтобы вычислить сумму длин файлов, минус длина файла сравнения, минус количество пустых строк, которые diff
включены как соответствующие. И даже тогда вы пропустите некоторые случаи, когда diff
решил, что одинаковые строки не совпадают из-за разных вещей, вставленных перед ними.
Гораздо лучшим вариантом является одно из предложений, перечисленных в https://stackru.com/questions/5294447/how-can-i-find-source-code-copying (или в https://stackru.com/questions/4131900 / Как обнаружить плагиат-код, хотя ответы, кажется, дублируют).
Использование diff абсолютно не очень хорошая идея, если вы не хотите рисковать в области комбинаторного ада:
- Если у вас есть 2 представления, вы должны выполнить 1 diff, чтобы проверить на плагиат,
- Если у вас есть 3 представления, вы должны выполнить 2 сравнения, чтобы проверить плагиат,
- Если у вас есть 4 представления, вы должны выполнить 6 различий, чтобы проверить плагиат,
- ...
- Если у вас есть n представлений, вы должны выполнить
(n-1)!
отличаться!
С другой стороны, Мосс, уже предложенный в другом ответе, использует совершенно другой алгоритм. По сути, он вычисляет набор отпечатков пальцев для значительных килограммов каждого документа. Отпечаток пальца фактически является хешем, используемым для классификации документов, и возможный плагиат обнаруживается, когда два документа в конечном итоге сортируются в одном и том же сегменте.