diff: --{rotate,skip}-to=<path>
In the implementation of "git difftool", there is a case where the
user wants to start viewing the diffs at a specific path and
continue on to the rest, optionally wrapping around to the
beginning. Since it is somewhat cumbersome to implement such a
feature as a post-processing step of "git diff" output, let's
support it internally with two new options.
- "git diff --rotate-to=C", when the resulting patch would show
paths A B C D E without the option, would "rotate" the paths to
shows patch to C D E A B instead. It is an error when there is
no patch for C is shown.
- "git diff --skip-to=C" would instead "skip" the paths before C,
and shows patch to C D E. Again, it is an error when there is no
patch for C is shown.
- "git log [-p]" also accepts these two options, but it is not an
error if there is no change to the specified path. Instead, the
set of output paths are rotated or skipped to the specified path
or the first path that sorts after the specified path.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-02-11 20:57:50 +01:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2021, Google LLC.
|
|
|
|
* Based on diffcore-order.c, which is Copyright (C) 2005, Junio C Hamano
|
|
|
|
*/
|
2023-02-24 01:09:34 +01:00
|
|
|
#include "git-compat-util.h"
|
|
|
|
#include "gettext.h"
|
diff: --{rotate,skip}-to=<path>
In the implementation of "git difftool", there is a case where the
user wants to start viewing the diffs at a specific path and
continue on to the rest, optionally wrapping around to the
beginning. Since it is somewhat cumbersome to implement such a
feature as a post-processing step of "git diff" output, let's
support it internally with two new options.
- "git diff --rotate-to=C", when the resulting patch would show
paths A B C D E without the option, would "rotate" the paths to
shows patch to C D E A B instead. It is an error when there is
no patch for C is shown.
- "git diff --skip-to=C" would instead "skip" the paths before C,
and shows patch to C D E. Again, it is an error when there is no
patch for C is shown.
- "git log [-p]" also accepts these two options, but it is not an
error if there is no change to the specified path. Instead, the
set of output paths are rotated or skipped to the specified path
or the first path that sorts after the specified path.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-02-11 20:57:50 +01:00
|
|
|
#include "diff.h"
|
|
|
|
#include "diffcore.h"
|
|
|
|
|
|
|
|
void diffcore_rotate(struct diff_options *opt)
|
|
|
|
{
|
|
|
|
struct diff_queue_struct *q = &diff_queued_diff;
|
|
|
|
struct diff_queue_struct outq;
|
|
|
|
int rotate_to, i;
|
|
|
|
|
|
|
|
if (!q->nr)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < q->nr; i++) {
|
|
|
|
int cmp = strcmp(opt->rotate_to, q->queue[i]->two->path);
|
|
|
|
if (!cmp)
|
|
|
|
break; /* exact match */
|
|
|
|
if (!opt->rotate_to_strict && cmp < 0)
|
|
|
|
break; /* q->queue[i] is now past the target pathname */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (q->nr <= i) {
|
|
|
|
/* we did not find the specified path */
|
|
|
|
if (opt->rotate_to_strict)
|
|
|
|
die(_("No such path '%s' in the diff"), opt->rotate_to);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
DIFF_QUEUE_CLEAR(&outq);
|
|
|
|
rotate_to = i;
|
|
|
|
|
|
|
|
for (i = rotate_to; i < q->nr; i++)
|
|
|
|
diff_q(&outq, q->queue[i]);
|
|
|
|
for (i = 0; i < rotate_to; i++) {
|
|
|
|
if (opt->skip_instead_of_rotate)
|
|
|
|
diff_free_filepair(q->queue[i]);
|
|
|
|
else
|
|
|
|
diff_q(&outq, q->queue[i]);
|
|
|
|
}
|
|
|
|
free(q->queue);
|
|
|
|
*q = outq;
|
|
|
|
}
|