зеркало из https://github.com/microsoft/git.git
git-pickaxe: split find_origin() into find_rename() and find_origin().
When a merge adds a new file from the second parent, the earlier code tried to find renames in the first parent before noticing that the vertion from the second parent was added without modification. Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Родитель
ae86ad6575
Коммит
f69e743d97
|
@ -211,7 +211,6 @@ static struct origin *find_origin(struct scoreboard *sb,
|
|||
{
|
||||
struct origin *porigin = NULL;
|
||||
struct diff_options diff_opts;
|
||||
int i;
|
||||
const char *paths[2];
|
||||
|
||||
/* See if the origin->path is different between parent
|
||||
|
@ -260,10 +259,17 @@ static struct origin *find_origin(struct scoreboard *sb,
|
|||
}
|
||||
}
|
||||
diff_flush(&diff_opts);
|
||||
if (porigin)
|
||||
return porigin;
|
||||
return porigin;
|
||||
}
|
||||
|
||||
/* Otherwise we would look for a rename */
|
||||
static struct origin *find_rename(struct scoreboard *sb,
|
||||
struct commit *parent,
|
||||
struct origin *origin)
|
||||
{
|
||||
struct origin *porigin = NULL;
|
||||
struct diff_options diff_opts;
|
||||
int i;
|
||||
const char *paths[2];
|
||||
|
||||
diff_setup(&diff_opts);
|
||||
diff_opts.recursive = 1;
|
||||
|
@ -875,34 +881,46 @@ static int find_copy_in_parent(struct scoreboard *sb,
|
|||
|
||||
static void pass_blame(struct scoreboard *sb, struct origin *origin, int opt)
|
||||
{
|
||||
int i;
|
||||
int i, pass;
|
||||
struct commit *commit = origin->commit;
|
||||
struct commit_list *parent;
|
||||
struct origin *parent_origin[MAXPARENT], *porigin;
|
||||
|
||||
memset(parent_origin, 0, sizeof(parent_origin));
|
||||
for (i = 0, parent = commit->parents;
|
||||
i < MAXPARENT && parent;
|
||||
parent = parent->next, i++) {
|
||||
struct commit *p = parent->item;
|
||||
|
||||
if (parse_commit(p))
|
||||
continue;
|
||||
porigin = find_origin(sb, parent->item, origin);
|
||||
if (!porigin)
|
||||
continue;
|
||||
if (!hashcmp(porigin->blob_sha1, origin->blob_sha1)) {
|
||||
struct blame_entry *e;
|
||||
for (e = sb->ent; e; e = e->next)
|
||||
if (e->suspect == origin) {
|
||||
origin_incref(porigin);
|
||||
origin_decref(e->suspect);
|
||||
e->suspect = porigin;
|
||||
}
|
||||
origin_decref(porigin);
|
||||
goto finish;
|
||||
/* The first pass looks for unrenamed path to optimize for
|
||||
* common cases, then we look for renames in the second pass.
|
||||
*/
|
||||
for (pass = 0; pass < 2; pass++) {
|
||||
struct origin *(*find)(struct scoreboard *,
|
||||
struct commit *, struct origin *);
|
||||
find = pass ? find_rename : find_origin;
|
||||
|
||||
for (i = 0, parent = commit->parents;
|
||||
i < MAXPARENT && parent;
|
||||
parent = parent->next, i++) {
|
||||
struct commit *p = parent->item;
|
||||
|
||||
if (parent_origin[i])
|
||||
continue;
|
||||
if (parse_commit(p))
|
||||
continue;
|
||||
porigin = find(sb, parent->item, origin);
|
||||
if (!porigin)
|
||||
continue;
|
||||
if (!hashcmp(porigin->blob_sha1, origin->blob_sha1)) {
|
||||
struct blame_entry *e;
|
||||
for (e = sb->ent; e; e = e->next)
|
||||
if (e->suspect == origin) {
|
||||
origin_incref(porigin);
|
||||
origin_decref(e->suspect);
|
||||
e->suspect = porigin;
|
||||
}
|
||||
origin_decref(porigin);
|
||||
goto finish;
|
||||
}
|
||||
parent_origin[i] = porigin;
|
||||
}
|
||||
parent_origin[i] = porigin;
|
||||
}
|
||||
|
||||
for (i = 0, parent = commit->parents;
|
||||
|
|
Загрузка…
Ссылка в новой задаче