Merge branch 'cc/trace' into next

* cc/trace:
  Trace into a file or an open fd and refactor tracing code.
  Replace uses of strdup with xstrdup.
  consolidate two copies of new style object header parsing code.
  Documentation: Fix howto/revert-branch-rebase.html generation
  fmt-merge-msg: fix off-by-one bug
  git-rev-list(1): group options; reformat; document more options
This commit is contained in:
Junio C Hamano
2006-09-02 21:42:12 -07:00
38 changed files with 355 additions and 187 deletions

View File

@@ -107,7 +107,7 @@ WEBDOC_DEST = /pub/software/scm/git/docs
$(patsubst %.txt,%.html,$(wildcard howto/*.txt)): %.html : %.txt
rm -f $@+ $@
sed -e '1,/^$$/d' $? | asciidoc -b xhtml11 - >$@+
sed -e '1,/^$$/d' $< | asciidoc -b xhtml11 - >$@+
mv $@+ $@
install-webdoc : html

View File

@@ -27,111 +27,233 @@ SYNOPSIS
DESCRIPTION
-----------
Lists commit objects in reverse chronological order starting at the
given commit(s), taking ancestry relationship into account. This is
useful to produce human-readable log output.
Commits which are stated with a preceding '{caret}' cause listing to stop at
that point. Their parents are implied. "git-rev-list foo bar {caret}baz" thus
Commits which are stated with a preceding '{caret}' cause listing to
stop at that point. Their parents are implied. Thus the following
command:
-----------------------------------------------------------------------
$ git-rev-list foo bar ^baz
-----------------------------------------------------------------------
means "list all the commits which are included in 'foo' and 'bar', but
not in 'baz'".
A special notation <commit1>..<commit2> can be used as a
short-hand for {caret}<commit1> <commit2>.
A special notation "'<commit1>'..'<commit2>'" can be used as a
short-hand for "{caret}'<commit1>' '<commit2>'". For example, either of
the following may be used interchangeably:
Another special notation is <commit1>...<commit2> which is useful for
merges. The resulting set of commits is the symmetric difference
-----------------------------------------------------------------------
$ git-rev-list origin..HEAD
$ git-rev-list HEAD ^origin
-----------------------------------------------------------------------
Another special notation is "'<commit1>'...'<commit2>'" which is useful
for merges. The resulting set of commits is the symmetric difference
between the two operands. The following two commands are equivalent:
------------
$ git-rev-list A B --not $(git-merge-base --all A B)
$ git-rev-list A...B
------------
-----------------------------------------------------------------------
$ git-rev-list A B --not $(git-merge-base --all A B)
$ git-rev-list A...B
-----------------------------------------------------------------------
gitlink:git-rev-list[1] is a very essential git program, since it
provides the ability to build and traverse commit ancestry graphs. For
this reason, it has a lot of different options that enables it to be
used by commands as different as gitlink:git-bisect[1] and
gitlink:git-repack[1].
OPTIONS
-------
--pretty::
Print the contents of the commit changesets in human-readable form.
Commit Formatting
~~~~~~~~~~~~~~~~~
Using these options, gitlink:git-rev-list[1] will act similar to the
more specialized family of commit log tools: gitlink:git-log[1],
gitlink:git-show[1], and gitlink:git-whatchanged[1]
--pretty[='<format>']::
Pretty print the contents of the commit logs in a given format,
where '<format>' can be one of 'raw', 'medium', 'short', 'full',
and 'oneline'. When left out the format default to 'medium'.
--relative-date::
Show dates relative to the current time, e.g. "2 hours ago".
Only takes effect for dates shown in human-readable format, such
as when using "--pretty".
--header::
Print the contents of the commit in raw-format; each
record is separated with a NUL character.
Print the contents of the commit in raw-format; each record is
separated with a NUL character.
--parents::
Print the parents of the commit.
--objects::
Print the object IDs of any object referenced by the listed commits.
'git-rev-list --objects foo ^bar' thus means "send me all object IDs
which I need to download if I have the commit object 'bar', but
not 'foo'".
Diff Formatting
~~~~~~~~~~~~~~~
--objects-edge::
Similar to `--objects`, but also print the IDs of
excluded commits prefixed with a `-` character. This is
used by `git-pack-objects` to build 'thin' pack, which
records objects in deltified form based on objects
contained in these excluded commits to reduce network
traffic.
Below are listed options that control the formatting of diff output.
Some of them are specific to gitlink:git-rev-list[1], however other diff
options may be given. See gitlink:git-diff-files[1] for more options.
--unpacked::
Only useful with `--objects`; print the object IDs that
are not in packs.
-c::
--bisect::
Limit output to the one commit object which is roughly halfway
between the included and excluded commits. Thus, if 'git-rev-list
--bisect foo {caret}bar {caret}baz' outputs 'midpoint', the output
of 'git-rev-list foo {caret}midpoint' and 'git-rev-list midpoint
{caret}bar {caret}baz' would be of roughly the same length.
Finding the change
which introduces a regression is thus reduced to a binary search:
repeatedly generate and test new 'midpoint's until the commit chain
is of length one.
This flag changes the way a merge commit is displayed. It shows
the differences from each of the parents to the merge result
simultaneously instead of showing pairwise diff between a parent
and the result one at a time. Furthermore, it lists only files
which were modified from all parents.
--cc::
This flag implies the '-c' options and further compresses the
patch output by omitting hunks that show differences from only
one parent, or show the same change from all but one parent for
an Octopus merge.
-r::
Show recursive diffs.
-t::
Show the tree objects in the diff output. This implies '-r'.
Commit Limiting
~~~~~~~~~~~~~~~
Besides specifying a range of commits that should be listed using the
special notations explained in the description, additional commit
limiting may be applied.
--
-n 'number', --max-count='number'::
--max-count::
Limit the number of commits output.
--max-age=timestamp, --min-age=timestamp::
--since='date', --after='date'::
Show commits more recent than a specific date.
--until='date', --before='date'::
Show commits older than a specific date.
--max-age='timestamp', --min-age='timestamp'::
Limit the commits output to specified time range.
--sparse::
When optional paths are given, the command outputs only
the commits that changes at least one of them, and also
ignores merges that do not touch the given paths. This
flag makes the command output all eligible commits
(still subject to count and age limitation), but apply
merge simplification nevertheless.
--remove-empty::
Stop when a given path disappears from the tree.
--no-merges::
Do not print commits with more than one parent.
--not::
Reverses the meaning of the '{caret}' prefix (or lack
thereof) for all following revision specifiers, up to
the next `--not`.
Reverses the meaning of the '{caret}' prefix (or lack thereof)
for all following revision specifiers, up to the next '--not'.
--all::
Pretend as if all the refs in `$GIT_DIR/refs/` are
listed on the command line as <commit>.
--topo-order::
By default, the commits are shown in reverse
chronological order. This option makes them appear in
topological order (i.e. descendant commits are shown
before their parents).
Pretend as if all the refs in `$GIT_DIR/refs/` are listed on the
command line as '<commit>'.
--merge::
After a failed merge, show refs that touch files having a
conflict and don't exist on all heads to merge.
--relative-date::
Show dates relative to the current time, e.g. "2 hours ago".
Only takes effect for dates shown in human-readable format,
such as when using "--pretty".
--boundary::
Output uninteresting commits at the boundary, which are usually
not shown.
--dense, --sparse::
When optional paths are given, the default behaviour ('--dense') is to
only output commits that changes at least one of them, and also ignore
merges that do not touch the given paths.
Use the '--sparse' flag to makes the command output all eligible commits
(still subject to count and age limitation), but apply merge
simplification nevertheless.
--bisect::
Limit output to the one commit object which is roughly halfway between
the included and excluded commits. Thus, if
-----------------------------------------------------------------------
$ git-rev-list --bisect foo ^bar ^baz
-----------------------------------------------------------------------
outputs 'midpoint', the output of the two commands
-----------------------------------------------------------------------
$ git-rev-list foo ^midpoint
$ git-rev-list midpoint ^bar ^baz
-----------------------------------------------------------------------
would be of roughly the same length. Finding the change which
introduces a regression is thus reduced to a binary search: repeatedly
generate and test new 'midpoint's until the commit chain is of length
one.
--
Commit Ordering
~~~~~~~~~~~~~~~
By default, the commits are shown in reverse chronological order.
--topo-order::
This option makes them appear in topological order (i.e.
descendant commits are shown before their parents).
--date-order::
This option is similar to '--topo-order' in the sense that no
parent comes before all of its children, but otherwise things
are still ordered in the commit timestamp order.
Object Traversal
~~~~~~~~~~~~~~~~
These options are mostly targeted for packing of git repositories.
--objects::
Print the object IDs of any object referenced by the listed
commits. 'git-rev-list --objects foo ^bar' thus means "send me
all object IDs which I need to download if I have the commit
object 'bar', but not 'foo'".
--objects-edge::
Similar to '--objects', but also print the IDs of excluded
commits prefixed with a "-" character. This is used by
gitlink:git-pack-objects[1] to build "thin" pack, which records
objects in deltified form based on objects contained in these
excluded commits to reduce network traffic.
--unpacked::
Only useful with '--objects'; print the object IDs that are not
in packs.
Author
------
@@ -139,9 +261,9 @@ Written by Linus Torvalds <torvalds@osdl.org>
Documentation
--------------
Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
Documentation by David Greaves, Junio C Hamano, Jonas Fonseca
and the git-list <git@vger.kernel.org>.
GIT
---
Part of the gitlink:git[7] suite

View File

@@ -617,7 +617,7 @@ static void simplify_commit(struct rev_info *revs, struct commit *commit)
if (new_name) {
struct util_info* putil = get_util(p);
if (!putil->pathname)
putil->pathname = strdup(new_name);
putil->pathname = xstrdup(new_name);
} else {
*pp = parent->next;
continue;

View File

@@ -2449,7 +2449,7 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
static int git_apply_config(const char *var, const char *value)
{
if (!strcmp(var, "apply.whitespace")) {
apply_default_whitespace = strdup(value);
apply_default_whitespace = xstrdup(value);
return 0;
}
return git_default_config(var, value);

View File

@@ -111,29 +111,29 @@ static int handle_line(char *line)
i = find_in_list(&srcs, src);
if (i < 0) {
i = srcs.nr;
append_to_list(&srcs, strdup(src),
append_to_list(&srcs, xstrdup(src),
xcalloc(1, sizeof(struct src_data)));
}
src_data = srcs.payload[i];
if (pulling_head) {
origin = strdup(src);
origin = xstrdup(src);
src_data->head_status |= 1;
} else if (!strncmp(line, "branch ", 7)) {
origin = strdup(line + 7);
origin = xstrdup(line + 7);
append_to_list(&src_data->branch, origin, NULL);
src_data->head_status |= 2;
} else if (!strncmp(line, "tag ", 4)) {
origin = line;
append_to_list(&src_data->tag, strdup(origin + 4), NULL);
append_to_list(&src_data->tag, xstrdup(origin + 4), NULL);
src_data->head_status |= 2;
} else if (!strncmp(line, "remote branch ", 14)) {
origin = strdup(line + 14);
origin = xstrdup(line + 14);
append_to_list(&src_data->r_branch, origin, NULL);
src_data->head_status |= 2;
} else {
origin = strdup(src);
append_to_list(&src_data->generic, strdup(line), NULL);
origin = xstrdup(src);
append_to_list(&src_data->generic, xstrdup(line), NULL);
src_data->head_status |= 2;
}
@@ -142,10 +142,10 @@ static int handle_line(char *line)
if (origin[0] == '\'' && origin[len - 1] == '\'') {
char *new_origin = xmalloc(len - 1);
memcpy(new_origin, origin + 1, len - 2);
new_origin[len - 1] = 0;
new_origin[len - 2] = 0;
origin = new_origin;
} else
origin = strdup(origin);
origin = xstrdup(origin);
} else {
char *new_origin = xmalloc(strlen(origin) + strlen(src) + 5);
sprintf(new_origin, "%s of %s", origin, src);
@@ -203,7 +203,7 @@ static void shortlog(const char *name, unsigned char *sha1,
bol = strstr(commit->buffer, "\n\n");
if (!bol) {
append_to_list(&subjects, strdup(sha1_to_hex(
append_to_list(&subjects, xstrdup(sha1_to_hex(
commit->object.sha1)),
NULL);
continue;
@@ -218,7 +218,7 @@ static void shortlog(const char *name, unsigned char *sha1,
memcpy(oneline, bol, len);
oneline[len] = 0;
} else
oneline = strdup(bol);
oneline = xstrdup(bol);
append_to_list(&subjects, oneline, NULL);
}
@@ -277,7 +277,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
usage(fmt_merge_msg_usage);
/* get current branch */
head = strdup(git_path("HEAD"));
head = xstrdup(git_path("HEAD"));
current_branch = resolve_ref(head, head_sha1, 1);
current_branch += strlen(head) - 4;
free((char *)head);

View File

@@ -1048,7 +1048,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
/* ignore empty line like grep does */
if (!buf[0])
continue;
add_pattern(&opt, strdup(buf), argv[1], ++lno,
add_pattern(&opt, xstrdup(buf), argv[1], ++lno,
GREP_PATTERN);
}
fclose(patterns);

View File

@@ -100,7 +100,7 @@ static int name_ref(const char *path, const unsigned char *sha1)
else if (!strncmp(path, "refs/", 5))
path = path + 5;
name_rev(commit, strdup(path), 0, 0, deref);
name_rev(commit, xstrdup(path), 0, 0, deref);
}
return 0;
}

