Git diff алгоритм, который не разрывает функции на части? (с учетом языка различий)

Можно ли настроить git diff для учета отступов и синтаксиса? Я не говорю об игнорировании отступов и пробелов, а скорее об использовании пустых строк, уровней отступов и, возможно, скобок, чтобы помочь сопоставить старые строки с новыми строками.

Например, git diff часто прорезает функции и их докблок, например:

 class C {

   /**
+   * Goes to the bar.
+   */
+  function bar() {
+    return 'bar';
+  }
+
+  /**
    * Gets your foo up to date.
    */
   function foo() {

Когда я бы предпочел

 class C {
+
+  /**
+   * Goes to the bar.
+   */
+  function bar() {
+    return 'bar';
+  }

   /**
    * Gets your foo up to date.
    */
   function foo() {

В этом примере он все еще довольно безвреден, но есть примеры, когда функции и их докблок действительно разрываются из-за жадной и наивной реализации diff.

Примечание: я уже настроил *.php diff=php в ~/.gitattributes,

РЕДАКТИРОВАТЬ: Другой пример: здесь git diff смешивает свойство docblock с методом docblock:

   /**
-   * @var int
+   * @param string $str
    */

2 ответа

Я не знаю, как это сделать в одном git, но есть по крайней мере один коммерческий инструмент (то есть он стоит денег), который занимается такими проблемами, называемый SemanticMerge.

Он может обрабатывать множество интересных случаев и поддерживает C#, Java и частично C. Вы можете настроить git для использования его в качестве инструмента слияния.

(Я не связан.)

Прежде всего, используйте более сложный алгоритм сравнения, такой как:

git config --global diff.algorithm histogram

Кроме того, существуют также инструменты семантического сравнения, такие как https://github.com/GumTreeDiff/gumtree, алгоритм которых также был реализован в clang-diff: https://github.com/krobelus/clang-diff-playground

Другие вопросы по тегам