TL; DR: попробуйте git apply -p2 ...
.
Описание
Настройка справа не совсем понятна мне из вашего сообщения, поэтому я покажу свою настройку :
$ mkdir tpatch
$ cd tpatch
$ mkdir -p 20140902/Documents 20141227/Documents
$ printf 'binary\0stuff' > 20140902/Documents/foo
$ printf 'different\0binary' > 20141227/Documents/foo
$ git diff --no-index --binary 20140902/ 20141227/ > 01.diff
(Результирующий патч действительно GIT binary patch
благодаря NUL в выходных данных printf
выше, хотя у меня есть два literal
вместо delta
.)
Далее я создал репозиторий в каталоге current
. Если ваш репозиторий находится на другом уровне, вам может потребоваться другое значение -p
:
$ mkdir current; cd current; git init
Initialized empty Git repository in .../tmp/tpatch/current/.git/
$ cp -r ../20140902/Documents .
$ ls
Documents
$ git add . && git commit -m initial
[master (root-commit) ee60bbe] initial
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 Documents/foo
Обратите внимание, что на этом этапе я получаю ту же ошибку с простым git apply
, потому что удаление a/
from diff оставляет Git с 20140902/Documents/foo
, а не Documents/foo
:
$ git apply ../01.diff
error: git diff header lacks filename information when removing 1 leading pathname component (line 3)
Однако, используя -p2
, мы говорим Git удалить два компонентов ( a/20140902/
) из пути, после которого имя файла Documents/foo
совпадает с именем файла в репозитории и рабочем дереве:
$ git apply -p2 ../01.diff
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: Documents/foo
no changes added to commit (use "git add" and/or "git commit -a")
Если у вас более сложная ситуация, вам может потребоваться --src-prefix
и / или --dst-prefix
в команде git diff
в первую очередь, но, вероятно, только -p2
подойдет.