View File

@@ -106,7 +106,7 @@ static void process_tree(struct tree *tree,
obj->flags |= SEEN;
if (parse_tree(tree) < 0)
die("bad tree object %s", sha1_to_hex(obj->sha1));
name = strdup(name);
name = xstrdup(name);
add_object(obj, p, path, name);
me.up = path;
me.elem = name;

View File

@@ -33,7 +33,7 @@ static int expand_one_ref(const char *ref, const unsigned char *sha1)
ref += 5;
if (!strncmp(ref, "tags/", 5))
add_refspec(strdup(ref));
add_refspec(xstrdup(ref));
return 0;
}
@@ -100,12 +100,12 @@ static int get_remotes_uri(const char *repo, const char *uri[MAX_URI])
if (!is_refspec) {
if (n < MAX_URI)
uri[n++] = strdup(s);
uri[n++] = xstrdup(s);
else
error("more than %d URL's specified, ignoring the rest", MAX_URI);
}
else if (is_refspec && !has_explicit_refspec)
add_refspec(strdup(s));
add_refspec(xstrdup(s));
}
fclose(f);
if (!n)
@@ -125,13 +125,13 @@ static int get_remote_config(const char* key, const char* value)
!strncmp(key + 7, config_repo, config_repo_len)) {
if (!strcmp(key + 7 + config_repo_len, ".url")) {
if (config_current_uri < MAX_URI)
config_uri[config_current_uri++] = strdup(value);
config_uri[config_current_uri++] = xstrdup(value);
else
error("more than %d URL's specified, ignoring the rest", MAX_URI);
}
else if (config_get_refspecs &&
!strcmp(key + 7 + config_repo_len, ".push"))
add_refspec(strdup(value));
add_refspec(xstrdup(value));
}
return 0;
}

