mirror of
https://github.com/git/git
synced 2024-08-28 20:20:07 +00:00
git-apply: require -p<n> when working in a subdirectory.
git-apply running inside a subdirectory, with or without --index, used to always assume that the patch is formatted in such a way to apply with -p1 from the toplevel, but it is more useful and consistent with the use of "GNU patch -p1" if it defaulted to assume that its input is meant to apply at the level it is invoked in. This changes the behaviour. It used to be that the patch generated this way would apply without any trick: edit Documentation/Makefile git diff >patch.file cd Documentation git apply ../patch.file You need to give an explicit -p2 to git-apply now. On the other hand, if you got a patch from somebody else who did not follow "patch is to apply from the top with -p1" convention, the input patch would start with: diff -u Makefile.old Makefile --- Makefile.old +++ Makefile and in such a case, you can apply it with: git apply -p0 patch.file Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
aea1945744
commit
56185f49d0
|
@ -238,7 +238,7 @@ static int name_terminate(const char *name, int namelen, int c, int terminate)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static char * find_name(const char *line, char *def, int p_value, int terminate)
|
||||
static char *find_name(const char *line, char *def, int p_value, int terminate)
|
||||
{
|
||||
int len;
|
||||
const char *start = line;
|
||||
|
@ -362,7 +362,7 @@ static int gitdiff_hdrend(const char *line, struct patch *patch)
|
|||
static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, const char *oldnew)
|
||||
{
|
||||
if (!orig_name && !isnull)
|
||||
return find_name(line, NULL, 1, TERM_TAB);
|
||||
return find_name(line, NULL, p_value, TERM_TAB);
|
||||
|
||||
if (orig_name) {
|
||||
int len;
|
||||
|
@ -372,7 +372,7 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,
|
|||
len = strlen(name);
|
||||
if (isnull)
|
||||
die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
|
||||
another = find_name(line, NULL, 1, TERM_TAB);
|
||||
another = find_name(line, NULL, p_value, TERM_TAB);
|
||||
if (!another || memcmp(another, name, len))
|
||||
die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
|
||||
free(another);
|
||||
|
@ -427,28 +427,28 @@ static int gitdiff_newfile(const char *line, struct patch *patch)
|
|||
static int gitdiff_copysrc(const char *line, struct patch *patch)
|
||||
{
|
||||
patch->is_copy = 1;
|
||||
patch->old_name = find_name(line, NULL, 0, 0);
|
||||
patch->old_name = find_name(line, NULL, p_value-1, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gitdiff_copydst(const char *line, struct patch *patch)
|
||||
{
|
||||
patch->is_copy = 1;
|
||||
patch->new_name = find_name(line, NULL, 0, 0);
|
||||
patch->new_name = find_name(line, NULL, p_value-1, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gitdiff_renamesrc(const char *line, struct patch *patch)
|
||||
{
|
||||
patch->is_rename = 1;
|
||||
patch->old_name = find_name(line, NULL, 0, 0);
|
||||
patch->old_name = find_name(line, NULL, p_value-1, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gitdiff_renamedst(const char *line, struct patch *patch)
|
||||
{
|
||||
patch->is_rename = 1;
|
||||
patch->new_name = find_name(line, NULL, 0, 0);
|
||||
patch->new_name = find_name(line, NULL, p_value-1, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2499,15 +2499,26 @@ static int use_patch(struct patch *p)
|
|||
return 0;
|
||||
x = x->next;
|
||||
}
|
||||
if (0 < prefix_length) {
|
||||
int pathlen = strlen(pathname);
|
||||
if (pathlen <= prefix_length ||
|
||||
memcmp(prefix, pathname, prefix_length))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *prefix_one(char *name)
|
||||
{
|
||||
if (!name)
|
||||
return name;
|
||||
return xstrdup(prefix_filename(prefix, prefix_length, name));
|
||||
}
|
||||
|
||||
static void prefix_patches(struct patch *p)
|
||||
{
|
||||
if (!prefix)
|
||||
return;
|
||||
for ( ; p; p = p->next) {
|
||||
p->new_name = prefix_one(p->new_name);
|
||||
p->old_name = prefix_one(p->old_name);
|
||||
}
|
||||
}
|
||||
|
||||
static int apply_patch(int fd, const char *filename, int inaccurate_eof)
|
||||
{
|
||||
unsigned long offset, size;
|
||||
|
@ -2530,11 +2541,14 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
|
|||
break;
|
||||
if (apply_in_reverse)
|
||||
reverse_patches(patch);
|
||||
if (prefix)
|
||||
prefix_patches(patch);
|
||||
if (use_patch(patch)) {
|
||||
patch_stats(patch);
|
||||
*listp = patch;
|
||||
listp = &patch->next;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* perhaps free it a bit better? */
|
||||
free(patch);
|
||||
skipped_patch++;
|
||||
|
|
|
@ -10,20 +10,22 @@ test_description='git-apply --whitespace=strip and configuration file.
|
|||
. ./test-lib.sh
|
||||
|
||||
test_expect_success setup '
|
||||
echo A >file1 &&
|
||||
cp file1 saved &&
|
||||
git add file1 &&
|
||||
echo "B " >file1 &&
|
||||
mkdir sub &&
|
||||
echo A >sub/file1 &&
|
||||
cp sub/file1 saved &&
|
||||
git add sub/file1 &&
|
||||
echo "B " >sub/file1 &&
|
||||
git diff >patch.file
|
||||
'
|
||||
|
||||
test_expect_success 'apply --whitespace=strip' '
|
||||
|
||||
cp saved file1 &&
|
||||
rm -f sub/file1 &&
|
||||
cp saved sub/file1 &&
|
||||
git update-index --refresh &&
|
||||
|
||||
git apply --whitespace=strip patch.file &&
|
||||
if grep " " file1
|
||||
if grep " " sub/file1
|
||||
then
|
||||
echo "Eh?"
|
||||
false
|
||||
|
@ -34,12 +36,13 @@ test_expect_success 'apply --whitespace=strip' '
|
|||
|
||||
test_expect_success 'apply --whitespace=strip from config' '
|
||||
|
||||
cp saved file1 &&
|
||||
rm -f sub/file1 &&
|
||||
cp saved sub/file1 &&
|
||||
git update-index --refresh &&
|
||||
|
||||
git config apply.whitespace strip &&
|
||||
git apply patch.file &&
|
||||
if grep " " file1
|
||||
if grep " " sub/file1
|
||||
then
|
||||
echo "Eh?"
|
||||
false
|
||||
|
@ -48,19 +51,19 @@ test_expect_success 'apply --whitespace=strip from config' '
|
|||
fi
|
||||
'
|
||||
|
||||
mkdir sub
|
||||
D=`pwd`
|
||||
|
||||
test_expect_success 'apply --whitespace=strip in subdir' '
|
||||
|
||||
cd "$D" &&
|
||||
git config --unset-all apply.whitespace
|
||||
cp saved file1 &&
|
||||
rm -f sub/file1 &&
|
||||
cp saved sub/file1 &&
|
||||
git update-index --refresh &&
|
||||
|
||||
cd sub &&
|
||||
git apply --whitespace=strip ../patch.file &&
|
||||
if grep " " ../file1
|
||||
git apply --whitespace=strip -p2 ../patch.file &&
|
||||
if grep " " file1
|
||||
then
|
||||
echo "Eh?"
|
||||
false
|
||||
|
@ -73,11 +76,12 @@ test_expect_success 'apply --whitespace=strip from config in subdir' '
|
|||
|
||||
cd "$D" &&
|
||||
git config apply.whitespace strip &&
|
||||
cp saved file1 &&
|
||||
rm -f sub/file1 &&
|
||||
cp saved sub/file1 &&
|
||||
git update-index --refresh &&
|
||||
|
||||
cd sub &&
|
||||
git apply ../patch.file &&
|
||||
git apply -p2 ../patch.file &&
|
||||
if grep " " file1
|
||||
then
|
||||
echo "Eh?"
|
||||
|
|
Loading…
Reference in a new issue