Не работает ли git apply -p (удаление начального sla sh) для переименований? - PullRequest
0 голосов
/ 12 июля 2020

Вот простой файл различий из git diff --no-index --no-prefix dir1 dir2 > dir.diff:

diff --git dir1/file1.txt dir2/file1.txt
index 45b983b..ce01362 100644
--- dir1/file1.txt
+++ dir2/file1.txt
@@ -1 +1 @@
-hi
+hello
diff --git dir1/file2.txt dir2/file2_rename.txt
similarity index 100%
rename from dir1/file2.txt
rename to dir2/file2_rename.txt
diff --git dir1/file3.txt dir1/file3.txt
deleted file mode 100644
index b1a17ba..0000000
--- dir1/file3.txt
+++ /dev/null
@@ -1 +0,0 @@
-zzz
diff --git dir2/file4.txt dir2/file4.txt
new file mode 100644
index 0000000..f761ec1
--- /dev/null
+++ dir2/file4.txt
@@ -0,0 +1 @@
+bbb

Как видите, file1.txt изменен, file2.txt переименован, file3.txt удален, а file4.txt добавлен.

Теперь, когда я пытаюсь применить патч:

cp -r dir1 dir_work
cd dir_work
git apply -v ../dir.diff

, я получаю следующий подробный вывод, указывающий, что патч не удался при переименовании файла2: (патч отлично работает без файла2)

Checking patch file1.txt...
Checking patch dir1/file2.txt => dir2/file2_rename.txt...
error: dir1/file2.txt: No such file or directory
Checking patch file3.txt...
Checking patch file4.txt...

Итак, для file1, file3, file4 ведущие каталоги (dir1/... и dir2/...) были удалены (-p1 - git apply по умолчанию), но не для переименования? Как удалить начальный каталог для file2?

1 Ответ

1 голос
/ 13 июля 2020

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

rename from dir1/file2.txt
rename to dir2/file2_rename.txt

, которые, как вы можете видеть, включают dir1/ и dir2/ части, но не a/ или b/ части. Это все равно будет так, даже если вы не использовали --no-prefix в команде git diff.

В конце концов, git apply опция -p1, которая обычно удаляет только a/ и b/ теперь удаляет dir1/ и dir2/ из других строк diff, но ничего не делает с этими двумя строками. Внутри git apply удаляет на один префиксов меньше, чем git apply, как правило:

static int gitdiff_renamesrc(struct gitdiff_data *state,
                             const char *line,
                             struct patch *patch)
{
        patch->is_rename = 1;
        free(patch->old_name);
        patch->old_name = find_name(state->root, line, NULL,
             state->p_value ? state->p_value - 1 : 0, 0);
        return 0;
}

Используя git diff без --no-prefix и git apply -p2, Git будет таким образом уберите один компонент из этих двух имен. Так что может помочь использование -p2 на шаге apply вместо --no-prefix в команде git diff.

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