View File

@@ -72,12 +72,12 @@ static int get_value(const char* key_, const char* regex_)
const char *home = getenv("HOME");
local = getenv("GIT_CONFIG_LOCAL");
if (!local)
local = repo_config = strdup(git_path("config"));
local = repo_config = xstrdup(git_path("config"));
if (home)
global = strdup(mkpath("%s/.gitconfig", home));
global = xstrdup(mkpath("%s/.gitconfig", home));
}
key = strdup(key_);
key = xstrdup(key_);
for (tl=key+strlen(key)-1; tl >= key && *tl != '.'; --tl)
*tl = tolower(*tl);
for (tl=key; *tl && *tl != '.'; ++tl)

View File

@@ -109,7 +109,7 @@ static void process_blob(struct blob *blob,
if (obj->flags & (UNINTERESTING | SEEN))
return;
obj->flags |= SEEN;
name = strdup(name);
name = xstrdup(name);
add_object(obj, p, path, name);
}
@@ -130,7 +130,7 @@ static void process_tree(struct tree *tree,
if (parse_tree(tree) < 0)
die("bad tree object %s", sha1_to_hex(obj->sha1));
obj->flags |= SEEN;
name = strdup(name);
name = xstrdup(name);
add_object(obj, p, path, name);
me.up = path;
me.elem = name;

View File

@@ -32,7 +32,7 @@ static int remove_file(const char *name)
ret = unlink(name);
if (!ret && (slash = strrchr(name, '/'))) {
char *n = strdup(name);
char *n = xstrdup(name);
do {
n[slash - name] = 0;
name = n;

View File

@@ -163,7 +163,7 @@ static void name_commits(struct commit_list *list,
en += sprintf(en, "^");
else
en += sprintf(en, "^%d", nth);
name_commit(p, strdup(newname), 0);
name_commit(p, xstrdup(newname), 0);
i++;
name_first_parent_chain(p);
}
@@ -364,7 +364,7 @@ static int append_ref(const char *refname, const unsigned char *sha1)
refname, MAX_REVS);
return 0;
}
ref_name[ref_name_cnt++] = strdup(refname);
ref_name[ref_name_cnt++] = xstrdup(refname);
ref_name[ref_name_cnt] = NULL;
return 0;
}
@@ -521,7 +521,7 @@ static int git_show_branch_config(const char *var, const char *value)
default_alloc = default_alloc * 3 / 2 + 20;
default_arg = xrealloc(default_arg, sizeof *default_arg * default_alloc);
}
default_arg[default_num++] = strdup(value);
default_arg[default_num++] = xstrdup(value);
default_arg[default_num] = NULL;
return 0;
}

