another commit will be marked with a `?` in the blame output. If the
`blame.markUnblamableLines` config option is set, then those lines touched
by an ignored commit that we could not attribute to another revision are
- marked with a '*'.
+ marked with a '*'. In the porcelain modes, we print 'ignored' and
+ 'unblamable' on a newline respectively.
--ignore-revs-file <file>::
Ignore revisions listed in `file`, which must be in the same format as an
The porcelain format generally suppresses commit information that has
already been seen. For example, two lines that are blamed to the same
commit will both be shown, but the details for that commit will be shown
-only once. This is more efficient, but may require more state be kept by
-the reader. The `--line-porcelain` option can be used to output full
-commit information for each line, allowing simpler (but less efficient)
-usage like:
+only once. Information which is specific to individual lines will not be
+grouped together, like revs to be marked 'ignored' or 'unblamable'. This
+is more efficient, but may require more state be kept by the reader. The
+`--line-porcelain` option can be used to output full commit information
+for each line, allowing simpler (but less efficient) usage like:
# count the number of lines attributed to each author
git blame --line-porcelain file |
write_filename_info(suspect);
}
+/*
+ * Information which needs to be printed per-line goes here. Any
+ * information which can be clubbed on a commit/file level, should
+ * be printed via 'emit_one_suspect_detail()'.
+ */
+static void emit_porcelain_per_line_details(struct blame_entry *ent)
+{
+ if (mark_unblamable_lines && ent->unblamable)
+ puts("unblamable");
+ if (mark_ignored_lines && ent->ignored)
+ puts("ignored");
+}
+
static void emit_porcelain(struct blame_scoreboard *sb, struct blame_entry *ent,
int opt)
{
ent->lno + 1,
ent->num_lines);
emit_porcelain_details(suspect, repeat);
+ emit_porcelain_per_line_details(ent);
cp = blame_nth_line(sb, ent->lno);
for (cnt = 0; cnt < ent->num_lines; cnt++) {
ent->lno + 1 + cnt);
if (repeat)
emit_porcelain_details(suspect, 1);
+ emit_porcelain_per_line_details(ent);
}
putchar('\t');
do {
test_cmp expect actual
'
+for opt in --porcelain --line-porcelain
+do
+ test_expect_success "mark_unblamable_lines with $opt" "
+ sha=$(git rev-parse Y) &&
+
+ git -c blame.markUnblamableLines=false blame $opt --ignore-rev Y file >raw &&
+ cat > sedscript <<- 'EOF' &&
+ /^ y3/i\\
+ unblamable
+ /^ y4/i\\
+ unblamable
+ EOF
+ sed -f sedscript raw >expect &&
+
+ git -c blame.markUnblamableLines=true blame $opt --ignore-rev Y file >actual &&
+ test_cmp expect actual
+ "
+done
+
# Commit Z will touch the first two lines. Y touched all four.
# A--B--X--Y--Z
# The blame output when ignoring Z should be:
! test_cmp expect actual
'
+for opt in --porcelain --line-porcelain
+do
+ test_expect_success "mark_ignored_lines with $opt" "
+ sha=$(git rev-parse Y) &&
+
+ git -c blame.markIgnoredLines=false blame $opt --ignore-rev Z file >raw &&
+ cat > sedscript <<- 'EOF' &&
+ /^ line-one-Z/i\\
+ ignored
+ /^ line-two-Z/i\\
+ ignored
+ EOF
+ sed -f sedscript raw >expect &&
+
+ git -c blame.markIgnoredLines=true blame $opt --ignore-rev Z file >actual &&
+ test_cmp expect actual
+ "
+done
+
# For ignored revs that added 'unblamable' lines and more recent commits changed
# the blamable lines, mark the unblamable lines with a
# '*'