git-apply: notice "diff --git" patch again
Earlier one that tried to be too consistent with GNU patch by not stripping the leading path when we _know_ we are in a subdirectory and the patch is relative to the toplevel was a mistake. This fixes it. - No change to behaviour when it is run from the toplevel of the repository. - When run from a subdirectory to apply a git-generated patch, it uses the right -p<n> value automatically, with or without --index nor --cached option. - When run from a subdirectory to apply a randomly generated patch, it wants the right -p<n> value to be given by the user. The second one is a pure improvement to correct inconsistency between --index and non --index case, compared with 1.5.0. The third point could be further improved to guess what the right value for -p<n> should be by looking at the patch, but should be a topic of a separate patch. Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
6c912f5b04
commit
9987d7c58a
@ -144,6 +144,7 @@ struct patch {
|
|||||||
unsigned long deflate_origlen;
|
unsigned long deflate_origlen;
|
||||||
int lines_added, lines_deleted;
|
int lines_added, lines_deleted;
|
||||||
int score;
|
int score;
|
||||||
|
unsigned int is_toplevel_relative:1;
|
||||||
unsigned int inaccurate_eof:1;
|
unsigned int inaccurate_eof:1;
|
||||||
unsigned int is_binary:1;
|
unsigned int is_binary:1;
|
||||||
unsigned int is_copy:1;
|
unsigned int is_copy:1;
|
||||||
@ -362,7 +363,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)
|
static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, const char *oldnew)
|
||||||
{
|
{
|
||||||
if (!orig_name && !isnull)
|
if (!orig_name && !isnull)
|
||||||
return find_name(line, NULL, p_value, TERM_TAB);
|
return find_name(line, NULL, 1, TERM_TAB);
|
||||||
|
|
||||||
if (orig_name) {
|
if (orig_name) {
|
||||||
int len;
|
int len;
|
||||||
@ -372,7 +373,7 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,
|
|||||||
len = strlen(name);
|
len = strlen(name);
|
||||||
if (isnull)
|
if (isnull)
|
||||||
die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
|
die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
|
||||||
another = find_name(line, NULL, p_value, TERM_TAB);
|
another = find_name(line, NULL, 1, TERM_TAB);
|
||||||
if (!another || memcmp(another, name, len))
|
if (!another || memcmp(another, name, len))
|
||||||
die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
|
die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
|
||||||
free(another);
|
free(another);
|
||||||
@ -427,28 +428,28 @@ static int gitdiff_newfile(const char *line, struct patch *patch)
|
|||||||
static int gitdiff_copysrc(const char *line, struct patch *patch)
|
static int gitdiff_copysrc(const char *line, struct patch *patch)
|
||||||
{
|
{
|
||||||
patch->is_copy = 1;
|
patch->is_copy = 1;
|
||||||
patch->old_name = find_name(line, NULL, p_value-1, 0);
|
patch->old_name = find_name(line, NULL, 0, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gitdiff_copydst(const char *line, struct patch *patch)
|
static int gitdiff_copydst(const char *line, struct patch *patch)
|
||||||
{
|
{
|
||||||
patch->is_copy = 1;
|
patch->is_copy = 1;
|
||||||
patch->new_name = find_name(line, NULL, p_value-1, 0);
|
patch->new_name = find_name(line, NULL, 0, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gitdiff_renamesrc(const char *line, struct patch *patch)
|
static int gitdiff_renamesrc(const char *line, struct patch *patch)
|
||||||
{
|
{
|
||||||
patch->is_rename = 1;
|
patch->is_rename = 1;
|
||||||
patch->old_name = find_name(line, NULL, p_value-1, 0);
|
patch->old_name = find_name(line, NULL, 0, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gitdiff_renamedst(const char *line, struct patch *patch)
|
static int gitdiff_renamedst(const char *line, struct patch *patch)
|
||||||
{
|
{
|
||||||
patch->is_rename = 1;
|
patch->is_rename = 1;
|
||||||
patch->new_name = find_name(line, NULL, p_value-1, 0);
|
patch->new_name = find_name(line, NULL, 0, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -787,6 +788,7 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
|
|||||||
{
|
{
|
||||||
unsigned long offset, len;
|
unsigned long offset, len;
|
||||||
|
|
||||||
|
patch->is_toplevel_relative = 0;
|
||||||
patch->is_rename = patch->is_copy = 0;
|
patch->is_rename = patch->is_copy = 0;
|
||||||
patch->is_new = patch->is_delete = -1;
|
patch->is_new = patch->is_delete = -1;
|
||||||
patch->old_mode = patch->new_mode = 0;
|
patch->old_mode = patch->new_mode = 0;
|
||||||
@ -831,6 +833,7 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
|
|||||||
die("git diff header lacks filename information (line %d)", linenr);
|
die("git diff header lacks filename information (line %d)", linenr);
|
||||||
patch->old_name = patch->new_name = patch->def_name;
|
patch->old_name = patch->new_name = patch->def_name;
|
||||||
}
|
}
|
||||||
|
patch->is_toplevel_relative = 1;
|
||||||
*hdrsize = git_hdr_len;
|
*hdrsize = git_hdr_len;
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
@ -2499,6 +2502,12 @@ static int use_patch(struct patch *p)
|
|||||||
return 0;
|
return 0;
|
||||||
x = x->next;
|
x = x->next;
|
||||||
}
|
}
|
||||||
|
if (0 < prefix_length) {
|
||||||
|
int pathlen = strlen(pathname);
|
||||||
|
if (pathlen <= prefix_length ||
|
||||||
|
memcmp(prefix, pathname, prefix_length))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2513,7 +2522,7 @@ static void prefix_one(char **name)
|
|||||||
|
|
||||||
static void prefix_patches(struct patch *p)
|
static void prefix_patches(struct patch *p)
|
||||||
{
|
{
|
||||||
if (!prefix)
|
if (!prefix || p->is_toplevel_relative)
|
||||||
return;
|
return;
|
||||||
for ( ; p; p = p->next) {
|
for ( ; p; p = p->next) {
|
||||||
if (p->new_name == p->old_name) {
|
if (p->new_name == p->old_name) {
|
||||||
|
@ -78,7 +78,7 @@ test_expect_success 'apply --whitespace=strip in subdir' '
|
|||||||
git update-index --refresh &&
|
git update-index --refresh &&
|
||||||
|
|
||||||
cd sub &&
|
cd sub &&
|
||||||
git apply --whitespace=strip -p2 ../patch.file &&
|
git apply --whitespace=strip ../patch.file &&
|
||||||
if grep " " file1
|
if grep " " file1
|
||||||
then
|
then
|
||||||
echo "Eh?"
|
echo "Eh?"
|
||||||
@ -101,7 +101,7 @@ test_expect_success 'apply --whitespace=strip from config in subdir' '
|
|||||||
git update-index --refresh &&
|
git update-index --refresh &&
|
||||||
|
|
||||||
cd sub &&
|
cd sub &&
|
||||||
git apply -p2 ../patch.file &&
|
git apply ../patch.file &&
|
||||||
if grep " " file1
|
if grep " " file1
|
||||||
then
|
then
|
||||||
echo "Eh?"
|
echo "Eh?"
|
||||||
|
Loading…
Reference in New Issue
Block a user