View File

@@ -7,7 +7,7 @@ static const char git_symbolic_ref_usage[] =
static void check_symref(const char *HEAD)
{
unsigned char sha1[20];
const char *git_HEAD = strdup(git_path("%s", HEAD));
const char *git_HEAD = xstrdup(git_path("%s", HEAD));
const char *git_refs_heads_master = resolve_ref(git_HEAD, sha1, 0);
if (git_refs_heads_master) {
/* we want to strip the .git/ part */
@@ -26,7 +26,7 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix)
check_symref(argv[1]);
break;
case 3:
create_symref(strdup(git_path("%s", argv[1])), argv[2]);
create_symref(xstrdup(git_path("%s", argv[1])), argv[2]);
break;
default:
usage(git_symbolic_ref_usage);

View File

@@ -351,7 +351,7 @@ static int remote_tar(int argc, const char **argv)
usage(tar_tree_usage);
/* --remote=<repo> */
url = strdup(argv[1]+9);
url = xstrdup(argv[1]+9);
pid = git_connect(fd, url, exec);
if (pid < 0)
return 1;

View File

@@ -53,7 +53,7 @@ int cmd_upload_tar(int argc, const char **argv, const char *prefix)
return nak("expected (optional) base");
if (buf[len-1] == '\n')
buf[--len] = 0;
base = strdup(buf + 5);
base = xstrdup(buf + 5);
len = packet_read_line(0, buf, sizeof(buf));
}
if (len)

