* [PATCH 1/4] git-apply.txt: remove a space
2016-03-24 11:56 ` Nguyễn Thái Ngọc Duy
@ 2016-03-24 11:56 ` Nguyễn Thái Ngọc Duy
2016-03-24 11:56 ` [PATCH 2/4] git-apply.txt: mention the behavior inside a subdir Nguyễn Thái Ngọc Duy
` (3 subsequent siblings)
4 siblings, 0 replies; 18+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2016-03-24 11:56 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, sbeller, mehul.jain2029, sandals,
Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-apply.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt
index d9ed6a1..5444d2f 100644
--- a/Documentation/git-apply.txt
+++ b/Documentation/git-apply.txt
@@ -13,7 +13,7 @@ SYNOPSIS
[--apply] [--no-add] [--build-fake-ancestor=<file>] [-R | --reverse]
[--allow-binary-replacement | --binary] [--reject] [-z]
[-p<n>] [-C<n>] [--inaccurate-eof] [--recount] [--cached]
- [--ignore-space-change | --ignore-whitespace ]
+ [--ignore-space-change | --ignore-whitespace]
[--whitespace=(nowarn|warn|fix|error|error-all)]
[--exclude=<path>] [--include=<path>] [--directory=<root>]
[--verbose] [--unsafe-paths] [<patch>...]
--
2.8.0.rc0.210.gd302cd2
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 2/4] git-apply.txt: mention the behavior inside a subdir
2016-03-24 11:56 ` Nguyễn Thái Ngọc Duy
2016-03-24 11:56 ` [PATCH 1/4] git-apply.txt: remove a space Nguyễn Thái Ngọc Duy
@ 2016-03-24 11:56 ` Nguyễn Thái Ngọc Duy
2016-03-24 11:56 ` [PATCH 3/4] apply: add --whole to apply git patch without prefix filtering Nguyễn Thái Ngọc Duy
` (2 subsequent siblings)
4 siblings, 0 replies; 18+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2016-03-24 11:56 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, sbeller, mehul.jain2029, sandals,
Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-apply.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt
index 5444d2f..8ddb207 100644
--- a/Documentation/git-apply.txt
+++ b/Documentation/git-apply.txt
@@ -21,6 +21,8 @@ SYNOPSIS
DESCRIPTION
-----------
Reads the supplied diff output (i.e. "a patch") and applies it to files.
+When running from a subdirectory in a repository, patched paths
+outside the directory are ignored.
With the `--index` option the patch is also applied to the index, and
with the `--cached` option the patch is only applied to the index.
Without these options, the command applies the patch only to files,
--
2.8.0.rc0.210.gd302cd2
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 3/4] apply: add --whole to apply git patch without prefix filtering
2016-03-24 11:56 ` Nguyễn Thái Ngọc Duy
2016-03-24 11:56 ` [PATCH 1/4] git-apply.txt: remove a space Nguyễn Thái Ngọc Duy
2016-03-24 11:56 ` [PATCH 2/4] git-apply.txt: mention the behavior inside a subdir Nguyễn Thái Ngọc Duy
@ 2016-03-24 11:56 ` Nguyễn Thái Ngọc Duy
2016-03-24 11:56 ` [PATCH 4/4] apply: report patch skipping in verbose mode Nguyễn Thái Ngọc Duy
2016-03-24 16:50 ` git-apply does not work in a sub-directory of a Git repository Junio C Hamano
4 siblings, 0 replies; 18+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2016-03-24 11:56 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, sbeller, mehul.jain2029, sandals,
Nguyễn Thái Ngọc Duy
Back in edf2e37 (git-apply: work from subdirectory. - 2005-11-25),
git-apply is made to work from a subdir of a worktree. When applying a
git patch this way, only paths in the subdir are patched, the rest is
filtered out. To apply without filtering, the user has to move back to
toplevel. Add --whole to make it more convenient to do so without moving
cwd around.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-apply.txt | 8 +++++++-
builtin/apply.c | 4 +++-
t/t4111-apply-subdir.sh | 32 ++++++++++++++++++++++++++++++++
3 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt
index 8ddb207..47cea57 100644
--- a/Documentation/git-apply.txt
+++ b/Documentation/git-apply.txt
@@ -13,7 +13,7 @@ SYNOPSIS
[--apply] [--no-add] [--build-fake-ancestor=<file>] [-R | --reverse]
[--allow-binary-replacement | --binary] [--reject] [-z]
[-p<n>] [-C<n>] [--inaccurate-eof] [--recount] [--cached]
- [--ignore-space-change | --ignore-whitespace]
+ [--ignore-space-change | --ignore-whitespace] [--whole]
[--whitespace=(nowarn|warn|fix|error|error-all)]
[--exclude=<path>] [--include=<path>] [--directory=<root>]
[--verbose] [--unsafe-paths] [<patch>...]
@@ -154,6 +154,12 @@ discouraged.
flag was the way to do so. Currently we always allow binary
patch application, so this is a no-op.
+--whole::
+ Normally when running inside a subdirectory of a working area,
+ patched files outside current directory is filtered out. This option
+ makes `git apply` to apply them all. All paths are still subject
+ to `--exclude` and `--include` fitlering if present.
+
--exclude=<path-pattern>::
Don't apply changes to files matching the given path pattern. This can
be useful when importing patchsets, where you want to exclude certain
diff --git a/builtin/apply.c b/builtin/apply.c
index 42c610e..01e1d5e 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -80,6 +80,7 @@ static const char *patch_input_file;
static struct strbuf root = STRBUF_INIT;
static int read_stdin = 1;
static int options;
+static int apply_whole;
static void parse_whitespace_option(const char *option)
{
@@ -1956,7 +1957,7 @@ static int use_patch(struct patch *p)
int i;
/* Paths outside are not touched regardless of "--include" */
- if (0 < prefix_length) {
+ if (!apply_whole && 0 < prefix_length) {
int pathlen = strlen(pathname);
if (pathlen <= prefix_length ||
memcmp(prefix, pathname, prefix_length))
@@ -4565,6 +4566,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)
OPT_BIT(0, "recount", &options,
N_("do not trust the line counts in the hunk headers"),
RECOUNT),
+ OPT_BOOL(0, "whole", &apply_whole, N_("apply whole patch")),
{ OPTION_CALLBACK, 0, "directory", NULL, N_("root"),
N_("prepend <root> to all filenames"),
0, option_parse_directory },
diff --git a/t/t4111-apply-subdir.sh b/t/t4111-apply-subdir.sh
index 1618a6d..e5cd019 100755
--- a/t/t4111-apply-subdir.sh
+++ b/t/t4111-apply-subdir.sh
@@ -153,4 +153,36 @@ test_expect_success 'apply --cached from subdir of .git dir' '
test_cmp expected.subdir actual.subdir
'
+test_expect_success 'setup a git patch' '
+ cat >gitpatch <<-\EOF &&
+ diff --git a/file b/file
+ --- a/file
+ +++ b/file
+ @@ -1 +1,2 @@
+ 1
+ +2
+ EOF
+ gitpatch="$(pwd)/gitpatch"
+'
+
+test_expect_success 'apply a git patch from subdir of toplevel' '
+ reset_subdir other preimage &&
+ (
+ cd sub/dir &&
+ git apply "$gitpatch"
+ ) &&
+ test_cmp preimage sub/dir/file &&
+ test_cmp preimage file
+'
+
+test_expect_success 'apply the whole git patch from subdir of toplevel' '
+ reset_subdir other preimage &&
+ (
+ cd sub/dir &&
+ git apply --whole "$gitpatch"
+ ) &&
+ test_cmp preimage sub/dir/file &&
+ test_cmp postimage file
+'
+
test_done
--
2.8.0.rc0.210.gd302cd2
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 4/4] apply: report patch skipping in verbose mode
2016-03-24 11:56 ` Nguyễn Thái Ngọc Duy
` (2 preceding siblings ...)
2016-03-24 11:56 ` [PATCH 3/4] apply: add --whole to apply git patch without prefix filtering Nguyễn Thái Ngọc Duy
@ 2016-03-24 11:56 ` Nguyễn Thái Ngọc Duy
2016-03-24 16:50 ` git-apply does not work in a sub-directory of a Git repository Junio C Hamano
4 siblings, 0 replies; 18+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2016-03-24 11:56 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, sbeller, mehul.jain2029, sandals,
Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
builtin/apply.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/builtin/apply.c b/builtin/apply.c
index 01e1d5e..9cbb186 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -4384,6 +4384,8 @@ static int apply_patch(int fd, const char *filename, int options)
listp = &patch->next;
}
else {
+ if (apply_verbosely)
+ say_patch_name(stderr, _("Skipped patch '%s'."), patch);
free_patch(patch);
skipped_patch++;
}
--
2.8.0.rc0.210.gd302cd2
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: git-apply does not work in a sub-directory of a Git repository
2016-03-24 11:56 ` Nguyễn Thái Ngọc Duy
` (3 preceding siblings ...)
2016-03-24 11:56 ` [PATCH 4/4] apply: report patch skipping in verbose mode Nguyễn Thái Ngọc Duy
@ 2016-03-24 16:50 ` Junio C Hamano
2016-03-24 17:32 ` Junio C Hamano
` (2 more replies)
4 siblings, 3 replies; 18+ messages in thread
From: Junio C Hamano @ 2016-03-24 16:50 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy
Cc: git, sbeller, mehul.jain2029, sandals
Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
>> On Wed, Mar 23, 2016 at 11:55 PM, Junio C Hamano <gitster@pobox.com> wrote:
>>> The include/exclude mechanism does use wildmatch() but does not use
>>> the pathspec mechanism (it predates the pathspec machinery that was
>>> made reusable in places like this). We should be able to
>>>
>>> $ cd d/e/e/p/d/i/r
>>> $ git apply --include=:/ ../../../../../../../patch
>>>
>>> to lift this limitation. IOW, we can think of the use_patch() to
>>> include only the paths in the subdirectory we are in by default, but
>>> we can make it allow --include/--exclude command line option to
>>> override that default.
>
> I went with a new option instead of changing --include.
It might be a "workable" band-aid, but would be an unsatisfying UI
if it were the endgame state. You do not say "git grep --whole" (by
the way, "whole" is a bad option name, as you cannot tell "100% of
*what*" you are referring to--what you are widening is the limit
based on the location in the directory structure, so the option name
should have some hint about it, e.g. "full-tree" or something) and
this command will become an odd-man-out.
I haven't thought things through, but thinking out aloud a few
points...
An existing user/script may be working in a subdirectory of a huge
working tree and relies on the current behaviour that outside world
is excluded by default, and may be passing --exclude to further
limit the extent of damage by applying the patch to a subset of
paths in the current directory that itself is also huge. And that
use case would not be harmed by such a change.
On the other hand, an existing user/script would not be passing an
"--include" that names outside the current subdirectory to force
them to be included, because it is known for the past 10 years not
to have any effect at all.
So a better alternative may be to conditionally disable the "Paths
outside are not touched regardless of --include" logic, i.e. we
exclude paths outside by default just as before, but if there is at
least one explicit "--include" given, we skip this "return 0".
That way, we do not have to commit to turning --include/--exclude to
pathspec (which I agree is a huge change in behaviour that may not
be a good idea) and we do not have to add "--full-tree" that is only
understood by "apply" but not other commands that operate on the
current directory by default.
I agree that the "excluded because the path is outside cwd" should
be reported just like we show notices when applying a hunk with
offset, and that the "excluded because the path is outside cwd"
should be documented.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: git-apply does not work in a sub-directory of a Git repository
2016-03-24 16:50 ` git-apply does not work in a sub-directory of a Git repository Junio C Hamano
@ 2016-03-24 17:32 ` Junio C Hamano
2016-03-30 1:05 ` Duy Nguyen
2016-03-30 9:33 ` Duy Nguyen
2 siblings, 0 replies; 18+ messages in thread
From: Junio C Hamano @ 2016-03-24 17:32 UTC (permalink / raw)
To: Nguyễn Thái Ngọc Duy
Cc: git, sbeller, mehul.jain2029, sandals
Junio C Hamano <gitster@pobox.com> writes:
> So a better alternative may be to conditionally disable the "Paths
> outside are not touched regardless of --include" logic, i.e. we
> exclude paths outside by default just as before, but if there is at
> least one explicit "--include" given, we skip this "return 0".
>
> That way, we do not have to commit to turning --include/--exclude to
> pathspec (which I agree is a huge change in behaviour that may not
> be a good idea) and we do not have to add "--full-tree" that is only
> understood by "apply" but not other commands that operate on the
> current directory by default.
And the necessary change to do so may look like this. With this:
$ git show >P
$ git reset --hard HEAD^
$ cd t
$ git apply -v ../P
$ git apply -v --include=\* ../P
seem to work as expected.
diff --git a/builtin/apply.c b/builtin/apply.c
index c993333..1af3f7e 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -1955,8 +1955,8 @@ static int use_patch(struct patch *p)
const char *pathname = p->new_name ? p->new_name : p->old_name;
int i;
- /* Paths outside are not touched regardless of "--include" */
- if (0 < prefix_length) {
+ /* Paths outside are not touched when there is no explicit "--include" */
+ if (!has_include && 0 < prefix_length) {
int pathlen = strlen(pathname);
if (pathlen <= prefix_length ||
memcmp(prefix, pathname, prefix_length))
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: git-apply does not work in a sub-directory of a Git repository
2016-03-24 16:50 ` git-apply does not work in a sub-directory of a Git repository Junio C Hamano
2016-03-24 17:32 ` Junio C Hamano
@ 2016-03-30 1:05 ` Duy Nguyen
2016-03-30 17:13 ` Junio C Hamano
2016-03-30 9:33 ` Duy Nguyen
2 siblings, 1 reply; 18+ messages in thread
From: Duy Nguyen @ 2016-03-30 1:05 UTC (permalink / raw)
To: Junio C Hamano
Cc: Git Mailing List, Stefan Beller, Mehul Jain, brian m. carlson
On Thu, Mar 24, 2016 at 11:50 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Nguyễn Thái Ngọc Duy <pclouds@gmail.com> writes:
>
>>> On Wed, Mar 23, 2016 at 11:55 PM, Junio C Hamano <gitster@pobox.com> wrote:
>>>> The include/exclude mechanism does use wildmatch() but does not use
>>>> the pathspec mechanism (it predates the pathspec machinery that was
>>>> made reusable in places like this). We should be able to
>>>>
>>>> $ cd d/e/e/p/d/i/r
>>>> $ git apply --include=:/ ../../../../../../../patch
>>>>
>>>> to lift this limitation. IOW, we can think of the use_patch() to
>>>> include only the paths in the subdirectory we are in by default, but
>>>> we can make it allow --include/--exclude command line option to
>>>> override that default.
>>
>> I went with a new option instead of changing --include.
>
> It might be a "workable" band-aid, but would be an unsatisfying UI
> if it were the endgame state. You do not say "git grep --whole" (by
> the way, "whole" is a bad option name, as you cannot tell "100% of
> *what*" you are referring to--what you are widening is the limit
> based on the location in the directory structure, so the option name
> should have some hint about it, e.g. "full-tree" or something) and
> this command will become an odd-man-out.
>
> I haven't thought things through, but thinking out aloud a few
> points...
>
> An existing user/script may be working in a subdirectory of a huge
> working tree and relies on the current behaviour that outside world
> is excluded by default, and may be passing --exclude to further
> limit the extent of damage by applying the patch to a subset of
> paths in the current directory that itself is also huge. And that
> use case would not be harmed by such a change.
>
> On the other hand, an existing user/script would not be passing an
> "--include" that names outside the current subdirectory to force
> them to be included, because it is known for the past 10 years not
> to have any effect at all.
Real-world .gitignore patterns have taught me that even if it does not
have any effect, it might still be present in some scripts, waiting
for a chance to bite me.
> So a better alternative may be to conditionally disable the "Paths
> outside are not touched regardless of --include" logic, i.e. we
> exclude paths outside by default just as before, but if there is at
> least one explicit "--include" given, we skip this "return 0".
>
> That way, we do not have to commit to turning --include/--exclude to
> pathspec (which I agree is a huge change in behaviour that may not
> be a good idea) and we do not have to add "--full-tree" that is only
> understood by "apply" but not other commands that operate on the
> current directory by default.
But your suggestion is good and I can't think of any better. We could
introduce pathspec as ftiler after "--", but it does not look elegant,
and it overlaps with --include/--exclude.
Perhaps we can start to warn people if --include is specified but has
no effect for a cycle or two, then we can do as you suggested?
--
Duy
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: git-apply does not work in a sub-directory of a Git repository
2016-03-30 1:05 ` Duy Nguyen
@ 2016-03-30 17:13 ` Junio C Hamano
0 siblings, 0 replies; 18+ messages in thread
From: Junio C Hamano @ 2016-03-30 17:13 UTC (permalink / raw)
To: Duy Nguyen; +Cc: Git Mailing List, Stefan Beller, Mehul Jain, brian m. carlson
Duy Nguyen <pclouds@gmail.com> writes:
> But your suggestion is good and I can't think of any better. We could
> introduce pathspec as ftiler after "--", but it does not look elegant,
> and it overlaps with --include/--exclude.
I was imagining that we would allow the magic pathspec syntax used
in --include/--exclude command line option parameter. Nobody sane
uses glob special characters in their pathnames and those that do
deserve whatever breakage that comes to them.
> Perhaps we can start to warn people if --include is specified but has
> no effect for a cycle or two, then we can do as you suggested?
I do not think I'd be against going in that direction.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: git-apply does not work in a sub-directory of a Git repository
2016-03-24 16:50 ` git-apply does not work in a sub-directory of a Git repository Junio C Hamano
2016-03-24 17:32 ` Junio C Hamano
2016-03-30 1:05 ` Duy Nguyen
@ 2016-03-30 9:33 ` Duy Nguyen
2 siblings, 0 replies; 18+ messages in thread
From: Duy Nguyen @ 2016-03-30 9:33 UTC (permalink / raw)
To: Junio C Hamano
Cc: Git Mailing List, Stefan Beller, Mehul Jain, brian m. carlson
On Thu, Mar 24, 2016 at 11:50 PM, Junio C Hamano <gitster@pobox.com> wrote:
> So a better alternative may be to conditionally disable the "Paths
> outside are not touched regardless of --include" logic, i.e. we
> exclude paths outside by default just as before, but if there is at
> least one explicit "--include" given, we skip this "return 0".
>
> That way, we do not have to commit to turning --include/--exclude to
> pathspec (which I agree is a huge change in behaviour that may not
> be a good idea) and we do not have to add "--full-tree" that is only
> understood by "apply" but not other commands that operate on the
> current directory by default.
Suppose I don't like git-apply's default behavior, I make an alias.ap
= "apply --include=*". So far so good, but when I want to limit paths
back to "subdir" (it does not have to be the same as cwd), how do I do
it without typing resorting to typing "git apply" explicitly ? I don't
see an option to cancel out --include=*. For "git ap --exclude=*
--include=subdir" to have that effect, we need to change
for (i = 0; i < limit_by_name.nr; i++) {
in use_patch() to
for (i = limit_by_name.nr - 1; i >= 0; i--) {
Simple change, but not exactly harmless.
Off topic, but --include/--exclude should be able to deal with
relative path like --include=../*.c or --include=./*. I guess nobody
has complained about it, so it's not needed.
--
Duy
^ permalink raw reply [flat|nested] 18+ messages in thread