{"thread":{"id":"28193","subject":"Behaviour of git apply --directory","startedAt":"2011-08-22T15:21:55Z","lastAt":"2011-08-24T14:26:21Z","messageCount":3,"participants":["Andrew Berry","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"174022","messageId":"E21BC0F8-2DF0-44AB-B18A-013451CDB670@sentex.net","threadId":"28193","inReplyTo":null,"subject":"Behaviour of git apply --directory","fromName":"Andrew Berry","fromEmail":"andrewberry@sentex.net","sentAt":"2011-08-22T15:21:55Z","receivedAt":"2011-08-22T15:21:55Z","isPatch":false,"sender":{"key":"andrewberry@sentex.net","avatar":null},"body":"Hi,\n\nThe behaviour of git apply --directory seems a little confusing. It looks to be dependent on the current directory, but I can't use relative paths to apply a patch in one directory to a sibling directory. Absolute paths don't work either. I'd expected the parameter to either be relative to the git repository root, or to expand relative directories.\n\nAny thoughts?\n\n--Andrew"},{"id":"174031","messageId":"7vfwktwbbb.fsf@alter.siamese.dyndns.org","threadId":"28193","inReplyTo":"E21BC0F8-2DF0-44AB-B18A-013451CDB670@sentex.net","subject":"Re: Behaviour of git apply --directory","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-22T18:28:08Z","receivedAt":"2011-08-22T18:28:08Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andrew Berry <andrewberry@sentex.net> writes:\n\n> The behaviour of git apply --directory seems a little confusing. It\n> looks to be dependent on the current directory, but I can't use relative\n> paths to apply a patch in one directory to a sibling directory. Absolute\n> paths don't work either. I'd expected the parameter to either be\n> relative to the git repository root, or to expand relative directories.\n\nI do not think that parameter does not have anything to do with your\ncwd. As the documentation says:\n\n  --directory=<root>::\n          Prepend <root> to all filenames.  If a \"-p\" argument was also passed,\n          it is applied before prepending the new root.\n\n  For example, a patch that talks about updating `a/git-gui.sh` to `b/git-gui.sh`\n  can be applied to the file in the working tree `modules/git-gui/git-gui.sh` by\n  running `git apply --directory=modules/git-gui`.\n\nthe parameter is just a fixed string that is used to modify the path that\nappears in the patch before it gets applied, and has nothing to do with\nyour current (or previous for that matter) working directory.\n\nSuppose you have a patch that tries to update \"COPYING\". Such a patch\ngenerated by Git would look like this:\n\n    diff --git a/COPYING b/COPYING\n    index 536e555..ee559b1 100644\n    --- a/COPYING\n    +++ b/COPYING\n    @@ -1,3 +1,4 @@\n    +GPL GPL GPL\n\n      Note that the only valid version of the GPL as far as this project\n      is concerned is _this_ particular version of the license (ie v2, not\n\n\nFurther suppose that you have already rearranged your project so that that\nfile appears in licenses/gpl directory, and your $(cwd) is licenses/\nsubdirectory of your working tree.\n\nYou would give --directory=licenses/gpl/ without passing any custom -p\nparameter. This internally turns the patch being applied into something\nlike:\n\n    diff --git a/licenses/gpl/COPYING b/licenses/gpl/COPYING\n    index 536e555..ee559b1 100644\n    --- a/licenses/gpl/COPYING\n    +++ b/licenses/gpl/COPYING\n    @@ -1,3 +1,4 @@\n    +GPL GPL GPL\n\n      Note that the only valid version of the GPL as far as this project\n      is concerned is _this_ particular version of the license (ie v2, not\n\nBecause the patch application in git is always relative to the top level\nof your working tree no matter where you are, this applies to the path you\nintended it to.\n\nHere is a sample transcript to try it yourself.\n\n    $ (echo GPL GPL GPL; cat COPYING) >x && cat x >COPYING\n    $ git diff >P.diff\n    $ git checkout COPYING\n    $ mkdir -p licenses/gpl\n    $ git mv COPYING licenses/gpl\n    $ cd licenses\n    $ git apply -v --directory=licenses/gpl ../P.diff\n    Checking patch licenses/gpl/COPYING...\n    Applied patch licenses/gpl/COPYING cleanly.\n    $ git diff\n    diff --git a/licenses/gpl/COPYING b/licenses/gpl/COPYING\n    index 536e555..ee559b1 100644\n    --- a/licenses/gpl/COPYING\n    +++ b/licenses/gpl/COPYING\n    @@ -1,3 +1,4 @@\n    +GPL GPL GPL\n\n      Note that the only valid version of the GPL as far as this project\n      is concerned is _this_ particular version of the license (ie v2, not\n"},{"id":"174154","messageId":"5FC87CBA-13C9-4FAD-80C1-66B3550C9EBB@sentex.net","threadId":"28193","inReplyTo":"7vfwktwbbb.fsf@alter.siamese.dyndns.org","subject":"Re: Behaviour of git apply --directory","fromName":"Andrew Berry","fromEmail":"andrewberry@sentex.net","sentAt":"2011-08-24T14:26:21Z","receivedAt":"2011-08-24T14:26:21Z","isPatch":false,"sender":{"key":"andrewberry@sentex.net","avatar":null},"body":"Thanks for your detailed explanation.\n\nOn 2011-08-22, at 2:28 PM, Junio C Hamano wrote:\n\n> Because the patch application in git is always relative to the top level\n> of your working tree no matter where you are, this applies to the path you\n> intended it to.\n\nThis is where I see the issue. For some reason when I specify --directory, I do have to be somewhere in the directory tree that the patch is going to be applied to. For example, in the following it works if my cwd is the repository root, or src, but not patches.\n\n$ find . -not -path '*.git*'\n.\n./patches\n./patches/LICENSE.patch\n./src\n./src/LICENSE.txt\n$ git status\n# On branch master\nnothing to commit (working directory clean)\n$ cat patches/LICENSE.patch \ndiff --git a/LICENSE.txt b/LICENSE.txt\nindex 2c095c8..64ee213 100644\n--- a/LICENSE.txt\n+++ b/LICENSE.txt\n@@ -1,3 +1,4 @@\n+GPL GPL GPL\n GNU GENERAL PUBLIC LICENSE\n \n               Version 2, June 1991\n$ cd patches\n$ git apply -v --directory=src LICENSE.patch\n$ git status\n# On branch master\nnothing to commit (working directory clean)\n$ cd ..\n$ git apply -v --directory=src patches/LICENSE.patch\nChecking patch src/LICENSE.txt...\nApplied patch src/LICENSE.txt cleanly.\n$ git status\n# On branch master\n# Changes not staged for commit:\n#   (use \"git add <file>...\" to update what will be committed)\n#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n#\n#\tmodified:   src/LICENSE.txt\n#\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\n$ git checkout src\n$ cd src\n$ git apply -v --directory=src ../patches/LICENSE.patch\nChecking patch src/LICENSE.txt...\nApplied patch src/LICENSE.txt cleanly.\n$ git status\n# On branch master\n# Changes not staged for commit:\n#   (use \"git add <file>...\" to update what will be committed)\n#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n#\n#\tmodified:   LICENSE.txt\n#\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\n\n"}]}