View File

@@ -311,11 +311,11 @@ int cmd_zip_tree(int argc, const char **argv, const char *prefix)
switch (argc) {
case 3:
base = strdup(argv[2]);
base = xstrdup(argv[2]);
baselen = strlen(base);
break;
case 2:
base = strdup("");
base = xstrdup("");
baselen = 0;
break;
default:

View File

@@ -350,11 +350,11 @@ int git_config(config_fn_t fn)
home = getenv("HOME");
filename = getenv("GIT_CONFIG_LOCAL");
if (!filename)
filename = repo_config = strdup(git_path("config"));
filename = repo_config = xstrdup(git_path("config"));
}
if (home) {
char *user_config = strdup(mkpath("%s/.gitconfig", home));
char *user_config = xstrdup(mkpath("%s/.gitconfig", home));
if (!access(user_config, R_OK))
ret = git_config_from_file(fn, user_config);
free(user_config);
@@ -545,8 +545,8 @@ int git_config_set_multivar(const char* key, const char* value,
if (!config_filename)
config_filename = git_path("config");
}
config_filename = strdup(config_filename);
lock_file = strdup(mkpath("%s.lock", config_filename));
config_filename = xstrdup(config_filename);
lock_file = xstrdup(mkpath("%s.lock", config_filename));
/*
* Since "key" actually contains the section name and the real

View File

@@ -69,7 +69,7 @@ struct ref **get_remote_heads(int in, struct ref **list,
if (len != name_len + 41) {
if (server_capabilities)
free(server_capabilities);
server_capabilities = strdup(name + name_len + 1);
server_capabilities = xstrdup(name + name_len + 1);
}
if (!check_ref(name, name_len, flags))
@@ -661,7 +661,7 @@ int git_connect(int fd[2], char *url, const char *prog)
if (path[1] == '~')
path++;
else {
path = strdup(ptr);
path = xstrdup(ptr);
free_path = 1;
}
@@ -672,7 +672,7 @@ int git_connect(int fd[2], char *url, const char *prog)
/* These underlying connection commands die() if they
* cannot connect.
*/
char *target_host = strdup(host);
char *target_host = xstrdup(host);
if (git_use_proxy(host))
git_proxy_connect(fd, host);
else

4
diff.c
View File

@@ -216,7 +216,7 @@ static char *quote_one(const char *str)
return NULL;
needlen = quote_c_style(str, NULL, NULL, 0);
if (!needlen)
return strdup(str);
return xstrdup(str);
xp = xmalloc(needlen + 1);
quote_c_style(str, xp, NULL, 0);
return xp;
@@ -658,7 +658,7 @@ static struct diffstat_file *diffstat_add(struct diffstat_t *diffstat,
x->is_renamed = 1;
}
else
x->name = strdup(name_a);
x->name = xstrdup(name_a);
return x;
}

View File

@@ -67,7 +67,7 @@ void setup_git(char *new_git_dir, char *new_git_object_dir,
free(git_graft_file);
git_graft_file = new_git_graft_file;
if (!git_graft_file) {
git_graft_file = strdup(git_path("info/grafts"));
git_graft_file = xstrdup(git_path("info/grafts"));
dyn_git_graft_file = 1;
} else {
dyn_git_graft_file = 0;

View File

@@ -234,8 +234,8 @@ int pull_targets_stdin(char ***target, const char ***write_ref)
*target = xrealloc(*target, targets_alloc * sizeof(**target));
*write_ref = xrealloc(*write_ref, targets_alloc * sizeof(**write_ref));
}
(*target)[targets] = strdup(tg_one);
(*write_ref)[targets] = rf_one ? strdup(rf_one) : NULL;
(*target)[targets] = xstrdup(tg_one);
(*write_ref)[targets] = rf_one ? xstrdup(rf_one) : NULL;
targets++;
}
return targets;

View File

