Принудительно Git показывать удаление + переход к удаленному пути как удаление + переименование, а не редактирование + удаление - PullRequest
0 голосов
/ 06 января 2020

Возможно, это противоположность обычного вопроса: я хочу Git сделать обнаружение переименования более агрессивным, чем оно есть на самом деле.

$ git init demo
Initialized empty Git repository in …/demo/.git/
$ cd demo
$ echo '#include b' > a
$ (for x in {00..99}; do echo $x; done) > b
$ git add a b
$ git commit -m initial
[master (root-commit) …] initial
 2 files changed, 101 insertions(+)
 create mode 100644 a
 create mode 100644 b
$ git rm a
rm 'a'
$ git mv b a
$ git commit -m inlined
[master …] inlined
 2 files changed, 100 insertions(+), 101 deletions(-)
 delete mode 100644 b
$ git show -p
commit … (HEAD -> master)
Author: …
Date:   …

    inlined

diff --git a a
index …..… 100644
--- a
+++ a
@@ -1 +1,100 @@
-#include b
+00
+01
+02
+03
+04
+05
…
+95
+96
+97
+98
+99
diff --git b b
deleted file mode 100644
index …..0000000
--- b
+++ /dev/null
@@ -1,100 +0,0 @@
-00
-01
-02
-03
-04
-05
…
-95
-96
-97
-98
-99

Есть ли способ отображения это изменение как то, что я намеревался - удаление a в сочетании с переходом от b к a - но как коммит атоми c, поскольку промежуточное состояние недопустимо?

В частности Я забочусь о том, как это будет представлено GitHub в целях проверки кода.

В более общем смысле, я могу немного отредактировать большой файл после перемещения (небольшая часть его строк), и я бы хотел хотите, чтобы diff отображал только эти изменения в верхней части перемещения, как Git сделал бы автоматически, если бы не произошло переименование в ранее существовавший путь к файлу. На самом деле, настоящие правки будут потеряны в шуме.

1 Ответ

1 голос
/ 07 января 2020

К сожалению, нет: Git (и GitHub) обнаружение переименования основано на том, что имя файла в левом коммите не найдено вообще в правом коммите, а некоторые файлы в коммит с правой стороны не найден вообще при коммите с левой стороны.

То есть, если у нас есть это:

left        right
-----       -----
fileA       fileA
fileB
            fileC
fileD       fileD

, то единственными кандидатами на переименование являются и . Файлы считаются «тем же файлом» (в паре или «идентифицированы» как глагол 1 ) , поскольку они имеют одинаковый путь и аналогичные файлы были идентифицированы по имени, оставив только B и C непарными.

Когда вы запускаете git diff (или git show или все, что вызывает git diff внутри) вручную, вы можете добавьте параметр -B, который позволяет вам «прервать» предварительно объявленное сопряжение на основе имени пути, если файлы достаточно различаются. 2 Таким образом, в командной строке вы можете возможно достичь того, что вы хотите. Но GitHub не предлагает вам вариант -B.


1 То есть Git на данный момент касается проблемы метафизики идентичности . См. Корабль Тесея . Является ли версия X некоторого файла "тем же файлом", что и версия Y этого файла? Откуда мы знаем?

2 Опция -B принимает два числа, оба из которых в конечном итоге выражаются в процентах индекса сходства. Первоначальные пары на основе имен предварительно разбиваются на отдельные «удалить старый файл левой стороны» и «добавить новый файл правой стороны», если индекс сходства содержимого двух файлов падает ниже порогового значения. Затем они становятся кандидатами на обнаружение переименования при условии, что -M включено (возможно, через diff.renames, который теперь является значением по умолчанию true вместо false по умолчанию). Если при обнаружении переименования не удаляются ни одна, ни обе пары, они будут объединены, если только индекс сходства не упадет ниже второго, обычно более мягкого, порога.

Аргументы -B цифра c выражается в виде dis - сходства, а не сходства, но отличие версии X файла F от версии Y файла F составляет просто 100 минус сходство.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...