43
static int max_digits;
44
static int max_score_digits;
45
static int show_root;
46
+static int reverse;
47
static int blank_boundary;
48
static int incremental;
49
static int cmd_is_annotate;
178
struct scoreboard {
179
/* the final commit (i.e. where we started digging from) */
180
struct commit *final;
180
-
181
+ struct rev_info *revs;
182
const char *path;
183
184
/*
1197
* "parent" (and "porigin"), but what we mean is to find scapegoat to
1198
* exonerate ourselves.
1199
*/
1199
-static struct commit_list *first_scapegoat(struct commit *commit)
1200
+static struct commit_list *first_scapegoat(struct rev_info *revs, struct commit *commit)
1201
{
1201
- return commit->parents;
1202
+ if (!reverse)
1203
+ return commit->parents;
1204
+ return lookup_decoration(&revs->children, &commit->object);
1205
}
1206
1204
-static int num_scapegoats(struct commit *commit)
1207
+static int num_scapegoats(struct rev_info *revs, struct commit *commit)
1208
{
1209
int cnt;
1207
- struct commit_list *l = first_scapegoat(commit);
1210
+ struct commit_list *l = first_scapegoat(revs, commit);
1211
for (cnt = 0; l; l = l->next)
1212
cnt++;
1213
return cnt;
1217
1218
static void pass_blame(struct scoreboard *sb, struct origin *origin, int opt)
1219
{
1220
+ struct rev_info *revs = sb->revs;
1221
int i, pass, num_sg;
1222
struct commit *commit = origin->commit;
1223
struct commit_list *sg;
1224
struct origin *sg_buf[MAXSG];
1225
struct origin *porigin, **sg_origin = sg_buf;
1226
1223
- num_sg = num_scapegoats(commit);
1227
+ num_sg = num_scapegoats(revs, commit);
1228
if (!num_sg)
1229
goto finish;
1230
else if (num_sg < ARRAY_SIZE(sg_buf))
1241
struct commit *, struct origin *);
1242
find = pass ? find_rename : find_origin;
1243
1240
- for (i = 0, sg = first_scapegoat(commit);
1244
+ for (i = 0, sg = first_scapegoat(revs, commit);
1245
i < num_sg && sg;
1246
sg = sg->next, i++) {
1247
struct commit *p = sg->item;
1274
}
1275
1276
num_commits++;
1273
- for (i = 0, sg = first_scapegoat(commit);
1277
+ for (i = 0, sg = first_scapegoat(revs, commit);
1278
i < num_sg && sg;
1279
sg = sg->next, i++) {
1280
struct origin *porigin = sg_origin[i];
1288
* Optionally find moves in parents' files.
1289
*/
1290
if (opt & PICKAXE_BLAME_MOVE)
1287
- for (i = 0, sg = first_scapegoat(commit);
1291
+ for (i = 0, sg = first_scapegoat(revs, commit);
1292
i < num_sg && sg;
1293
sg = sg->next, i++) {
1294
struct origin *porigin = sg_origin[i];
1302
* Optionally find copies from parents' files.
1303
*/
1304
if (opt & PICKAXE_BLAME_COPY)
1301
- for (i = 0, sg = first_scapegoat(commit);
1305
+ for (i = 0, sg = first_scapegoat(revs, commit);
1306
i < num_sg && sg;
1307
sg = sg->next, i++) {
1308
struct origin *porigin = sg_origin[i];
1519
* is still unknown, pick one blame_entry, and allow its current
1520
* suspect to pass blames to its parents.
1521
*/
1518
-static void assign_blame(struct scoreboard *sb, struct rev_info *revs, int opt)
1522
+static void assign_blame(struct scoreboard *sb, int opt)
1523
{
1524
+ struct rev_info *revs = sb->revs;
1525
+
1526
while (1) {
1527
struct blame_entry *ent;
1528
struct commit *commit;
1543
commit = suspect->commit;
1544
if (!commit->object.parsed)
1545
parse_commit(commit);
1540
- if (!(commit->object.flags & UNINTERESTING) &&
1541
- !(revs->max_age != -1 && commit->date < revs->max_age))
1546
+ if (reverse ||
1547
+ (!(commit->object.flags & UNINTERESTING) &&
1548
+ !(revs->max_age != -1 && commit->date < revs->max_age)))
1549
pass_blame(sb, suspect, opt);
1550
else {
1551
commit->object.flags |= UNINTERESTING;
2161
return commit;
2162
}
2163
2157
-static const char *prepare_final(struct scoreboard *sb, struct rev_info *revs)
2164
+static const char *prepare_final(struct scoreboard *sb)
2165
{
2166
int i;
2167
const char *final_commit_name = NULL;
2168
+ struct rev_info *revs = sb->revs;
2169
2170
/*
2171
* There must be one and only one positive commit in the
2189
return final_commit_name;
2190
}
2191
2192
+static const char *prepare_initial(struct scoreboard *sb)
2193
+{
2194
+ int i;
2195
+ const char *final_commit_name = NULL;
2196
+ struct rev_info *revs = sb->revs;
2197
+
2198
+ /*
2199
+ * There must be one and only one negative commit, and it must be
2200
+ * the boundary.
2201
+ */
2202
+ for (i = 0; i < revs->pending.nr; i++) {
2203
+ struct object *obj = revs->pending.objects[i].item;
2204
+ if (!(obj->flags & UNINTERESTING))
2205
+ continue;
2206
+ while (obj->type == OBJ_TAG)
2207
+ obj = deref_tag(obj, NULL, 0);
2208
+ if (obj->type != OBJ_COMMIT)
2209
+ die("Non commit %s?", revs->pending.objects[i].name);
2210
+ if (sb->final)
2211
+ die("More than one commit to dig down to %s and %s?",
2212
+ revs->pending.objects[i].name,
2213
+ final_commit_name);
2214
+ sb->final = (struct commit *) obj;
2215
+ final_commit_name = revs->pending.objects[i].name;
2216
+ }
2217
+ if (!final_commit_name)
2218
+ die("No commit to dig down to?");
2219
+ return final_commit_name;
2220
+}
2221
+
2222
int cmd_blame(int argc, const char **argv, const char *prefix)
2223
{
2224
struct rev_info revs;
2251
blank_boundary = 1;
2252
else if (!strcmp("--root", arg))
2253
show_root = 1;
2254
+ else if (!strcmp("--reverse", arg)) {
2255
+ argv[unk++] = "--children";
2256
+ reverse = 1;
2257
+ }
2258
else if (!strcmp(arg, "--show-stats"))
2259
show_stats = 1;
2260
else if (!strcmp("-c", arg))
2428
setup_revisions(unk, argv, &revs, NULL);
2429
memset(&sb, 0, sizeof(sb));
2430
2389
- final_commit_name = prepare_final(&sb, &revs);
2431
+ sb.revs = &revs;
2432
+ if (!reverse)
2433
+ final_commit_name = prepare_final(&sb);
2434
+ else if (contents_from)
2435
+ die("--contents and --children do not blend well.");
2436
+ else
2437
+ final_commit_name = prepare_initial(&sb);
2438
+
2439
if (!sb.final) {
2440
/*
2441
* "--not A B -- path" without anything positive;
2513
if (!incremental)
2514
setup_pager();
2515
2467
- assign_blame(&sb, &revs, opt);
2516
+ assign_blame(&sb, opt);
2517
2518
if (incremental)
2519
return 0;