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::
|
--show-stats::
|
||||||
Include additional statistics at the end of blame output.
|
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
|
Annotate only the given line range. <start> and <end> can take
|
||||||
one of these forms:
|
one of these forms:
|
||||||
|
|
||||||
- number
|
include::line-range-format.txt[]
|
||||||
+
|
|
||||||
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>.
|
|
||||||
+
|
|
||||||
|
|
||||||
-l::
|
-l::
|
||||||
Show long rev (Default: off).
|
Show long rev (Default: off).
|
||||||
|
@ -8,9 +8,9 @@ git-blame - Show what revision and author last modified each line of a file
|
|||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
[verse]
|
[verse]
|
||||||
'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental] [-L n,m]
|
'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental]
|
||||||
[-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>] [--abbrev=<n>]
|
[-L n,m | -L :fn] [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>]
|
||||||
[<rev> | --contents <file> | --reverse <rev>] [--] <file>
|
[--abbrev=<n>] [<rev> | --contents <file> | --reverse <rev>] [--] <file>
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
|
@ -62,6 +62,19 @@ produced by --stat etc.
|
|||||||
Note that only message is considered, if also a diff is shown
|
Note that only message is considered, if also a diff is shown
|
||||||
its size is not included.
|
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>::
|
<revision range>::
|
||||||
Show only commits in the specified revision range. When no
|
Show only commits in the specified revision range. When no
|
||||||
<revision range> is specified, it defaults to `HEAD` (i.e. the
|
<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
|
This makes sense only when following a strict policy of merging all
|
||||||
topic branches when staying on a single integration branch.
|
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`::
|
`git log -3`::
|
||||||
Limits the number of commits to show to 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 += http.h
|
||||||
LIB_H += kwset.h
|
LIB_H += kwset.h
|
||||||
LIB_H += levenshtein.h
|
LIB_H += levenshtein.h
|
||||||
|
LIB_H += line-log.h
|
||||||
|
LIB_H += line-range.h
|
||||||
LIB_H += list-objects.h
|
LIB_H += list-objects.h
|
||||||
LIB_H += ll-merge.h
|
LIB_H += ll-merge.h
|
||||||
LIB_H += log-tree.h
|
LIB_H += log-tree.h
|
||||||
@ -808,6 +810,8 @@ LIB_OBJS += hex.o
|
|||||||
LIB_OBJS += ident.o
|
LIB_OBJS += ident.o
|
||||||
LIB_OBJS += kwset.o
|
LIB_OBJS += kwset.o
|
||||||
LIB_OBJS += levenshtein.o
|
LIB_OBJS += levenshtein.o
|
||||||
|
LIB_OBJS += line-log.o
|
||||||
|
LIB_OBJS += line-range.o
|
||||||
LIB_OBJS += list-objects.o
|
LIB_OBJS += list-objects.o
|
||||||
LIB_OBJS += ll-merge.o
|
LIB_OBJS += ll-merge.o
|
||||||
LIB_OBJS += lockfile.o
|
LIB_OBJS += lockfile.o
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "parse-options.h"
|
#include "parse-options.h"
|
||||||
#include "utf8.h"
|
#include "utf8.h"
|
||||||
#include "userdiff.h"
|
#include "userdiff.h"
|
||||||
|
#include "line-range.h"
|
||||||
|
|
||||||
static char blame_usage[] = N_("git blame [options] [rev-opts] [rev] [--] file");
|
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;
|
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];
|
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
|
* 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
|
* 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);
|
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
|
* Parsing of -L option
|
||||||
*/
|
*/
|
||||||
@ -2016,15 +1945,7 @@ static void prepare_blame_range(struct scoreboard *sb,
|
|||||||
long lno,
|
long lno,
|
||||||
long *bottom, long *top)
|
long *bottom, long *top)
|
||||||
{
|
{
|
||||||
const char *term;
|
if (parse_range_arg(bottomtop, nth_line_cb, sb, lno, bottom, top, sb->path))
|
||||||
|
|
||||||
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)
|
|
||||||
usage(blame_usage);
|
usage(blame_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2574,10 +2495,6 @@ parse_done:
|
|||||||
bottom = top = 0;
|
bottom = top = 0;
|
||||||
if (bottomtop)
|
if (bottomtop)
|
||||||
prepare_blame_range(&sb, bottomtop, lno, &bottom, &top);
|
prepare_blame_range(&sb, bottomtop, lno, &bottom, &top);
|
||||||
if (bottom && top && top < bottom) {
|
|
||||||
long tmp;
|
|
||||||
tmp = top; top = bottom; bottom = tmp;
|
|
||||||
}
|
|
||||||
if (bottom < 1)
|
if (bottom < 1)
|
||||||
bottom = 1;
|
bottom = 1;
|
||||||
if (top < 1)
|
if (top < 1)
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
#include "string-list.h"
|
#include "string-list.h"
|
||||||
#include "parse-options.h"
|
#include "parse-options.h"
|
||||||
|
#include "line-log.h"
|
||||||
#include "branch.h"
|
#include "branch.h"
|
||||||
#include "streaming.h"
|
#include "streaming.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
@ -42,6 +43,12 @@ static const char * const builtin_log_usage[] = {
|
|||||||
NULL
|
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)
|
static int parse_decoration_style(const char *var, const char *value)
|
||||||
{
|
{
|
||||||
switch (git_config_maybe_bool(var, 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;
|
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)
|
static void cmd_log_init_defaults(struct rev_info *rev)
|
||||||
{
|
{
|
||||||
if (fmt_pretty)
|
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;
|
struct userformat_want w;
|
||||||
int quiet = 0, source = 0, mailmap = 0;
|
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[] = {
|
const struct option builtin_log_options[] = {
|
||||||
OPT_BOOL(0, "quiet", &quiet, N_("suppress diff output")),
|
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")),
|
OPT_BOOL(0, "use-mailmap", &mailmap, N_("Use mail map file")),
|
||||||
{ OPTION_CALLBACK, 0, "decorate", NULL, NULL, N_("decorate options"),
|
{ OPTION_CALLBACK, 0, "decorate", NULL, NULL, N_("decorate options"),
|
||||||
PARSE_OPT_OPTARG, decorate_callback},
|
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()
|
OPT_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
line_cb.rev = rev;
|
||||||
|
line_cb.prefix = prefix;
|
||||||
|
|
||||||
mailmap = use_mailmap_config;
|
mailmap = use_mailmap_config;
|
||||||
argc = parse_options(argc, argv, prefix,
|
argc = parse_options(argc, argv, prefix,
|
||||||
builtin_log_options, builtin_log_usage,
|
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;
|
rev->show_decorations = 1;
|
||||||
load_ref_decorations(decoration_style);
|
load_ref_decorations(decoration_style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rev->line_level_traverse)
|
||||||
|
line_log_init(rev, line_cb.prefix, &line_cb.args);
|
||||||
|
|
||||||
setup_pager();
|
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 "color.h"
|
||||||
#include "gpg-interface.h"
|
#include "gpg-interface.h"
|
||||||
#include "sequencer.h"
|
#include "sequencer.h"
|
||||||
|
#include "line-log.h"
|
||||||
|
|
||||||
struct decoration name_decoration = { "object names" };
|
struct decoration name_decoration = { "object names" };
|
||||||
|
|
||||||
@ -796,6 +797,9 @@ int log_tree_commit(struct rev_info *opt, struct commit *commit)
|
|||||||
log.parent = NULL;
|
log.parent = NULL;
|
||||||
opt->loginfo = &log;
|
opt->loginfo = &log;
|
||||||
|
|
||||||
|
if (opt->line_level_traverse)
|
||||||
|
return line_log_print(opt, commit);
|
||||||
|
|
||||||
shown = log_tree_diff(opt, commit, &log);
|
shown = log_tree_diff(opt, commit, &log);
|
||||||
if (!shown && opt->loginfo && opt->always_show_header) {
|
if (!shown && opt->loginfo && opt->always_show_header) {
|
||||||
log.parent = NULL;
|
log.parent = NULL;
|
||||||
|
22
revision.c
22
revision.c
@ -13,6 +13,7 @@
|
|||||||
#include "decorate.h"
|
#include "decorate.h"
|
||||||
#include "log-tree.h"
|
#include "log-tree.h"
|
||||||
#include "string-list.h"
|
#include "string-list.h"
|
||||||
|
#include "line-log.h"
|
||||||
#include "mailmap.h"
|
#include "mailmap.h"
|
||||||
|
|
||||||
volatile show_early_output_fn_t show_early_output;
|
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)
|
if (revs->combine_merges)
|
||||||
revs->ignore_merges = 0;
|
revs->ignore_merges = 0;
|
||||||
revs->diffopt.abbrev = revs->abbrev;
|
revs->diffopt.abbrev = revs->abbrev;
|
||||||
|
|
||||||
|
if (revs->line_level_traverse) {
|
||||||
|
revs->limited = 1;
|
||||||
|
revs->topo_order = 1;
|
||||||
|
}
|
||||||
|
|
||||||
diff_setup_done(&revs->diffopt);
|
diff_setup_done(&revs->diffopt);
|
||||||
|
|
||||||
grep_commit_pattern_type(GREP_PATTERN_TYPE_UNSPECIFIED,
|
grep_commit_pattern_type(GREP_PATTERN_TYPE_UNSPECIFIED,
|
||||||
@ -2185,6 +2192,8 @@ int prepare_revision_walk(struct rev_info *revs)
|
|||||||
return -1;
|
return -1;
|
||||||
if (revs->topo_order)
|
if (revs->topo_order)
|
||||||
sort_in_topological_order(&revs->commits, revs->lifo);
|
sort_in_topological_order(&revs->commits, revs->lifo);
|
||||||
|
if (revs->line_level_traverse)
|
||||||
|
line_log_filter(revs);
|
||||||
if (revs->simplify_merges)
|
if (revs->simplify_merges)
|
||||||
simplify_merges(revs);
|
simplify_merges(revs);
|
||||||
if (revs->children.name)
|
if (revs->children.name)
|
||||||
@ -2192,12 +2201,6 @@ int prepare_revision_walk(struct rev_info *revs)
|
|||||||
return 0;
|
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)
|
static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp)
|
||||||
{
|
{
|
||||||
struct commit_list *cache = NULL;
|
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;
|
struct commit_list **pp = &commit->parents;
|
||||||
while (*pp) {
|
while (*pp) {
|
||||||
struct commit_list *parent = *pp;
|
struct commit_list *parent = *pp;
|
||||||
switch (rewrite_one(revs, &parent->item)) {
|
switch (rewrite_parent(revs, &parent->item)) {
|
||||||
case rewrite_one_ok:
|
case rewrite_one_ok:
|
||||||
break;
|
break;
|
||||||
case rewrite_one_noparents:
|
case rewrite_one_noparents:
|
||||||
@ -2390,7 +2394,7 @@ enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
|
|||||||
if (action == commit_show &&
|
if (action == commit_show &&
|
||||||
!revs->show_all &&
|
!revs->show_all &&
|
||||||
revs->prune && revs->dense && want_ancestry(revs)) {
|
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 commit_error;
|
||||||
}
|
}
|
||||||
return action;
|
return action;
|
||||||
|
16
revision.h
16
revision.h
@ -97,7 +97,8 @@ struct rev_info {
|
|||||||
cherry_mark:1,
|
cherry_mark:1,
|
||||||
bisect:1,
|
bisect:1,
|
||||||
ancestry_path:1,
|
ancestry_path:1,
|
||||||
first_parent_only:1;
|
first_parent_only:1,
|
||||||
|
line_level_traverse:1;
|
||||||
|
|
||||||
/* Diff flags */
|
/* Diff flags */
|
||||||
unsigned int diff:1,
|
unsigned int diff:1,
|
||||||
@ -176,6 +177,9 @@ struct rev_info {
|
|||||||
int count_left;
|
int count_left;
|
||||||
int count_right;
|
int count_right;
|
||||||
int count_same;
|
int count_same;
|
||||||
|
|
||||||
|
/* line level range that we are chasing */
|
||||||
|
struct decoration line_log_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define REV_TREE_SAME 0
|
#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 get_commit_action(struct rev_info *revs, struct commit *commit);
|
||||||
extern enum commit_action simplify_commit(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
|
#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
|
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' '
|
test_expect_success 'indent of line numbers, nine lines' '
|
||||||
git blame nine_lines >actual &&
|
git blame nine_lines >actual &&
|
||||||
test $(grep -c " " actual) = 0
|
test $(grep -c " " actual) = 0
|
||||||
|
Loading…
Reference in New Issue
Block a user