Merge branch 'tr/line-log'
* tr/line-log: git-log(1): remove --full-line-diff description line-log: fix documentation formatting log -L: improve comments in process_all_files() log -L: store the path instead of a diff_filespec log -L: test merge of parallel modify/rename t4211: pass -M to 'git log -M -L...' test log -L: fix overlapping input ranges log -L: check range set invariants when we look it up Speed up log -L... -M log -L: :pattern:file syntax to find by funcname Implement line-history search (git log -L) Export rewrite_parents() for 'log -L' Refactor parse_loc
This commit is contained in:
commit
ed73fe5642
@ -9,28 +9,11 @@
|
||||
--show-stats::
|
||||
Include additional statistics at the end of blame output.
|
||||
|
||||
-L <start>,<end>::
|
||||
-L <start>,<end>, -L :<regex>::
|
||||
Annotate only the given line range. <start> and <end> can take
|
||||
one of these forms:
|
||||
|
||||
- number
|
||||
+
|
||||
If <start> or <end> is a number, it specifies an
|
||||
absolute line number (lines count from 1).
|
||||
+
|
||||
|
||||
- /regex/
|
||||
+
|
||||
This form will use the first line matching the given
|
||||
POSIX regex. If <end> is a regex, it will search
|
||||
starting at the line given by <start>.
|
||||
+
|
||||
|
||||
- +offset or -offset
|
||||
+
|
||||
This is only valid for <end> and will specify a number
|
||||
of lines before or after the line given by <start>.
|
||||
+
|
||||
include::line-range-format.txt[]
|
||||
|
||||
-l::
|
||||
Show long rev (Default: off).
|
||||
|
@ -8,9 +8,9 @@ git-blame - Show what revision and author last modified each line of a file
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental] [-L n,m]
|
||||
[-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>] [--abbrev=<n>]
|
||||
[<rev> | --contents <file> | --reverse <rev>] [--] <file>
|
||||
'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental]
|
||||
[-L n,m | -L :fn] [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>]
|
||||
[--abbrev=<n>] [<rev> | --contents <file> | --reverse <rev>] [--] <file>
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
@ -62,6 +62,19 @@ produced by --stat etc.
|
||||
Note that only message is considered, if also a diff is shown
|
||||
its size is not included.
|
||||
|
||||
-L <start>,<end>:<file>, -L :<regex>:<file>::
|
||||
|
||||
Trace the evolution of the line range given by "<start>,<end>"
|
||||
(or the funcname regex <regex>) within the <file>. You may
|
||||
not give any pathspec limiters. This is currently limited to
|
||||
a walk starting from a single revision, i.e., you may only
|
||||
give zero or one positive revision arguments.
|
||||
You can specify this option more than once.
|
||||
+
|
||||
<start> and <end> can take one of these forms:
|
||||
|
||||
include::line-range-format.txt[]
|
||||
|
||||
<revision range>::
|
||||
Show only commits in the specified revision range. When no
|
||||
<revision range> is specified, it defaults to `HEAD` (i.e. the
|
||||
@ -140,6 +153,11 @@ Examples
|
||||
This makes sense only when following a strict policy of merging all
|
||||
topic branches when staying on a single integration branch.
|
||||
|
||||
git log -L '/int main/',/^}/:main.c::
|
||||
|
||||
Shows how the function `main()` in the file 'main.c' evolved
|
||||
over time.
|
||||
|
||||
`git log -3`::
|
||||
Limits the number of commits to show to 3.
|
||||
|
||||
|
25
Documentation/line-range-format.txt
Normal file
25
Documentation/line-range-format.txt
Normal file
@ -0,0 +1,25 @@
|
||||
- number
|
||||
+
|
||||
If <start> or <end> is a number, it specifies an
|
||||
absolute line number (lines count from 1).
|
||||
+
|
||||
|
||||
- /regex/
|
||||
+
|
||||
This form will use the first line matching the given
|
||||
POSIX regex. If <end> is a regex, it will search
|
||||
starting at the line given by <start>.
|
||||
+
|
||||
|
||||
- +offset or -offset
|
||||
+
|
||||
This is only valid for <end> and will specify a number
|
||||
of lines before or after the line given by <start>.
|
||||
+
|
||||
|
||||
- :regex
|
||||
+
|
||||
If the option's argument is of the form :regex, it denotes the range
|
||||
from the first funcname line that matches <regex>, up to the next
|
||||
funcname line.
|
||||
+
|
4
Makefile
4
Makefile
@ -681,6 +681,8 @@ LIB_H += help.h
|
||||
LIB_H += http.h
|
||||
LIB_H += kwset.h
|
||||
LIB_H += levenshtein.h
|
||||
LIB_H += line-log.h
|
||||
LIB_H += line-range.h
|
||||
LIB_H += list-objects.h
|
||||
LIB_H += ll-merge.h
|
||||
LIB_H += log-tree.h
|
||||
@ -808,6 +810,8 @@ LIB_OBJS += hex.o
|
||||
LIB_OBJS += ident.o
|
||||
LIB_OBJS += kwset.o
|
||||
LIB_OBJS += levenshtein.o
|
||||
LIB_OBJS += line-log.o
|
||||
LIB_OBJS += line-range.o
|
||||
LIB_OBJS += list-objects.o
|
||||
LIB_OBJS += ll-merge.o
|
||||
LIB_OBJS += lockfile.o
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "parse-options.h"
|
||||
#include "utf8.h"
|
||||
#include "userdiff.h"
|
||||
#include "line-range.h"
|
||||
|
||||
static char blame_usage[] = N_("git blame [options] [rev-opts] [rev] [--] file");
|
||||
|
||||
@ -566,11 +567,16 @@ static void dup_entry(struct blame_entry *dst, struct blame_entry *src)
|
||||
dst->score = 0;
|
||||
}
|
||||
|
||||
static const char *nth_line(struct scoreboard *sb, int lno)
|
||||
static const char *nth_line(struct scoreboard *sb, long lno)
|
||||
{
|
||||
return sb->final_buf + sb->lineno[lno];
|
||||
}
|
||||
|
||||
static const char *nth_line_cb(void *data, long lno)
|
||||
{
|
||||
return nth_line((struct scoreboard *)data, lno);
|
||||
}
|
||||
|
||||
/*
|
||||
* It is known that lines between tlno to same came from parent, and e
|
||||
* has an overlap with that range. it also is known that parent's
|
||||
@ -1931,83 +1937,6 @@ static const char *add_prefix(const char *prefix, const char *path)
|
||||
return prefix_path(prefix, prefix ? strlen(prefix) : 0, path);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parsing of (comma separated) one item in the -L option
|
||||
*/
|
||||
static const char *parse_loc(const char *spec,
|
||||
struct scoreboard *sb, long lno,
|
||||
long begin, long *ret)
|
||||
{
|
||||
char *term;
|
||||
const char *line;
|
||||
long num;
|
||||
int reg_error;
|
||||
regex_t regexp;
|
||||
regmatch_t match[1];
|
||||
|
||||
/* Allow "-L <something>,+20" to mean starting at <something>
|
||||
* for 20 lines, or "-L <something>,-5" for 5 lines ending at
|
||||
* <something>.
|
||||
*/
|
||||
if (1 < begin && (spec[0] == '+' || spec[0] == '-')) {
|
||||
num = strtol(spec + 1, &term, 10);
|
||||
if (term != spec + 1) {
|
||||
if (spec[0] == '-')
|
||||
num = 0 - num;
|
||||
if (0 < num)
|
||||
*ret = begin + num - 2;
|
||||
else if (!num)
|
||||
*ret = begin;
|
||||
else
|
||||
*ret = begin + num;
|
||||
return term;
|
||||
}
|
||||
return spec;
|
||||
}
|
||||
num = strtol(spec, &term, 10);
|
||||
if (term != spec) {
|
||||
*ret = num;
|
||||
return term;
|
||||
}
|
||||
if (spec[0] != '/')
|
||||
return spec;
|
||||
|
||||
/* it could be a regexp of form /.../ */
|
||||
for (term = (char *) spec + 1; *term && *term != '/'; term++) {
|
||||
if (*term == '\\')
|
||||
term++;
|
||||
}
|
||||
if (*term != '/')
|
||||
return spec;
|
||||
|
||||
/* try [spec+1 .. term-1] as regexp */
|
||||
*term = 0;
|
||||
begin--; /* input is in human terms */
|
||||
line = nth_line(sb, begin);
|
||||
|
||||
if (!(reg_error = regcomp(®exp, spec + 1, REG_NEWLINE)) &&
|
||||
!(reg_error = regexec(®exp, line, 1, match, 0))) {
|
||||
const char *cp = line + match[0].rm_so;
|
||||
const char *nline;
|
||||
|
||||
while (begin++ < lno) {
|
||||
nline = nth_line(sb, begin);
|
||||
if (line <= cp && cp < nline)
|
||||
break;
|
||||
line = nline;
|
||||
}
|
||||
*ret = begin;
|
||||
regfree(®exp);
|
||||
*term++ = '/';
|
||||
return term;
|
||||
}
|
||||
else {
|
||||
char errbuf[1024];
|
||||
regerror(reg_error, ®exp, errbuf, 1024);
|
||||
die("-L parameter '%s': %s", spec + 1, errbuf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parsing of -L option
|
||||
*/
|
||||
@ -2016,15 +1945,7 @@ static void prepare_blame_range(struct scoreboard *sb,
|
||||
long lno,
|
||||
long *bottom, long *top)
|
||||
{
|
||||
const char *term;
|
||||
|
||||
term = parse_loc(bottomtop, sb, lno, 1, bottom);
|
||||
if (*term == ',') {
|
||||
term = parse_loc(term + 1, sb, lno, *bottom + 1, top);
|
||||
if (*term)
|
||||
usage(blame_usage);
|
||||
}
|
||||
if (*term)
|
||||
if (parse_range_arg(bottomtop, nth_line_cb, sb, lno, bottom, top, sb->path))
|
||||
usage(blame_usage);
|
||||
}
|
||||
|
||||
@ -2574,10 +2495,6 @@ parse_done:
|
||||
bottom = top = 0;
|
||||
if (bottomtop)
|
||||
prepare_blame_range(&sb, bottomtop, lno, &bottom, &top);
|
||||
if (bottom && top && top < bottom) {
|
||||
long tmp;
|
||||
tmp = top; top = bottom; bottom = tmp;
|
||||
}
|
||||
if (bottom < 1)
|
||||
bottom = 1;
|
||||
if (top < 1)
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "remote.h"
|
||||
#include "string-list.h"
|
||||
#include "parse-options.h"
|
||||
#include "line-log.h"
|
||||
#include "branch.h"
|
||||
#include "streaming.h"
|
||||
#include "version.h"
|
||||
@ -42,6 +43,12 @@ static const char * const builtin_log_usage[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
struct line_opt_callback_data {
|
||||
struct rev_info *rev;
|
||||
const char *prefix;
|
||||
struct string_list args;
|
||||
};
|
||||
|
||||
static int parse_decoration_style(const char *var, const char *value)
|
||||
{
|
||||
switch (git_config_maybe_bool(var, value)) {
|
||||
@ -76,6 +83,19 @@ static int decorate_callback(const struct option *opt, const char *arg, int unse
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int log_line_range_callback(const struct option *option, const char *arg, int unset)
|
||||
{
|
||||
struct line_opt_callback_data *data = option->value;
|
||||
|
||||
if (!arg)
|
||||
return -1;
|
||||
|
||||
data->rev->line_level_traverse = 1;
|
||||
string_list_append(&data->args, arg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cmd_log_init_defaults(struct rev_info *rev)
|
||||
{
|
||||
if (fmt_pretty)
|
||||
@ -98,6 +118,7 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
|
||||
{
|
||||
struct userformat_want w;
|
||||
int quiet = 0, source = 0, mailmap = 0;
|
||||
static struct line_opt_callback_data line_cb = {NULL, NULL, STRING_LIST_INIT_DUP};
|
||||
|
||||
const struct option builtin_log_options[] = {
|
||||
OPT_BOOL(0, "quiet", &quiet, N_("suppress diff output")),
|
||||
@ -105,9 +126,15 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
|
||||
OPT_BOOL(0, "use-mailmap", &mailmap, N_("Use mail map file")),
|
||||
{ OPTION_CALLBACK, 0, "decorate", NULL, NULL, N_("decorate options"),
|
||||
PARSE_OPT_OPTARG, decorate_callback},
|
||||
OPT_CALLBACK('L', NULL, &line_cb, "n,m:file",
|
||||
"Process line range n,m in file, counting from 1",
|
||||
log_line_range_callback),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
line_cb.rev = rev;
|
||||
line_cb.prefix = prefix;
|
||||
|
||||
mailmap = use_mailmap_config;
|
||||
argc = parse_options(argc, argv, prefix,
|
||||
builtin_log_options, builtin_log_usage,
|
||||
@ -161,6 +188,10 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
|
||||
rev->show_decorations = 1;
|
||||
load_ref_decorations(decoration_style);
|
||||
}
|
||||
|
||||
if (rev->line_level_traverse)
|
||||
line_log_init(rev, line_cb.prefix, &line_cb.args);
|
||||
|
||||
setup_pager();
|
||||
}
|
||||
|
||||
|
1273
line-log.c
Normal file
1273
line-log.c
Normal file
File diff suppressed because it is too large
Load Diff
53
line-log.h
Normal file
53
line-log.h
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef LINE_LOG_H
|
||||
#define LINE_LOG_H
|
||||
|
||||
#include "diffcore.h"
|
||||
|
||||
struct rev_info;
|
||||
struct commit;
|
||||
|
||||
/* A range [start,end]. Lines are numbered starting at 0, and the
|
||||
* ranges include start but exclude end. */
|
||||
struct range {
|
||||
long start, end;
|
||||
};
|
||||
|
||||
/* A set of ranges. The ranges must always be disjoint and sorted. */
|
||||
struct range_set {
|
||||
int alloc, nr;
|
||||
struct range *ranges;
|
||||
};
|
||||
|
||||
/* A diff, encoded as the set of pre- and post-image ranges where the
|
||||
* files differ. A pair of ranges corresponds to a hunk. */
|
||||
struct diff_ranges {
|
||||
struct range_set parent;
|
||||
struct range_set target;
|
||||
};
|
||||
|
||||
/* Linked list of interesting files and their associated ranges. The
|
||||
* list must be kept sorted by path.
|
||||
*
|
||||
* For simplicity, even though this is highly redundant, each
|
||||
* line_log_data owns its 'path'.
|
||||
*/
|
||||
struct line_log_data {
|
||||
struct line_log_data *next;
|
||||
char *path;
|
||||
char status;
|
||||
struct range_set ranges;
|
||||
int arg_alloc, arg_nr;
|
||||
const char **args;
|
||||
struct diff_filepair *pair;
|
||||
struct diff_ranges diff;
|
||||
};
|
||||
|
||||
extern void line_log_data_init(struct line_log_data *r);
|
||||
|
||||
extern void line_log_init(struct rev_info *rev, const char *prefix, struct string_list *args);
|
||||
|
||||
extern int line_log_filter(struct rev_info *rev);
|
||||
|
||||
extern int line_log_print(struct rev_info *rev, struct commit *commit);
|
||||
|
||||
#endif /* LINE_LOG_H */
|
243
line-range.c
Normal file
243
line-range.c
Normal file
@ -0,0 +1,243 @@
|
||||
#include "git-compat-util.h"
|
||||
#include "line-range.h"
|
||||
#include "xdiff-interface.h"
|
||||
#include "strbuf.h"
|
||||
#include "userdiff.h"
|
||||
|
||||
/*
|
||||
* Parse one item in the -L option
|
||||
*/
|
||||
static const char *parse_loc(const char *spec, nth_line_fn_t nth_line,
|
||||
void *data, long lines, long begin, long *ret)
|
||||
{
|
||||
char *term;
|
||||
const char *line;
|
||||
long num;
|
||||
int reg_error;
|
||||
regex_t regexp;
|
||||
regmatch_t match[1];
|
||||
|
||||
/* Allow "-L <something>,+20" to mean starting at <something>
|
||||
* for 20 lines, or "-L <something>,-5" for 5 lines ending at
|
||||
* <something>.
|
||||
*/
|
||||
if (1 < begin && (spec[0] == '+' || spec[0] == '-')) {
|
||||
num = strtol(spec + 1, &term, 10);
|
||||
if (term != spec + 1) {
|
||||
if (!ret)
|
||||
return term;
|
||||
if (spec[0] == '-')
|
||||
num = 0 - num;
|
||||
if (0 < num)
|
||||
*ret = begin + num - 2;
|
||||
else if (!num)
|
||||
*ret = begin;
|
||||
else
|
||||
*ret = begin + num;
|
||||
return term;
|
||||
}
|
||||
return spec;
|
||||
}
|
||||
num = strtol(spec, &term, 10);
|
||||
if (term != spec) {
|
||||
if (ret)
|
||||
*ret = num;
|
||||
return term;
|
||||
}
|
||||
if (spec[0] != '/')
|
||||
return spec;
|
||||
|
||||
/* it could be a regexp of form /.../ */
|
||||
for (term = (char *) spec + 1; *term && *term != '/'; term++) {
|
||||
if (*term == '\\')
|
||||
term++;
|
||||
}
|
||||
if (*term != '/')
|
||||
return spec;
|
||||
|
||||
/* in the scan-only case we are not interested in the regex */
|
||||
if (!ret)
|
||||
return term+1;
|
||||
|
||||
/* try [spec+1 .. term-1] as regexp */
|
||||
*term = 0;
|
||||
begin--; /* input is in human terms */
|
||||
line = nth_line(data, begin);
|
||||
|
||||
if (!(reg_error = regcomp(®exp, spec + 1, REG_NEWLINE)) &&
|
||||
!(reg_error = regexec(®exp, line, 1, match, 0))) {
|
||||
const char *cp = line + match[0].rm_so;
|
||||
const char *nline;
|
||||
|
||||
while (begin++ < lines) {
|
||||
nline = nth_line(data, begin);
|
||||
if (line <= cp && cp < nline)
|
||||
break;
|
||||
line = nline;
|
||||
}
|
||||
*ret = begin;
|
||||
regfree(®exp);
|
||||
*term++ = '/';
|
||||
return term;
|
||||
}
|
||||
else {
|
||||
char errbuf[1024];
|
||||
regerror(reg_error, ®exp, errbuf, 1024);
|
||||
die("-L parameter '%s': %s", spec + 1, errbuf);
|
||||
}
|
||||
}
|
||||
|
||||
static int match_funcname(xdemitconf_t *xecfg, const char *bol, const char *eol)
|
||||
{
|
||||
if (xecfg) {
|
||||
char buf[1];
|
||||
return xecfg->find_func(bol, eol - bol, buf, 1,
|
||||
xecfg->find_func_priv) >= 0;
|
||||
}
|
||||
|
||||
if (bol == eol)
|
||||
return 0;
|
||||
if (isalpha(*bol) || *bol == '_' || *bol == '$')
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *find_funcname_matching_regexp(xdemitconf_t *xecfg, const char *start,
|
||||
regex_t *regexp)
|
||||
{
|
||||
int reg_error;
|
||||
regmatch_t match[1];
|
||||
while (1) {
|
||||
const char *bol, *eol;
|
||||
reg_error = regexec(regexp, start, 1, match, 0);
|
||||
if (reg_error == REG_NOMATCH)
|
||||
return NULL;
|
||||
else if (reg_error) {
|
||||
char errbuf[1024];
|
||||
regerror(reg_error, regexp, errbuf, 1024);
|
||||
die("-L parameter: regexec() failed: %s", errbuf);
|
||||
}
|
||||
/* determine extent of line matched */
|
||||
bol = start+match[0].rm_so;
|
||||
eol = start+match[0].rm_eo;
|
||||
while (bol > start && *bol != '\n')
|
||||
bol--;
|
||||
if (*bol == '\n')
|
||||
bol++;
|
||||
while (*eol && *eol != '\n')
|
||||
eol++;
|
||||
if (*eol == '\n')
|
||||
eol++;
|
||||
/* is it a funcname line? */
|
||||
if (match_funcname(xecfg, (char*) bol, (char*) eol))
|
||||
return bol;
|
||||
start = eol;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *parse_range_funcname(const char *arg, nth_line_fn_t nth_line_cb,
|
||||
void *cb_data, long lines, long *begin, long *end,
|
||||
const char *path)
|
||||
{
|
||||
char *pattern;
|
||||
const char *term;
|
||||
struct userdiff_driver *drv;
|
||||
xdemitconf_t *xecfg = NULL;
|
||||
const char *start;
|
||||
const char *p;
|
||||
int reg_error;
|
||||
regex_t regexp;
|
||||
|
||||
assert(*arg == ':');
|
||||
term = arg+1;
|
||||
while (*term && *term != ':') {
|
||||
if (*term == '\\' && *(term+1))
|
||||
term++;
|
||||
term++;
|
||||
}
|
||||
if (term == arg+1)
|
||||
return NULL;
|
||||
if (!begin) /* skip_range_arg case */
|
||||
return term;
|
||||
|
||||
pattern = xstrndup(arg+1, term-(arg+1));
|
||||
|
||||
start = nth_line_cb(cb_data, 0);
|
||||
|
||||
drv = userdiff_find_by_path(path);
|
||||
if (drv && drv->funcname.pattern) {
|
||||
const struct userdiff_funcname *pe = &drv->funcname;
|
||||
xecfg = xcalloc(1, sizeof(*xecfg));
|
||||
xdiff_set_find_func(xecfg, pe->pattern, pe->cflags);
|
||||
}
|
||||
|
||||
reg_error = regcomp(®exp, pattern, REG_NEWLINE);
|
||||
if (reg_error) {
|
||||
char errbuf[1024];
|
||||
regerror(reg_error, ®exp, errbuf, 1024);
|
||||
die("-L parameter '%s': %s", pattern, errbuf);
|
||||
}
|
||||
|
||||
p = find_funcname_matching_regexp(xecfg, (char*) start, ®exp);
|
||||
if (!p)
|
||||
die("-L parameter '%s': no match", pattern);
|
||||
*begin = 0;
|
||||
while (p > nth_line_cb(cb_data, *begin))
|
||||
(*begin)++;
|
||||
|
||||
if (*begin >= lines)
|
||||
die("-L parameter '%s' matches at EOF", pattern);
|
||||
|
||||
*end = *begin+1;
|
||||
while (*end < lines) {
|
||||
const char *bol = nth_line_cb(cb_data, *end);
|
||||
const char *eol = nth_line_cb(cb_data, *end+1);
|
||||
if (match_funcname(xecfg, bol, eol))
|
||||
break;
|
||||
(*end)++;
|
||||
}
|
||||
|
||||
regfree(®exp);
|
||||
free(xecfg);
|
||||
free(pattern);
|
||||
|
||||
/* compensate for 1-based numbering */
|
||||
(*begin)++;
|
||||
|
||||
return term;
|
||||
}
|
||||
|
||||
int parse_range_arg(const char *arg, nth_line_fn_t nth_line_cb,
|
||||
void *cb_data, long lines, long *begin, long *end,
|
||||
const char *path)
|
||||
{
|
||||
if (*arg == ':') {
|
||||
arg = parse_range_funcname(arg, nth_line_cb, cb_data, lines, begin, end, path);
|
||||
if (!arg || *arg)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
arg = parse_loc(arg, nth_line_cb, cb_data, lines, 1, begin);
|
||||
|
||||
if (*arg == ',')
|
||||
arg = parse_loc(arg + 1, nth_line_cb, cb_data, lines, *begin + 1, end);
|
||||
|
||||
if (*arg)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *skip_range_arg(const char *arg)
|
||||
{
|
||||
if (*arg == ':')
|
||||
return parse_range_funcname(arg, NULL, NULL, 0, NULL, NULL, NULL);
|
||||
|
||||
arg = parse_loc(arg, NULL, NULL, 0, -1, NULL);
|
||||
|
||||
if (*arg == ',')
|
||||
arg = parse_loc(arg+1, NULL, NULL, 0, 0, NULL);
|
||||
|
||||
return arg;
|
||||
}
|
36
line-range.h
Normal file
36
line-range.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef LINE_RANGE_H
|
||||
#define LINE_RANGE_H
|
||||
|
||||
/*
|
||||
* Parse one item in an -L begin,end option w.r.t. the notional file
|
||||
* object 'cb_data' consisting of 'lines' lines.
|
||||
*
|
||||
* The 'nth_line_cb' callback is used to determine the start of the
|
||||
* line 'lno' inside the 'cb_data'. The caller is expected to already
|
||||
* have a suitable map at hand to make this a constant-time lookup.
|
||||
*
|
||||
* Returns 0 in case of success and -1 if there was an error. The
|
||||
* actual range is stored in *begin and *end. The counting starts
|
||||
* at 1! In case of error, the caller should show usage message.
|
||||
*/
|
||||
|
||||
typedef const char *(*nth_line_fn_t)(void *data, long lno);
|
||||
|
||||
extern int parse_range_arg(const char *arg,
|
||||
nth_line_fn_t nth_line_cb,
|
||||
void *cb_data, long lines,
|
||||
long *begin, long *end,
|
||||
const char *path);
|
||||
|
||||
/*
|
||||
* Scan past a range argument that could be parsed by
|
||||
* 'parse_range_arg', to help the caller determine the start of the
|
||||
* filename in '-L n,m:file' syntax.
|
||||
*
|
||||
* Returns a pointer to the first character after the 'n,m' part, or
|
||||
* NULL in case the argument is obviously malformed.
|
||||
*/
|
||||
|
||||
extern const char *skip_range_arg(const char *arg);
|
||||
|
||||
#endif /* LINE_RANGE_H */
|
@ -10,6 +10,7 @@
|
||||
#include "color.h"
|
||||
#include "gpg-interface.h"
|
||||
#include "sequencer.h"
|
||||
#include "line-log.h"
|
||||
|
||||
struct decoration name_decoration = { "object names" };
|
||||
|
||||
@ -796,6 +797,9 @@ int log_tree_commit(struct rev_info *opt, struct commit *commit)
|
||||
log.parent = NULL;
|
||||
opt->loginfo = &log;
|
||||
|
||||
if (opt->line_level_traverse)
|
||||
return line_log_print(opt, commit);
|
||||
|
||||
shown = log_tree_diff(opt, commit, &log);
|
||||
if (!shown && opt->loginfo && opt->always_show_header) {
|
||||
log.parent = NULL;
|
||||
|
22
revision.c
22
revision.c
@ -13,6 +13,7 @@
|
||||
#include "decorate.h"
|
||||
#include "log-tree.h"
|
||||
#include "string-list.h"
|
||||
#include "line-log.h"
|
||||
#include "mailmap.h"
|
||||
|
||||
volatile show_early_output_fn_t show_early_output;
|
||||
@ -1914,6 +1915,12 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
|
||||
if (revs->combine_merges)
|
||||
revs->ignore_merges = 0;
|
||||
revs->diffopt.abbrev = revs->abbrev;
|
||||
|
||||
if (revs->line_level_traverse) {
|
||||
revs->limited = 1;
|
||||
revs->topo_order = 1;
|
||||
}
|
||||
|
||||
diff_setup_done(&revs->diffopt);
|
||||
|
||||
grep_commit_pattern_type(GREP_PATTERN_TYPE_UNSPECIFIED,
|
||||
@ -2185,6 +2192,8 @@ int prepare_revision_walk(struct rev_info *revs)
|
||||
return -1;
|
||||
if (revs->topo_order)
|
||||
sort_in_topological_order(&revs->commits, revs->lifo);
|
||||
if (revs->line_level_traverse)
|
||||
line_log_filter(revs);
|
||||
if (revs->simplify_merges)
|
||||
simplify_merges(revs);
|
||||
if (revs->children.name)
|
||||
@ -2192,12 +2201,6 @@ int prepare_revision_walk(struct rev_info *revs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum rewrite_result {
|
||||
rewrite_one_ok,
|
||||
rewrite_one_noparents,
|
||||
rewrite_one_error
|
||||
};
|
||||
|
||||
static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp)
|
||||
{
|
||||
struct commit_list *cache = NULL;
|
||||
@ -2219,12 +2222,13 @@ static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp
|
||||
}
|
||||
}
|
||||
|
||||
static int rewrite_parents(struct rev_info *revs, struct commit *commit)
|
||||
int rewrite_parents(struct rev_info *revs, struct commit *commit,
|
||||
rewrite_parent_fn_t rewrite_parent)
|
||||
{
|
||||
struct commit_list **pp = &commit->parents;
|
||||
while (*pp) {
|
||||
struct commit_list *parent = *pp;
|
||||
switch (rewrite_one(revs, &parent->item)) {
|
||||
switch (rewrite_parent(revs, &parent->item)) {
|
||||
case rewrite_one_ok:
|
||||
break;
|
||||
case rewrite_one_noparents:
|
||||
@ -2390,7 +2394,7 @@ enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
|
||||
if (action == commit_show &&
|
||||
!revs->show_all &&
|
||||
revs->prune && revs->dense && want_ancestry(revs)) {
|
||||
if (rewrite_parents(revs, commit) < 0)
|
||||
if (rewrite_parents(revs, commit, rewrite_one) < 0)
|
||||
return commit_error;
|
||||
}
|
||||
return action;
|
||||
|
16
revision.h
16
revision.h
@ -97,7 +97,8 @@ struct rev_info {
|
||||
cherry_mark:1,
|
||||
bisect:1,
|
||||
ancestry_path:1,
|
||||
first_parent_only:1;
|
||||
first_parent_only:1,
|
||||
line_level_traverse:1;
|
||||
|
||||
/* Diff flags */
|
||||
unsigned int diff:1,
|
||||
@ -176,6 +177,9 @@ struct rev_info {
|
||||
int count_left;
|
||||
int count_right;
|
||||
int count_same;
|
||||
|
||||
/* line level range that we are chasing */
|
||||
struct decoration line_log_data;
|
||||
};
|
||||
|
||||
#define REV_TREE_SAME 0
|
||||
@ -242,4 +246,14 @@ enum commit_action {
|
||||
extern enum commit_action get_commit_action(struct rev_info *revs, struct commit *commit);
|
||||
extern enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit);
|
||||
|
||||
enum rewrite_result {
|
||||
rewrite_one_ok,
|
||||
rewrite_one_noparents,
|
||||
rewrite_one_error
|
||||
};
|
||||
|
||||
typedef enum rewrite_result (*rewrite_parent_fn_t)(struct rev_info *revs, struct commit **pp);
|
||||
|
||||
extern int rewrite_parents(struct rev_info *revs, struct commit *commit,
|
||||
rewrite_parent_fn_t rewrite_parent);
|
||||
#endif
|
||||
|
34
t/perf/p4211-line-log.sh
Executable file
34
t/perf/p4211-line-log.sh
Executable file
@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='Tests log -L performance'
|
||||
. ./perf-lib.sh
|
||||
|
||||
test_perf_default_repo
|
||||
|
||||
# Pick a file to log pseudo-randomly. The sort key is the blob hash,
|
||||
# so it is stable.
|
||||
test_expect_success 'select a file' '
|
||||
git ls-tree HEAD | grep ^100644 |
|
||||
sort -k 3 | head -1 | cut -f 2 >filelist
|
||||
'
|
||||
|
||||
file=$(cat filelist)
|
||||
export file
|
||||
|
||||
test_perf 'git rev-list --topo-order (baseline)' '
|
||||
git rev-list --topo-order HEAD >/dev/null
|
||||
'
|
||||
|
||||
test_perf 'git log --follow (baseline for -M)' '
|
||||
git log --oneline --follow -- "$file" >/dev/null
|
||||
'
|
||||
|
||||
test_perf 'git log -L' '
|
||||
git log -L 1:"$file" >/dev/null
|
||||
'
|
||||
|
||||
test_perf 'git log -M -L' '
|
||||
git log -M -L 1:"$file" >/dev/null
|
||||
'
|
||||
|
||||
test_done
|
67
t/t4211-line-log.sh
Executable file
67
t/t4211-line-log.sh
Executable file
@ -0,0 +1,67 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='test log -L'
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success 'setup (import history)' '
|
||||
git fast-import < "$TEST_DIRECTORY"/t4211/history.export &&
|
||||
git reset --hard
|
||||
'
|
||||
|
||||
canned_test_1 () {
|
||||
test_expect_$1 "$2" "
|
||||
git log $2 >actual &&
|
||||
test_cmp \"\$TEST_DIRECTORY\"/t4211/expect.$3 actual
|
||||
"
|
||||
}
|
||||
|
||||
canned_test () {
|
||||
canned_test_1 success "$@"
|
||||
}
|
||||
canned_test_failure () {
|
||||
canned_test_1 failure "$@"
|
||||
}
|
||||
|
||||
test_bad_opts () {
|
||||
test_expect_success "invalid args: $1" "
|
||||
test_must_fail git log $1 2>errors &&
|
||||
grep '$2' errors
|
||||
"
|
||||
}
|
||||
|
||||
canned_test "-L 4,12:a.c simple" simple-f
|
||||
canned_test "-L 4,+9:a.c simple" simple-f
|
||||
canned_test "-L '/long f/,/^}/:a.c' simple" simple-f
|
||||
canned_test "-L :f:a.c simple" simple-f-to-main
|
||||
|
||||
canned_test "-L '/main/,/^}/:a.c' simple" simple-main
|
||||
canned_test "-L :main:a.c simple" simple-main-to-end
|
||||
|
||||
canned_test "-L 1,+4:a.c simple" beginning-of-file
|
||||
|
||||
canned_test "-L 20:a.c simple" end-of-file
|
||||
|
||||
canned_test "-L '/long f/',/^}/:a.c -L /main/,/^}/:a.c simple" two-ranges
|
||||
canned_test "-L 24,+1:a.c simple" vanishes-early
|
||||
|
||||
canned_test "-M -L '/long f/,/^}/:b.c' move-support" move-support-f
|
||||
canned_test "-M -L ':f:b.c' parallel-change" parallel-change-f-to-main
|
||||
|
||||
canned_test "-L 4,12:a.c -L :main:a.c simple" multiple
|
||||
canned_test "-L 4,18:a.c -L :main:a.c simple" multiple-overlapping
|
||||
canned_test "-L :main:a.c -L 4,18:a.c simple" multiple-overlapping
|
||||
canned_test "-L 4:a.c -L 8,12:a.c simple" multiple-superset
|
||||
canned_test "-L 8,12:a.c -L 4:a.c simple" multiple-superset
|
||||
|
||||
test_bad_opts "-L" "switch.*requires a value"
|
||||
test_bad_opts "-L b.c" "argument.*not of the form"
|
||||
test_bad_opts "-L 1:" "argument.*not of the form"
|
||||
test_bad_opts "-L 1:nonexistent" "There is no path"
|
||||
test_bad_opts "-L 1:simple" "There is no path"
|
||||
test_bad_opts "-L '/foo:b.c'" "argument.*not of the form"
|
||||
test_bad_opts "-L 1000:b.c" "has only.*lines"
|
||||
test_bad_opts "-L 1,1000:b.c" "has only.*lines"
|
||||
test_bad_opts "-L :b.c" "argument.*not of the form"
|
||||
test_bad_opts "-L :foo:b.c" "no match"
|
||||
|
||||
test_done
|
43
t/t4211/expect.beginning-of-file
Normal file
43
t/t4211/expect.beginning-of-file
Normal file
@ -0,0 +1,43 @@
|
||||
commit 4a23ae5c98d59a58c6da036156959f2dc9f472ad
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:47:40 2013 +0100
|
||||
|
||||
change at very beginning
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -1,3 +1,4 @@
|
||||
+#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
long f(long x)
|
||||
|
||||
commit a6eb82647d5d67f893da442f8f9375fd89a3b1e2
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:45:16 2013 +0100
|
||||
|
||||
touch both functions
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -1,3 +1,3 @@
|
||||
#include <stdio.h>
|
||||
|
||||
-int f(int x)
|
||||
+long f(long x)
|
||||
|
||||
commit de4c48ae814792c02a49c4c3c0c757ae69c55f6a
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:48 2013 +0100
|
||||
|
||||
initial
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- /dev/null
|
||||
+++ b/a.c
|
||||
@@ -0,0 +1,3 @@
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+int f(int x)
|
62
t/t4211/expect.end-of-file
Normal file
62
t/t4211/expect.end-of-file
Normal file
@ -0,0 +1,62 @@
|
||||
commit 4659538844daa2849b1a9e7d6fadb96fcd26fc83
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:48:43 2013 +0100
|
||||
|
||||
change back to complete line
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -20,3 +20,5 @@
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
-}
|
||||
\ No newline at end of file
|
||||
+}
|
||||
+
|
||||
+/* incomplete lines are bad! */
|
||||
|
||||
commit 100b61a6f2f720f812620a9d10afb3a960ccb73c
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:48:10 2013 +0100
|
||||
|
||||
change to an incomplete line at end
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -20,3 +20,3 @@
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
-}
|
||||
+}
|
||||
\ No newline at end of file
|
||||
|
||||
commit a6eb82647d5d67f893da442f8f9375fd89a3b1e2
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:45:16 2013 +0100
|
||||
|
||||
touch both functions
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -19,3 +19,3 @@
|
||||
- printf("%d\n", f(15));
|
||||
+ printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
commit de4c48ae814792c02a49c4c3c0c757ae69c55f6a
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:48 2013 +0100
|
||||
|
||||
initial
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- /dev/null
|
||||
+++ b/a.c
|
||||
@@ -0,0 +18,3 @@
|
||||
+ printf("%d\n", f(15));
|
||||
+ return 0;
|
||||
+}
|
80
t/t4211/expect.move-support-f
Normal file
80
t/t4211/expect.move-support-f
Normal file
@ -0,0 +1,80 @@
|
||||
commit 6ce3c4ff690136099bb17e1a8766b75764726ea7
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:49:50 2013 +0100
|
||||
|
||||
another simple change
|
||||
|
||||
diff --git a/b.c b/b.c
|
||||
--- a/b.c
|
||||
+++ b/b.c
|
||||
@@ -4,9 +4,9 @@
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
- x >>= 1;
|
||||
+ x /= 2;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
commit a6eb82647d5d67f893da442f8f9375fd89a3b1e2
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:45:16 2013 +0100
|
||||
|
||||
touch both functions
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,9 +3,9 @@
|
||||
-int f(int x)
|
||||
+long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
commit f04fb20f2c77850996cba739709acc6faecc58f7
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:55 2013 +0100
|
||||
|
||||
change f()
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,8 +3,9 @@
|
||||
int f(int x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
+ return s;
|
||||
}
|
||||
|
||||
commit de4c48ae814792c02a49c4c3c0c757ae69c55f6a
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:48 2013 +0100
|
||||
|
||||
initial
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- /dev/null
|
||||
+++ b/a.c
|
||||
@@ -0,0 +3,8 @@
|
||||
+int f(int x)
|
||||
+{
|
||||
+ int s = 0;
|
||||
+ while (x) {
|
||||
+ x >>= 1;
|
||||
+ s++;
|
||||
+ }
|
||||
+}
|
104
t/t4211/expect.multiple
Normal file
104
t/t4211/expect.multiple
Normal file
@ -0,0 +1,104 @@
|
||||
commit 4659538844daa2849b1a9e7d6fadb96fcd26fc83
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:48:43 2013 +0100
|
||||
|
||||
change back to complete line
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -18,5 +18,7 @@
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
-}
|
||||
\ No newline at end of file
|
||||
+}
|
||||
+
|
||||
+/* incomplete lines are bad! */
|
||||
|
||||
commit 100b61a6f2f720f812620a9d10afb3a960ccb73c
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:48:10 2013 +0100
|
||||
|
||||
change to an incomplete line at end
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -18,5 +18,5 @@
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
-}
|
||||
+}
|
||||
\ No newline at end of file
|
||||
|
||||
commit a6eb82647d5d67f893da442f8f9375fd89a3b1e2
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:45:16 2013 +0100
|
||||
|
||||
touch both functions
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,9 +3,9 @@
|
||||
-int f(int x)
|
||||
+long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
@@ -17,5 +17,5 @@
|
||||
int main ()
|
||||
{
|
||||
- printf("%d\n", f(15));
|
||||
+ printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
commit f04fb20f2c77850996cba739709acc6faecc58f7
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:55 2013 +0100
|
||||
|
||||
change f()
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,8 +3,9 @@
|
||||
int f(int x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
+ return s;
|
||||
}
|
||||
|
||||
commit de4c48ae814792c02a49c4c3c0c757ae69c55f6a
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:48 2013 +0100
|
||||
|
||||
initial
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- /dev/null
|
||||
+++ b/a.c
|
||||
@@ -0,0 +3,8 @@
|
||||
+int f(int x)
|
||||
+{
|
||||
+ int s = 0;
|
||||
+ while (x) {
|
||||
+ x >>= 1;
|
||||
+ s++;
|
||||
+ }
|
||||
+}
|
187
t/t4211/expect.multiple-overlapping
Normal file
187
t/t4211/expect.multiple-overlapping
Normal file
@ -0,0 +1,187 @@
|
||||
commit 4659538844daa2849b1a9e7d6fadb96fcd26fc83
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:48:43 2013 +0100
|
||||
|
||||
change back to complete line
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -4,19 +4,21 @@
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is only an example!
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
-}
|
||||
\ No newline at end of file
|
||||
+}
|
||||
+
|
||||
+/* incomplete lines are bad! */
|
||||
|
||||
commit 100b61a6f2f720f812620a9d10afb3a960ccb73c
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:48:10 2013 +0100
|
||||
|
||||
change to an incomplete line at end
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -4,19 +4,19 @@
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is only an example!
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
-}
|
||||
+}
|
||||
\ No newline at end of file
|
||||
|
||||
commit 39b6eb2d5b706d3322184a169f666f25ed3fbd00
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:45:41 2013 +0100
|
||||
|
||||
touch comment
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,19 +3,19 @@
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
- * A comment.
|
||||
+ * This is only an example!
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
commit a6eb82647d5d67f893da442f8f9375fd89a3b1e2
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:45:16 2013 +0100
|
||||
|
||||
touch both functions
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,19 +3,19 @@
|
||||
-int f(int x)
|
||||
+long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* A comment.
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
- printf("%d\n", f(15));
|
||||
+ printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
commit f04fb20f2c77850996cba739709acc6faecc58f7
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:55 2013 +0100
|
||||
|
||||
change f()
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,18 +3,19 @@
|
||||
int f(int x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
+ return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* A comment.
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
printf("%d\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
commit de4c48ae814792c02a49c4c3c0c757ae69c55f6a
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:48 2013 +0100
|
||||
|
||||
initial
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- /dev/null
|
||||
+++ b/a.c
|
||||
@@ -0,0 +3,18 @@
|
||||
+int f(int x)
|
||||
+{
|
||||
+ int s = 0;
|
||||
+ while (x) {
|
||||
+ x >>= 1;
|
||||
+ s++;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * A comment.
|
||||
+ */
|
||||
+
|
||||
+int main ()
|
||||
+{
|
||||
+ printf("%d\n", f(15));
|
||||
+ return 0;
|
||||
+}
|
59
t/t4211/expect.multiple-superset
Normal file
59
t/t4211/expect.multiple-superset
Normal file
@ -0,0 +1,59 @@
|
||||
commit a6eb82647d5d67f893da442f8f9375fd89a3b1e2
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:45:16 2013 +0100
|
||||
|
||||
touch both functions
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,9 +3,9 @@
|
||||
-int f(int x)
|
||||
+long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
commit f04fb20f2c77850996cba739709acc6faecc58f7
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:55 2013 +0100
|
||||
|
||||
change f()
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,8 +3,9 @@
|
||||
int f(int x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
+ return s;
|
||||
}
|
||||
|
||||
commit de4c48ae814792c02a49c4c3c0c757ae69c55f6a
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:48 2013 +0100
|
||||
|
||||
initial
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- /dev/null
|
||||
+++ b/a.c
|
||||
@@ -0,0 +3,8 @@
|
||||
+int f(int x)
|
||||
+{
|
||||
+ int s = 0;
|
||||
+ while (x) {
|
||||
+ x >>= 1;
|
||||
+ s++;
|
||||
+ }
|
||||
+}
|
160
t/t4211/expect.parallel-change-f-to-main
Normal file
160
t/t4211/expect.parallel-change-f-to-main
Normal file
@ -0,0 +1,160 @@
|
||||
commit 0469c60bc4837d52d97b1f081dec5f98dea20fed
|
||||
Merge: ba227c6 6ce3c4f
|
||||
Author: Thomas Rast <trast@inf.ethz.ch>
|
||||
Date: Fri Apr 12 16:16:24 2013 +0200
|
||||
|
||||
Merge across the rename
|
||||
|
||||
|
||||
commit 6ce3c4ff690136099bb17e1a8766b75764726ea7
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:49:50 2013 +0100
|
||||
|
||||
another simple change
|
||||
|
||||
diff --git a/b.c b/b.c
|
||||
--- a/b.c
|
||||
+++ b/b.c
|
||||
@@ -4,14 +4,14 @@
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
- x >>= 1;
|
||||
+ x /= 2;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is only an example!
|
||||
*/
|
||||
|
||||
|
||||
commit ba227c6632349700fbb957dec2b50f5e2358be3f
|
||||
Author: Thomas Rast <trast@inf.ethz.ch>
|
||||
Date: Fri Apr 12 16:15:57 2013 +0200
|
||||
|
||||
change on another line of history while rename happens
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -4,14 +4,14 @@
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
- * This is only an example!
|
||||
+ * This is only a short example!
|
||||
*/
|
||||
|
||||
|
||||
commit 39b6eb2d5b706d3322184a169f666f25ed3fbd00
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:45:41 2013 +0100
|
||||
|
||||
touch comment
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,14 +3,14 @@
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
- * A comment.
|
||||
+ * This is only an example!
|
||||
*/
|
||||
|
||||
|
||||
commit a6eb82647d5d67f893da442f8f9375fd89a3b1e2
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:45:16 2013 +0100
|
||||
|
||||
touch both functions
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,14 +3,14 @@
|
||||
-int f(int x)
|
||||
+long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* A comment.
|
||||
*/
|
||||
|
||||
|
||||
commit f04fb20f2c77850996cba739709acc6faecc58f7
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:55 2013 +0100
|
||||
|
||||
change f()
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,13 +3,14 @@
|
||||
int f(int x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
+ return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* A comment.
|
||||
*/
|
||||
|
||||
|
||||
commit de4c48ae814792c02a49c4c3c0c757ae69c55f6a
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:48 2013 +0100
|
||||
|
||||
initial
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- /dev/null
|
||||
+++ b/a.c
|
||||
@@ -0,0 +3,13 @@
|
||||
+int f(int x)
|
||||
+{
|
||||
+ int s = 0;
|
||||
+ while (x) {
|
||||
+ x >>= 1;
|
||||
+ s++;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * A comment.
|
||||
+ */
|
||||
+
|
59
t/t4211/expect.simple-f
Normal file
59
t/t4211/expect.simple-f
Normal file
@ -0,0 +1,59 @@
|
||||
commit a6eb82647d5d67f893da442f8f9375fd89a3b1e2
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:45:16 2013 +0100
|
||||
|
||||
touch both functions
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,9 +3,9 @@
|
||||
-int f(int x)
|
||||
+long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
commit f04fb20f2c77850996cba739709acc6faecc58f7
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:55 2013 +0100
|
||||
|
||||
change f()
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,8 +3,9 @@
|
||||
int f(int x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
+ return s;
|
||||
}
|
||||
|
||||
commit de4c48ae814792c02a49c4c3c0c757ae69c55f6a
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:48 2013 +0100
|
||||
|
||||
initial
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- /dev/null
|
||||
+++ b/a.c
|
||||
@@ -0,0 +3,8 @@
|
||||
+int f(int x)
|
||||
+{
|
||||
+ int s = 0;
|
||||
+ while (x) {
|
||||
+ x >>= 1;
|
||||
+ s++;
|
||||
+ }
|
||||
+}
|
100
t/t4211/expect.simple-f-to-main
Normal file
100
t/t4211/expect.simple-f-to-main
Normal file
@ -0,0 +1,100 @@
|
||||
commit 39b6eb2d5b706d3322184a169f666f25ed3fbd00
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:45:41 2013 +0100
|
||||
|
||||
touch comment
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,14 +3,14 @@
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
- * A comment.
|
||||
+ * This is only an example!
|
||||
*/
|
||||
|
||||
|
||||
commit a6eb82647d5d67f893da442f8f9375fd89a3b1e2
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:45:16 2013 +0100
|
||||
|
||||
touch both functions
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,14 +3,14 @@
|
||||
-int f(int x)
|
||||
+long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* A comment.
|
||||
*/
|
||||
|
||||
|
||||
commit f04fb20f2c77850996cba739709acc6faecc58f7
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:55 2013 +0100
|
||||
|
||||
change f()
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,13 +3,14 @@
|
||||
int f(int x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
+ return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* A comment.
|
||||
*/
|
||||
|
||||
|
||||
commit de4c48ae814792c02a49c4c3c0c757ae69c55f6a
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:48 2013 +0100
|
||||
|
||||
initial
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- /dev/null
|
||||
+++ b/a.c
|
||||
@@ -0,0 +3,13 @@
|
||||
+int f(int x)
|
||||
+{
|
||||
+ int s = 0;
|
||||
+ while (x) {
|
||||
+ x >>= 1;
|
||||
+ s++;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * A comment.
|
||||
+ */
|
||||
+
|
68
t/t4211/expect.simple-main
Normal file
68
t/t4211/expect.simple-main
Normal file
@ -0,0 +1,68 @@
|
||||
commit 4659538844daa2849b1a9e7d6fadb96fcd26fc83
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:48:43 2013 +0100
|
||||
|
||||
change back to complete line
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -18,5 +18,5 @@
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
-}
|
||||
\ No newline at end of file
|
||||
+}
|
||||
|
||||
commit 100b61a6f2f720f812620a9d10afb3a960ccb73c
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:48:10 2013 +0100
|
||||
|
||||
change to an incomplete line at end
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -18,5 +18,5 @@
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
-}
|
||||
+}
|
||||
\ No newline at end of file
|
||||
|
||||
commit a6eb82647d5d67f893da442f8f9375fd89a3b1e2
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:45:16 2013 +0100
|
||||
|
||||
touch both functions
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -17,5 +17,5 @@
|
||||
int main ()
|
||||
{
|
||||
- printf("%d\n", f(15));
|
||||
+ printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
commit de4c48ae814792c02a49c4c3c0c757ae69c55f6a
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:48 2013 +0100
|
||||
|
||||
initial
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- /dev/null
|
||||
+++ b/a.c
|
||||
@@ -0,0 +16,5 @@
|
||||
+int main ()
|
||||
+{
|
||||
+ printf("%d\n", f(15));
|
||||
+ return 0;
|
||||
+}
|
70
t/t4211/expect.simple-main-to-end
Normal file
70
t/t4211/expect.simple-main-to-end
Normal file
@ -0,0 +1,70 @@
|
||||
commit 4659538844daa2849b1a9e7d6fadb96fcd26fc83
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:48:43 2013 +0100
|
||||
|
||||
change back to complete line
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -18,5 +18,7 @@
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
-}
|
||||
\ No newline at end of file
|
||||
+}
|
||||
+
|
||||
+/* incomplete lines are bad! */
|
||||
|
||||
commit 100b61a6f2f720f812620a9d10afb3a960ccb73c
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:48:10 2013 +0100
|
||||
|
||||
change to an incomplete line at end
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -18,5 +18,5 @@
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
-}
|
||||
+}
|
||||
\ No newline at end of file
|
||||
|
||||
commit a6eb82647d5d67f893da442f8f9375fd89a3b1e2
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:45:16 2013 +0100
|
||||
|
||||
touch both functions
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -17,5 +17,5 @@
|
||||
int main ()
|
||||
{
|
||||
- printf("%d\n", f(15));
|
||||
+ printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
commit de4c48ae814792c02a49c4c3c0c757ae69c55f6a
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:48 2013 +0100
|
||||
|
||||
initial
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- /dev/null
|
||||
+++ b/a.c
|
||||
@@ -0,0 +16,5 @@
|
||||
+int main ()
|
||||
+{
|
||||
+ printf("%d\n", f(15));
|
||||
+ return 0;
|
||||
+}
|
102
t/t4211/expect.two-ranges
Normal file
102
t/t4211/expect.two-ranges
Normal file
@ -0,0 +1,102 @@
|
||||
commit 4659538844daa2849b1a9e7d6fadb96fcd26fc83
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:48:43 2013 +0100
|
||||
|
||||
change back to complete line
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -18,5 +18,5 @@
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
-}
|
||||
\ No newline at end of file
|
||||
+}
|
||||
|
||||
commit 100b61a6f2f720f812620a9d10afb3a960ccb73c
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:48:10 2013 +0100
|
||||
|
||||
change to an incomplete line at end
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -18,5 +18,5 @@
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
-}
|
||||
+}
|
||||
\ No newline at end of file
|
||||
|
||||
commit a6eb82647d5d67f893da442f8f9375fd89a3b1e2
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:45:16 2013 +0100
|
||||
|
||||
touch both functions
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,9 +3,9 @@
|
||||
-int f(int x)
|
||||
+long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
@@ -17,5 +17,5 @@
|
||||
int main ()
|
||||
{
|
||||
- printf("%d\n", f(15));
|
||||
+ printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
commit f04fb20f2c77850996cba739709acc6faecc58f7
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:55 2013 +0100
|
||||
|
||||
change f()
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -3,8 +3,9 @@
|
||||
int f(int x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
+ return s;
|
||||
}
|
||||
|
||||
commit de4c48ae814792c02a49c4c3c0c757ae69c55f6a
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:48 2013 +0100
|
||||
|
||||
initial
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- /dev/null
|
||||
+++ b/a.c
|
||||
@@ -0,0 +3,8 @@
|
||||
+int f(int x)
|
||||
+{
|
||||
+ int s = 0;
|
||||
+ while (x) {
|
||||
+ x >>= 1;
|
||||
+ s++;
|
||||
+ }
|
||||
+}
|
39
t/t4211/expect.vanishes-early
Normal file
39
t/t4211/expect.vanishes-early
Normal file
@ -0,0 +1,39 @@
|
||||
commit 4659538844daa2849b1a9e7d6fadb96fcd26fc83
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:48:43 2013 +0100
|
||||
|
||||
change back to complete line
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -22,1 +24,1 @@
|
||||
-}
|
||||
\ No newline at end of file
|
||||
+/* incomplete lines are bad! */
|
||||
|
||||
commit 100b61a6f2f720f812620a9d10afb3a960ccb73c
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:48:10 2013 +0100
|
||||
|
||||
change to an incomplete line at end
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- a/a.c
|
||||
+++ b/a.c
|
||||
@@ -22,1 +22,1 @@
|
||||
-}
|
||||
+}
|
||||
\ No newline at end of file
|
||||
|
||||
commit de4c48ae814792c02a49c4c3c0c757ae69c55f6a
|
||||
Author: Thomas Rast <trast@student.ethz.ch>
|
||||
Date: Thu Feb 28 10:44:48 2013 +0100
|
||||
|
||||
initial
|
||||
|
||||
diff --git a/a.c b/a.c
|
||||
--- /dev/null
|
||||
+++ b/a.c
|
||||
@@ -0,0 +20,1 @@
|
||||
+}
|
406
t/t4211/history.export
Normal file
406
t/t4211/history.export
Normal file
@ -0,0 +1,406 @@
|
||||
blob
|
||||
mark :1
|
||||
data 157
|
||||
#include <stdio.h>
|
||||
|
||||
int f(int x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A comment.
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
printf("%d\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
reset refs/tags/simple
|
||||
commit refs/tags/simple
|
||||
mark :2
|
||||
author Thomas Rast <trast@student.ethz.ch> 1362044688 +0100
|
||||
committer Thomas Rast <trast@student.ethz.ch> 1362044688 +0100
|
||||
data 8
|
||||
initial
|
||||
M 100644 :1 a.c
|
||||
|
||||
blob
|
||||
mark :3
|
||||
data 168
|
||||
#include <stdio.h>
|
||||
|
||||
int f(int x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* A comment.
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
printf("%d\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
commit refs/tags/simple
|
||||
mark :4
|
||||
author Thomas Rast <trast@student.ethz.ch> 1362044695 +0100
|
||||
committer Thomas Rast <trast@student.ethz.ch> 1362044695 +0100
|
||||
data 11
|
||||
change f()
|
||||
from :2
|
||||
M 100644 :3 a.c
|
||||
|
||||
blob
|
||||
mark :5
|
||||
data 171
|
||||
#include <stdio.h>
|
||||
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* A comment.
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
commit refs/tags/simple
|
||||
mark :6
|
||||
author Thomas Rast <trast@student.ethz.ch> 1362044716 +0100
|
||||
committer Thomas Rast <trast@student.ethz.ch> 1362044716 +0100
|
||||
data 21
|
||||
touch both functions
|
||||
from :4
|
||||
M 100644 :5 a.c
|
||||
|
||||
blob
|
||||
mark :7
|
||||
data 185
|
||||
#include <stdio.h>
|
||||
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is only an example!
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
commit refs/tags/simple
|
||||
mark :8
|
||||
author Thomas Rast <trast@student.ethz.ch> 1362044741 +0100
|
||||
committer Thomas Rast <trast@student.ethz.ch> 1362044741 +0100
|
||||
data 14
|
||||
touch comment
|
||||
from :6
|
||||
M 100644 :7 a.c
|
||||
|
||||
blob
|
||||
mark :9
|
||||
data 205
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is only an example!
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
commit refs/tags/simple
|
||||
mark :10
|
||||
author Thomas Rast <trast@student.ethz.ch> 1362044860 +0100
|
||||
committer Thomas Rast <trast@student.ethz.ch> 1362044860 +0100
|
||||
data 25
|
||||
change at very beginning
|
||||
from :8
|
||||
M 100644 :9 a.c
|
||||
|
||||
blob
|
||||
mark :11
|
||||
data 204
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is only an example!
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
commit refs/tags/simple
|
||||
mark :12
|
||||
author Thomas Rast <trast@student.ethz.ch> 1362044890 +0100
|
||||
committer Thomas Rast <trast@student.ethz.ch> 1362044890 +0100
|
||||
data 36
|
||||
change to an incomplete line at end
|
||||
from :10
|
||||
M 100644 :11 a.c
|
||||
|
||||
blob
|
||||
mark :13
|
||||
data 238
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is only an example!
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* incomplete lines are bad! */
|
||||
|
||||
commit refs/tags/simple
|
||||
mark :14
|
||||
author Thomas Rast <trast@student.ethz.ch> 1362044923 +0100
|
||||
committer Thomas Rast <trast@student.ethz.ch> 1362044923 +0100
|
||||
data 29
|
||||
change back to complete line
|
||||
from :12
|
||||
M 100644 :13 a.c
|
||||
|
||||
commit refs/tags/move-support
|
||||
mark :15
|
||||
author Thomas Rast <trast@student.ethz.ch> 1362044968 +0100
|
||||
committer Thomas Rast <trast@student.ethz.ch> 1362044968 +0100
|
||||
data 10
|
||||
move file
|
||||
from :14
|
||||
D a.c
|
||||
M 100644 :13 b.c
|
||||
|
||||
blob
|
||||
mark :16
|
||||
data 237
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x /= 2;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is only an example!
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* incomplete lines are bad! */
|
||||
|
||||
commit refs/tags/move-support
|
||||
mark :17
|
||||
author Thomas Rast <trast@student.ethz.ch> 1362044990 +0100
|
||||
committer Thomas Rast <trast@student.ethz.ch> 1362044990 +0100
|
||||
data 22
|
||||
another simple change
|
||||
from :15
|
||||
M 100644 :16 b.c
|
||||
|
||||
blob
|
||||
mark :18
|
||||
data 254
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
long f(long x);
|
||||
|
||||
/*
|
||||
* This is only an example!
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* incomplete lines are bad! */
|
||||
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x /= 2;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
commit refs/heads/master
|
||||
mark :19
|
||||
author Thomas Rast <trast@student.ethz.ch> 1362045024 +0100
|
||||
committer Thomas Rast <trast@student.ethz.ch> 1362045024 +0100
|
||||
data 21
|
||||
move within the file
|
||||
from :17
|
||||
M 100644 :18 b.c
|
||||
|
||||
blob
|
||||
mark :20
|
||||
data 243
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is only a short example!
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* incomplete lines are bad! */
|
||||
|
||||
commit refs/heads/parallel-change
|
||||
mark :21
|
||||
author Thomas Rast <trast@inf.ethz.ch> 1365776157 +0200
|
||||
committer Thomas Rast <trast@inf.ethz.ch> 1365776157 +0200
|
||||
data 55
|
||||
change on another line of history while rename happens
|
||||
from :14
|
||||
M 100644 :20 a.c
|
||||
|
||||
blob
|
||||
mark :22
|
||||
data 242
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
long f(long x)
|
||||
{
|
||||
int s = 0;
|
||||
while (x) {
|
||||
x /= 2;
|
||||
s++;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is only a short example!
|
||||
*/
|
||||
|
||||
int main ()
|
||||
{
|
||||
printf("%ld\n", f(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* incomplete lines are bad! */
|
||||
|
||||
commit refs/heads/parallel-change
|
||||
mark :23
|
||||
author Thomas Rast <trast@inf.ethz.ch> 1365776184 +0200
|
||||
committer Thomas Rast <trast@inf.ethz.ch> 1365776191 +0200
|
||||
data 24
|
||||
Merge across the rename
|
||||
from :21
|
||||
merge :17
|
||||
D a.c
|
||||
M 100644 :22 b.c
|
||||
|
||||
reset refs/heads/parallel-change
|
||||
from :23
|
||||
|
@ -175,6 +175,12 @@ test_expect_success 'blame -L with invalid end' '
|
||||
grep "has only 2 lines" errors
|
||||
'
|
||||
|
||||
test_expect_success 'blame parses <end> part of -L' '
|
||||
git blame -L1,1 tres >out &&
|
||||
cat out &&
|
||||
test $(wc -l < out) -eq 1
|
||||
'
|
||||
|
||||
test_expect_success 'indent of line numbers, nine lines' '
|
||||
git blame nine_lines >actual &&
|
||||
test $(grep -c " " actual) = 0
|
||||
|
Loading…
Reference in New Issue
Block a user