@@ -458,7 +458,7 @@ static void fsck_object_dir(const char *path)
static int fsck_head_link(void)
{
unsigned char sha1[20];
const char *git_HEAD = strdup(git_path("HEAD"));
const char *git_HEAD = xstrdup(git_path("HEAD"));
const char *git_refs_heads_master = resolve_ref(git_HEAD, sha1, 1);
int pfxlen = strlen(git_HEAD) - 4; /* strip .../.git/ part */

View File

@@ -84,6 +84,14 @@ extern char *gitstrcasestr(const char *haystack, const char *needle);
extern size_t gitstrlcpy(char *, const char *, size_t);
#endif
static inline char* xstrdup(const char *str)
{
char *ret = strdup(str);
if (!ret)
die("Out of memory, strdup failed");
return ret;
}
static inline void *xmalloc(size_t size)
{
void *ret = malloc(size);

2
git.c
View File

@@ -97,7 +97,7 @@ static char *alias_string;
static int git_alias_config(const char *var, const char *value)
{
if (!strncmp(var, "alias.", 6) && !strcmp(var + 6, alias_command)) {
alias_string = strdup(value);
alias_string = xstrdup(value);
}
return 0;
}

View File

@@ -787,7 +787,7 @@ static int remote_ls(struct alt_base *repo, const char *path, int flags,
ls.flags = flags;
ls.repo = repo;
ls.path = strdup(path);
ls.path = xstrdup(path);
ls.dentry_name = NULL;
ls.dentry_flags = 0;
ls.userData = userData;

View File

@@ -1539,7 +1539,7 @@ static void remote_ls(const char *path, int flags,
struct remote_ls_ctx ls;
ls.flags = flags;
ls.path = strdup(path);
ls.path = xstrdup(path);
ls.dentry_name = NULL;
ls.dentry_flags = 0;
ls.userData = userData;
@@ -1738,7 +1738,7 @@ static struct object_list **process_tree(struct tree *tree,
die("bad tree object %s", sha1_to_hex(obj->sha1));
obj->flags |= SEEN;
name = strdup(name);
name = xstrdup(name);
p = add_one_object(obj, p);
me.up = path;
me.elem = name;
@@ -2467,7 +2467,7 @@ int main(int argc, char **argv)
/* Set up revision info for this refspec */
commit_argc = 3;
new_sha1_hex = strdup(sha1_to_hex(ref->new_sha1));
new_sha1_hex = xstrdup(sha1_to_hex(ref->new_sha1));
old_sha1_hex = NULL;
commit_argv[1] = "--objects";
commit_argv[2] = new_sha1_hex;

View File

@@ -1007,7 +1007,7 @@ imap_open_store( imap_server_conf_t *srvc )
* getpass() returns a pointer to a static buffer. make a copy
* for long term storage.
*/
srvc->pass = strdup( arg );
srvc->pass = xstrdup( arg );
}
if (CAP(NOLOGIN)) {
fprintf( stderr, "Skipping account %s@%s, server forbids LOGIN\n", srvc->user, srvc->host );
@@ -1263,7 +1263,7 @@ git_imap_config(const char *key, const char *val)
key += sizeof imap_key - 1;
if (!strcmp( "folder", key )) {
imap_folder = strdup( val );
imap_folder = xstrdup( val );
} else if (!strcmp( "host", key )) {
{
if (!strncmp( "imap:", val, 5 ))
@@ -1273,16 +1273,16 @@ git_imap_config(const char *key, const char *val)
}
if (!strncmp( "//", val, 2 ))
val += 2;
server.host = strdup( val );
server.host = xstrdup( val );
}
else if (!strcmp( "user", key ))
server.user = strdup( val );
server.user = xstrdup( val );
else if (!strcmp( "pass", key ))
server.pass = strdup( val );
server.pass = xstrdup( val );
else if (!strcmp( "port", key ))
server.port = git_config_int( key, val );
else if (!strcmp( "tunnel", key ))
server.tunnel = strdup( val );
server.tunnel = xstrdup( val );
return 0;
}

View File

@@ -21,7 +21,7 @@ static const char *write_temp_file(mmfile_t *f)
fd = mkstemp(filename);
if (fd < 0)
return NULL;
filename = strdup(filename);
filename = xstrdup(filename);
if (f->size != xwrite(fd, f->ptr, f->size)) {
rm_temp_file(filename);
return NULL;

View File

@@ -513,8 +513,8 @@ static char *unique_path(const char *path, const char *branch)
static int mkdir_p(const char *path, unsigned long mode)
{
/* path points to cache entries, so strdup before messing with it */
char *buf = strdup(path);
/* path points to cache entries, so xstrdup before messing with it */
char *buf = xstrdup(path);
int result = safe_create_leading_directories(buf);
free(buf);
return result;
@@ -668,9 +668,9 @@ static struct merge_file_info merge_file(struct diff_filespec *o,
git_unpack_file(a->sha1, src1);
git_unpack_file(b->sha1, src2);
argv[2] = la = strdup(mkpath("%s/%s", branch1, a->path));
argv[6] = lb = strdup(mkpath("%s/%s", branch2, b->path));
argv[4] = lo = strdup(mkpath("orig/%s", o->path));
argv[2] = la = xstrdup(mkpath("%s/%s", branch1, a->path));
argv[6] = lb = xstrdup(mkpath("%s/%s", branch2, b->path));
argv[4] = lo = xstrdup(mkpath("orig/%s", o->path));
argv[7] = src1;
argv[8] = orig;
argv[9] = src2,
@@ -1314,9 +1314,9 @@ int main(int argc, char *argv[])
original_index_file = getenv("GIT_INDEX_FILE");
if (!original_index_file)
original_index_file = strdup(git_path("index"));
original_index_file = xstrdup(git_path("index"));
temporary_index_file = strdup(git_path("mrg-rcrsv-tmp-idx"));
temporary_index_file = xstrdup(git_path("mrg-rcrsv-tmp-idx"));
if (argc < 4)
die("Usage: %s <base>... -- <head> <remote> ...\n", argv[0]);

View File

@@ -177,7 +177,7 @@ static void resolve(const char *base, struct name_entry *branch1, struct name_en
if (!branch1)
return;
path = strdup(mkpath("%s%s", base, result->path));
path = xstrdup(mkpath("%s%s", base, result->path));
orig = create_entry(2, branch1->mode, branch1->sha1, path);
final = create_entry(0, result->mode, result->sha1, path);
@@ -233,7 +233,7 @@ static struct merge_list *link_entry(unsigned stage, const char *base, struct na
if (entry)
path = entry->path;
else
path = strdup(mkpath("%s%s", base, n->path));
path = xstrdup(mkpath("%s%s", base, n->path));
link = create_entry(stage, n->mode, n->sha1, path);
link->link = entry;
return link;

View File

@@ -45,7 +45,7 @@ static int add_entry(struct path_list *list, const char *path)
(list->nr - index)
* sizeof(struct path_list_item));
list->items[index].path = list->strdup_paths ?
strdup(path) : (char *)path;
xstrdup(path) : (char *)path;
list->items[index].util = NULL;
list->nr++;

4
refs.c
View File

@@ -313,8 +313,8 @@ static struct ref_lock *lock_ref_sha1_basic(const char *path,
}
lock->lk = xcalloc(1, sizeof(struct lock_file));
lock->ref_file = strdup(path);
lock->log_file = strdup(git_path("logs/%s", lock->ref_file + plen));
lock->ref_file = xstrdup(path);
lock->log_file = xstrdup(git_path("logs/%s", lock->ref_file + plen));
lock->force_write = lstat(lock->ref_file, &st) && errno == ENOENT;
if (safe_create_leading_directories(lock->ref_file))

View File

@@ -23,7 +23,7 @@ static int add_info_ref(const char *path, const unsigned char *sha1)
static int update_info_refs(int force)
{
char *path0 = strdup(git_path("info/refs"));
char *path0 = xstrdup(git_path("info/refs"));
int len = strlen(path0);
char *path1 = xmalloc(len + 2);

View File

@@ -115,7 +115,7 @@ static void fill_sha1_path(char *pathbuf, const unsigned char *sha1)
/*
* NOTE! This returns a statically allocated buffer, so you have to be
* careful about using it. Do a "strdup()" if you need to save the
* careful about using it. Do a "xstrdup()" if you need to save the
* filename.
*
* Also note that this returns the location for creating. Reading
@@ -729,17 +729,39 @@ int legacy_loose_object(unsigned char *map)
return 0;
}
static unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep)
{
unsigned shift;
unsigned char c;
unsigned long size;
unsigned long used = 0;
c = buf[used++];
*type = (c >> 4) & 7;
size = c & 15;
shift = 4;
while (c & 0x80) {
if (len <= used)
return 0;
if (sizeof(long) * 8 <= shift)
return 0;
c = buf[used++];
size += (c & 0x7f) << shift;
shift += 7;
}
*sizep = size;
return used;
}
static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz)
{
unsigned char c;
unsigned int bits;
unsigned long size;
static const char *typename[8] = {
NULL, /* OBJ_EXT */
"commit", "tree", "blob", "tag",
NULL, NULL, NULL
unsigned long size, used;
static const char valid_loose_object_type[8] = {
0, /* OBJ_EXT */
1, 1, 1, 1, /* "commit", "tree", "blob", "tag" */
0, /* "delta" and others are invalid in a loose object */
};
const char *type;
enum object_type type;
/* Get the data stream */
memset(stream, 0, sizeof(*stream));
@@ -753,22 +775,11 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
return inflate(stream, 0);
}
c = *map++;
mapsize--;
type = typename[(c >> 4) & 7];
if (!type)
used = unpack_object_header_gently(map, mapsize, &type, &size);
if (!used || !valid_loose_object_type[type])
return -1;
bits = 4;
size = c & 0xf;
while ((c & 0x80)) {
if (bits >= 8*sizeof(long))
return -1;
c = *map++;
size += (c & 0x7f) << bits;
bits += 7;
mapsize--;
}
map += used;
mapsize -= used;
/* Set up the stream for the rest.. */
stream->next_in = map;
@@ -776,7 +787,8 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
inflateInit(stream);
/* And generate the fake traditional header */
stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu", type, size);
stream->total_out = 1 + snprintf(buffer, bufsiz, "%s %lu",
type_names[type], size);
return 0;
}
@@ -934,25 +946,18 @@ static int packed_delta_info(unsigned char *base_sha1,
static unsigned long unpack_object_header(struct packed_git *p, unsigned long offset,
enum object_type *type, unsigned long *sizep)
{
unsigned shift;
unsigned char c;
unsigned long size;
unsigned long used;
if (offset >= p->pack_size)
if (p->pack_size <= offset)
die("object offset outside of pack file");
c = *((unsigned char *)p->pack_base + offset++);
*type = (c >> 4) & 7;
size = c & 15;
shift = 4;
while (c & 0x80) {
if (offset >= p->pack_size)
die("object offset outside of pack file");
c = *((unsigned char *)p->pack_base + offset++);
size += (c & 0x7f) << shift;
shift += 7;
}
*sizep = size;
return offset;
used = unpack_object_header_gently((unsigned char *)p->pack_base +
offset,
p->pack_size - offset, type, sizep);
if (!used)
die("object offset outside of pack file");
return offset + used;
}
int check_reuse_pack_delta(struct packed_git *p, unsigned long offset,

View File

@@ -285,7 +285,7 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
pathname = resolve_ref(git_path(*p, len, str), this_result, 1);
if (pathname) {
if (!refs_found++)
real_path = strdup(pathname);
real_path = xstrdup(pathname);
if (!warn_ambiguous_refs)
break;
}

View File

@@ -34,6 +34,15 @@ export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
export EDITOR VISUAL
case $(echo $GIT_TRACE |tr [A-Z] [a-z]) in
1|2|true)
echo "* warning: Some tests will not work if GIT_TRACE" \
"is set as to trace on STDERR ! *"
echo "* warning: Please set GIT_TRACE to something" \
"other than 1, 2 or true ! *"
;;
esac
# Each test should start with something like this, after copyright notices:
#
# test_description='Description of this test...

30
trace.c
View File

@@ -51,7 +51,7 @@ int nfvasprintf(char **str, const char *fmt, va_list va)
}
/* Get a trace file descriptor from GIT_TRACE env variable. */
static int get_trace_fd()
static int get_trace_fd(int *need_close)
{
char *trace = getenv("GIT_TRACE");
@@ -61,9 +61,25 @@ static int get_trace_fd()
return STDERR_FILENO;
if (strlen(trace) == 1 && isdigit(*trace))
return atoi(trace);
if (*trace == '/') {
int fd = open(trace, O_WRONLY | O_APPEND | O_CREAT, 0666);
if (fd == -1) {
fprintf(stderr,
"Could not open '%s' for tracing: %s\n"
"Defaulting to tracing on stderr...\n",
trace, strerror(errno));
return STDERR_FILENO;
}
*need_close = 1;
return fd;
}
fprintf(stderr, "What does '%s' for GIT_TRACE means ?\n", trace);
fprintf(stderr, "If you want to trace into a file, "
"then please set GIT_TRACE to an absolute pathname "
"(starting with /).\n");
fprintf(stderr, "Defaulting to tracing on stderr...\n");
return STDERR_FILENO;
}
@@ -74,7 +90,8 @@ void trace_printf(const char *format, ...)
{
char *trace_str;
va_list rest;
int fd = get_trace_fd();
int need_close = 0;
int fd = get_trace_fd(&need_close);
if (!fd)
return;
@@ -86,6 +103,9 @@ void trace_printf(const char *format, ...)
write_or_whine(fd, trace_str, strlen(trace_str), err_msg);
free(trace_str);
if (need_close)
close(fd);
}
void trace_argv_printf(const char **argv, int count, const char *format, ...)
@@ -93,7 +113,8 @@ void trace_argv_printf(const char **argv, int count, const char *format, ...)
char *argv_str, *format_str, *trace_str;
size_t argv_len, format_len, trace_len;
va_list rest;
int fd = get_trace_fd();
int need_close = 0;
int fd = get_trace_fd(&need_close);
if (!fd)
return;
@@ -122,4 +143,7 @@ void trace_argv_printf(const char **argv, int count, const char *format, ...)
free(argv_str);
free(format_str);
free(trace_str);
if (need_close)
close(fd);
}