-# Defaults
+# This file is an example configuration for clang-format 5.0.
+#
+# Note that this style definition should only be understood as a hint
+# for writing new code. The rules are still work-in-progress and does
+# not yet exactly match the style we have in the existing code.
# Use tabs whenever we need to fill whitespace that spans at least from one tab
# stop to the next one.
pre-parse everything, and an access to a single ref in the
packed-refs does not touch majority of irrelevant refs, either.
+ * Add comment to clarify that the style file is meant to be used with
+ clang-5 and the rules are still work in progress.
+
Also contains various documentation updates and code clean-ups.
correctly, which has been corrected.
(merge a6304fa4c2 bc/rev-parse-parseopt-fix later to maint).
+ * The checkpoint command "git fast-import" did not flush updates to
+ refs and marks unless at least one object was created since the
+ last checkpoint, which has been corrected, as these things can
+ happen without any new object getting created.
+ (merge 30e215a65c er/fast-import-dump-refs-on-checkpoint later to maint).
+
+ * Spell the name of our system as "Git" in the output from
+ request-pull script.
+ (merge e66d7c37a5 ar/request-pull-phrasofix later to maint).
+
* Other minor doc, test and build updates and code cleanups.
(merge f094b89a4d ma/parse-maybe-bool later to maint).
(merge 39b00fa4d4 jk/drop-sha1-entry-pos later to maint).
(merge 0bca165fdb jk/validate-headref-fix later to maint).
(merge 93dbefb389 mr/doc-negative-pathspec later to maint).
(merge 5e633326e4 ad/doc-markup-fix later to maint).
+ (merge 9ca356fa8b rs/cocci-de-paren-call-params later to maint).
+ (merge 7099153e8d rs/tag-null-pointer-arith-fix later to maint).
+ (merge 0e187d758c rs/run-command-use-alloc-array later to maint).
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v2.14.GIT
+DEF_VER=v2.15.0-rc0
LF='
'
if (!head_rev)
die(_("Couldn't look up commit object for HEAD"));
}
- for (i = 0; i < argc; i++, strbuf_release(&bname)) {
+ for (i = 0; i < argc; i++, strbuf_reset(&bname)) {
char *target = NULL;
int flags = 0;
}
free(name);
+ strbuf_release(&bname);
- return(ret);
+ return ret;
}
static int calc_maxwidth(struct ref_array *refs, int remote_bonus)
strbuf_addf(&obname, "%%(objectname:short=%d)", filter->abbrev);
strbuf_addf(&local, "%%(align:%d,left)%%(refname:lstrip=2)%%(end)", maxwidth);
- strbuf_addf(&local, "%s", branch_get_color(BRANCH_COLOR_RESET));
+ strbuf_addstr(&local, branch_get_color(BRANCH_COLOR_RESET));
strbuf_addf(&local, " %s ", obname.buf);
if (filter->verbose > 1)
if (new->path && !opts->force_detach && !opts->new_branch &&
!opts->ignore_other_worktrees) {
- struct object_id oid;
int flag;
- char *head_ref = resolve_refdup("HEAD", 0, oid.hash, &flag);
+ char *head_ref = resolve_refdup("HEAD", 0, NULL, &flag);
if (head_ref &&
(!(flag & REF_ISSYMREF) || strcmp(head_ref, new->path)))
die_if_checked_out(new->path, 1);
strbuf_release(&buf);
}
+ UNLEAK(opts);
if (opts.patch_mode || opts.pathspec.nr)
return checkout_paths(&opts, new.name);
else
return -1;
}
result = run_diff_index(&rev, cached);
+ UNLEAK(rev);
return diff_result_code(&rev.diffopt, result);
}
result = diff_result_code(&rev.diffopt, result);
if (1 < rev.diffopt.skip_stat_unmatch)
refresh_index_quietly();
+ UNLEAK(rev);
+ UNLEAK(ent);
+ UNLEAK(blob);
return result;
}
always, allow_undefined, data.name_only);
}
+ UNLEAK(revs);
return 0;
}
{
struct check_connected_options opt = CHECK_CONNECTED_INIT;
struct command *cmd;
- struct object_id oid;
struct iterate_data data;
struct async muxer;
int err_fd = 0;
check_aliased_updates(commands);
free(head_name_to_free);
- head_name = head_name_to_free = resolve_refdup("HEAD", 0, oid.hash, NULL);
+ head_name = head_name_to_free = resolve_refdup("HEAD", 0, NULL, NULL);
if (use_atomic)
execute_commands_atomic(commands, si);
if (force && !is_null_oid(&prev) && oidcmp(&prev, &object))
printf(_("Updated tag '%s' (was %s)\n"), tag, find_unique_abbrev(prev.hash, DEFAULT_ABBREV));
- strbuf_release(&err);
- strbuf_release(&buf);
- strbuf_release(&ref);
- strbuf_release(&reflog_msg);
+ UNLEAK(buf);
+ UNLEAK(ref);
+ UNLEAK(reflog_msg);
+ UNLEAK(msg);
+ UNLEAK(err);
return 0;
}
pfd[i].revents = happened;
rc++;
}
+ else
+ {
+ pfd[i].revents = 0;
+ }
}
return rc;
T *src;
expression n;
@@
-- memcpy(dst, src, n * sizeof(*dst));
+- memcpy(dst, src, (n) * sizeof(*dst));
+ COPY_ARRAY(dst, src, n);
@@
T *src;
expression n;
@@
-- memcpy(dst, src, n * sizeof(*src));
+- memcpy(dst, src, (n) * sizeof(*src));
+ COPY_ARRAY(dst, src, n);
@@
T *src;
expression n;
@@
-- memcpy(dst, src, n * sizeof(T));
+- memcpy(dst, src, (n) * sizeof(T));
+ COPY_ARRAY(dst, src, n);
@@
T *ptr;
expression n;
@@
-- ptr = xmalloc(n * sizeof(*ptr));
+- ptr = xmalloc((n) * sizeof(*ptr));
+ ALLOC_ARRAY(ptr, n);
@@
T *ptr;
expression n;
@@
-- ptr = xmalloc(n * sizeof(T));
+- ptr = xmalloc((n) * sizeof(T));
+ ALLOC_ARRAY(ptr, n);
checkpoint_requested = 0;
if (object_count) {
cycle_packfile();
- dump_branches();
- dump_tags();
- dump_marks();
}
+ dump_branches();
+ dump_tags();
+ dump_marks();
}
static void parse_checkpoint(void)
%s (%ci)
-are available in the git repository at:
+are available in the Git repository at:
' $merge_base &&
echo " $url $pretty_remote" &&
git show -s --format='
* This way, fields printed to the right of the graph will remain
* aligned for the entire commit.
*/
- int extra;
- if (chars_written >= graph->width)
- return;
-
- extra = graph->width - chars_written;
- strbuf_addf(sb, "%*s", (int) extra, "");
+ if (chars_written < graph->width)
+ strbuf_addchars(sb, ' ', graph->width - chars_written);
}
static void graph_output_padding_line(struct git_graph *graph,
if (col->commit == graph->commit) {
seen_this = 1;
strbuf_write_column(sb, col, '|');
- strbuf_addf(sb, "%*s", graph->expansion_row, "");
+ strbuf_addchars(sb, ' ', graph->expansion_row);
chars_written += 1 + graph->expansion_row;
} else if (seen_this && (graph->expansion_row == 0)) {
/*
memcpy(hex, path, 2);
path += 2;
path++; /* skip '/' */
- memcpy(hex, path, GIT_SHA1_HEXSZ - 2);
+ memcpy(hex + 2, path, GIT_SHA1_HEXSZ - 2);
return get_oid_hex(hex, oid);
}
return sb;
}
-static char *cleanup_path(char *path)
+static const char *cleanup_path(const char *path)
{
/* Clean it up */
- if (!memcmp(path, "./", 2)) {
- path += 2;
+ if (skip_prefix(path, "./", &path)) {
while (*path == '/')
path++;
}
static void strbuf_cleanup_path(struct strbuf *sb)
{
- char *path = cleanup_path(sb->buf);
+ const char *path = cleanup_path(sb->buf);
if (path > sb->buf)
strbuf_remove(sb, 0, path - sb->buf);
}
strlcpy(buf, bad_path, n);
return buf;
}
- return cleanup_path(buf);
+ return (char *)cleanup_path(buf);
}
static int dir_prefix(const char *buf, const char *dir)
if (!home)
goto return_null;
if (real_home)
- strbuf_addstr(&user_path, real_path(home));
+ strbuf_add_real_path(&user_path, home);
else
strbuf_addstr(&user_path, home);
#ifdef GIT_WINDOWS_NATIVE
return 0;
}
+static int match_placeholder_arg(const char *to_parse, const char *candidate,
+ const char **end)
+{
+ const char *p;
+
+ if (!(skip_prefix(to_parse, candidate, &p)))
+ return 0;
+ if (*p == ',') {
+ *end = p + 1;
+ return 1;
+ }
+ if (*p == ')') {
+ *end = p;
+ return 1;
+ }
+ return 0;
+}
+
static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
const char *placeholder,
void *context)
if (skip_prefix(placeholder, "(trailers", &arg)) {
struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT;
- while (*arg == ':') {
- if (skip_prefix(arg, ":only", &arg))
- opts.only_trailers = 1;
- else if (skip_prefix(arg, ":unfold", &arg))
- opts.unfold = 1;
+ if (*arg == ':') {
+ arg++;
+ for (;;) {
+ if (match_placeholder_arg(arg, "only", &arg))
+ opts.only_trailers = 1;
+ else if (match_placeholder_arg(arg, "unfold", &arg))
+ opts.unfold = 1;
+ else
+ break;
+ }
}
if (*arg == ')') {
format_trailers_from_commit(sb, msg + c->subject_off, &opts);
static void head_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
{
- struct object_id unused;
-
- atom->u.head = resolve_refdup("HEAD", RESOLVE_REF_READING, unused.hash, NULL);
+ atom->u.head = resolve_refdup("HEAD", RESOLVE_REF_READING, NULL, NULL);
}
static struct {
ref->value = xcalloc(used_atom_cnt, sizeof(struct atom_value));
if (need_symref && (ref->flag & REF_ISSYMREF) && !ref->symref) {
- struct object_id unused1;
ref->symref = resolve_refdup(ref->refname, RESOLVE_REF_READING,
- unused1.hash, NULL);
+ NULL, NULL);
if (!ref->symref)
ref->symref = "";
}
reflogs->ref = xstrdup(ref);
for_each_reflog_ent(ref, read_one_reflog, reflogs);
if (reflogs->nr == 0) {
- struct object_id oid;
const char *name;
void *name_to_free;
name = name_to_free = resolve_refdup(ref, RESOLVE_REF_READING,
- oid.hash, NULL);
+ NULL, NULL);
if (name) {
for_each_reflog_ent(name, read_one_reflog, reflogs);
free(name_to_free);
reflogs = item->util;
else {
if (*branch == '\0') {
- struct object_id oid;
free(branch);
- branch = resolve_refdup("HEAD", 0, oid.hash, NULL);
+ branch = resolve_refdup("HEAD", 0, NULL, NULL);
if (!branch)
die ("No current branch");
struct string_list affected_refnames = STRING_LIST_INIT_NODUP;
char *head_ref = NULL;
int head_type;
- struct object_id head_oid;
struct files_transaction_backend_data *backend_data;
struct ref_transaction *packed_transaction = NULL;
*/
head_ref = refs_resolve_refdup(ref_store, "HEAD",
RESOLVE_REF_NO_RECURSE,
- head_oid.hash, &head_type);
+ NULL, &head_type);
if (head_ref && !(head_type & REF_ISSYMREF)) {
FREE_AND_NULL(head_ref);
}
if (ok != ITER_DONE) {
- strbuf_addf(err, "unable to write packed-refs file: "
- "error iterating over old contents");
+ strbuf_addstr(err, "unable to write packed-refs file: "
+ "error iterating over old contents");
goto error;
}
void repo_clear(struct repository *repo)
{
- free(repo->gitdir);
- repo->gitdir = NULL;
- free(repo->commondir);
- repo->commondir = NULL;
- free(repo->objectdir);
- repo->objectdir = NULL;
- free(repo->graft_file);
- repo->graft_file = NULL;
- free(repo->index_file);
- repo->index_file = NULL;
- free(repo->worktree);
- repo->worktree = NULL;
- free(repo->submodule_prefix);
- repo->submodule_prefix = NULL;
+ FREE_AND_NULL(repo->gitdir);
+ FREE_AND_NULL(repo->commondir);
+ FREE_AND_NULL(repo->objectdir);
+ FREE_AND_NULL(repo->graft_file);
+ FREE_AND_NULL(repo->index_file);
+ FREE_AND_NULL(repo->worktree);
+ FREE_AND_NULL(repo->submodule_prefix);
if (repo->config) {
git_configset_clear(repo->config);
- free(repo->config);
- repo->config = NULL;
+ FREE_AND_NULL(repo->config);
}
if (repo->submodule_cache) {
if (repo->index) {
discard_index(repo->index);
- free(repo->index);
- repo->index = NULL;
+ FREE_AND_NULL(repo->index);
}
}
}
/* Create an array of 'char *' to be used as the childenv */
- childenv = xmalloc((env.nr + 1) * sizeof(char *));
+ ALLOC_ARRAY(childenv, env.nr + 1);
for (i = 0; i < env.nr; i++)
childenv[i] = env.items[i].util;
childenv[env.nr] = NULL;
free(opts->xopts[i]);
free(opts->xopts);
- strbuf_addf(&dir, "%s", get_dir(opts));
+ strbuf_addstr(&dir, get_dir(opts));
remove_dir_recursively(&dir, 0);
strbuf_release(&dir);
extern void strbuf_init(struct strbuf *, size_t);
/**
- * Release a string buffer and the memory it used. You should not use the
- * string buffer after using this function, unless you initialize it again.
+ * Release a string buffer and the memory it used. After this call, the
+ * strbuf points to an empty string that does not need to be free()ed, as
+ * if it had been set to `STRBUF_INIT` and never modified.
+ *
+ * To clear a strbuf in preparation for further use without the overhead
+ * of free()ing and malloc()ing again, use strbuf_reset() instead.
*/
extern void strbuf_release(struct strbuf *);
* Detach the string from the strbuf and returns it; you now own the
* storage the string occupies and it is your responsibility from then on
* to release it with `free(3)` when you are done with it.
+ *
+ * The strbuf that previously held the string is reset to `STRBUF_INIT` so
+ * it can be reused after calling this function.
*/
extern char *strbuf_detach(struct strbuf *, size_t *);
{
int err;
struct child_process *process;
- const char *argv[] = { cmd, NULL };
entry->cmd = cmd;
process = &entry->process;
child_process_init(process);
- process->argv = argv;
+ argv_array_push(&process->args, cmd);
process->use_shell = 1;
process->in = -1;
process->out = -1;
* Split by newline, but don't create a string_list item
* for the empty string after the last separator.
*/
- if (sb.buf[sb.len - 1] == '\n')
+ if (sb.len && sb.buf[sb.len - 1] == '\n')
strbuf_setlen(&sb, sb.len - 1);
string_list_split_in_place(&list, sb.buf, '\n', -1);
'
test_expect_success ':only and :unfold work together' '
- git log --no-walk --pretty="%(trailers:only:unfold)" >actual &&
- git log --no-walk --pretty="%(trailers:unfold:only)" >reverse &&
+ git log --no-walk --pretty="%(trailers:only,unfold)" >actual &&
+ git log --no-walk --pretty="%(trailers:unfold,only)" >reverse &&
test_cmp actual reverse &&
{
grep -v patch.description <trailers | unfold &&
cat <<-\EOT >read-request.sed &&
#!/bin/sed -nf
# Note that a request could ask for "tag $tagname"
- / in the git repository at:$/!d
+ / in the Git repository at:$/!d
n
/^$/ n
s/ tag \([^ ]*\)$/ tag--\1/
SUBJECT (DATE)
- are available in the git repository at:
+ are available in the Git repository at:
URL BRANCH
compare_diff_raw expect actual
'
+###
+### series V (checkpoint)
+###
+
+# The commands in input_file should not produce any output on the file
+# descriptor set with --cat-blob-fd (or stdout if unspecified).
+#
+# To make sure you're observing the side effects of checkpoint *before*
+# fast-import terminates (and thus writes out its state), check that the
+# fast-import process is still running using background_import_still_running
+# *after* evaluating the test conditions.
+background_import_then_checkpoint () {
+ options=$1
+ input_file=$2
+
+ mkfifo V.input
+ exec 8<>V.input
+ rm V.input
+
+ mkfifo V.output
+ exec 9<>V.output
+ rm V.output
+
+ git fast-import $options <&8 >&9 &
+ echo $! >V.pid
+ # We don't mind if fast-import has already died by the time the test
+ # ends.
+ test_when_finished "exec 8>&-; exec 9>&-; kill $(cat V.pid) || true"
+
+ # Start in the background to ensure we adhere strictly to (blocking)
+ # pipes writing sequence. We want to assume that the write below could
+ # block, e.g. if fast-import blocks writing its own output to &9
+ # because there is no reader on &9 yet.
+ (
+ cat "$input_file"
+ echo "checkpoint"
+ echo "progress checkpoint"
+ ) >&8 &
+
+ error=1 ;# assume the worst
+ while read output <&9
+ do
+ if test "$output" = "progress checkpoint"
+ then
+ error=0
+ break
+ fi
+ # otherwise ignore cruft
+ echo >&2 "cruft: $output"
+ done
+
+ if test $error -eq 1
+ then
+ false
+ fi
+}
+
+background_import_still_running () {
+ if ! kill -0 "$(cat V.pid)"
+ then
+ echo >&2 "background fast-import terminated too early"
+ false
+ fi
+}
+
+test_expect_success PIPE 'V: checkpoint helper does not get stuck with extra output' '
+ cat >input <<-INPUT_END &&
+ progress foo
+ progress bar
+
+ INPUT_END
+
+ background_import_then_checkpoint "" input &&
+ background_import_still_running
+'
+
+test_expect_success PIPE 'V: checkpoint updates refs after reset' '
+ cat >input <<-\INPUT_END &&
+ reset refs/heads/V
+ from refs/heads/U
+
+ INPUT_END
+
+ background_import_then_checkpoint "" input &&
+ test "$(git rev-parse --verify V)" = "$(git rev-parse --verify U)" &&
+ background_import_still_running
+'
+
+test_expect_success PIPE 'V: checkpoint updates refs and marks after commit' '
+ cat >input <<-INPUT_END &&
+ commit refs/heads/V
+ mark :1
+ committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+ data 0
+ from refs/heads/U
+
+ INPUT_END
+
+ background_import_then_checkpoint "--export-marks=marks.actual" input &&
+
+ echo ":1 $(git rev-parse --verify V)" >marks.expected &&
+
+ test "$(git rev-parse --verify V^)" = "$(git rev-parse --verify U)" &&
+ test_cmp marks.expected marks.actual &&
+ background_import_still_running
+'
+
+# Re-create the exact same commit, but on a different branch: no new object is
+# created in the database, but the refs and marks still need to be updated.
+test_expect_success PIPE 'V: checkpoint updates refs and marks after commit (no new objects)' '
+ cat >input <<-INPUT_END &&
+ commit refs/heads/V2
+ mark :2
+ committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+ data 0
+ from refs/heads/U
+
+ INPUT_END
+
+ background_import_then_checkpoint "--export-marks=marks.actual" input &&
+
+ echo ":2 $(git rev-parse --verify V2)" >marks.expected &&
+
+ test "$(git rev-parse --verify V2)" = "$(git rev-parse --verify V)" &&
+ test_cmp marks.expected marks.actual &&
+ background_import_still_running
+'
+
+test_expect_success PIPE 'V: checkpoint updates tags after tag' '
+ cat >input <<-INPUT_END &&
+ tag Vtag
+ from refs/heads/V
+ tagger $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
+ data 0
+
+ INPUT_END
+
+ background_import_then_checkpoint "" input &&
+ git show-ref -d Vtag &&
+ background_import_still_running
+'
+
test_done
bufptr = nl + 1;
if (!strcmp(type, blob_type)) {
- item->tagged = &lookup_blob(&oid)->object;
+ item->tagged = (struct object *)lookup_blob(&oid);
} else if (!strcmp(type, tree_type)) {
- item->tagged = &lookup_tree(&oid)->object;
+ item->tagged = (struct object *)lookup_tree(&oid);
} else if (!strcmp(type, commit_type)) {
- item->tagged = &lookup_commit(&oid)->object;
+ item->tagged = (struct object *)lookup_commit(&oid);
} else if (!strcmp(type, tag_type)) {
- item->tagged = &lookup_tag(&oid)->object;
+ item->tagged = (struct object *)lookup_tag(&oid);
} else {
error("Unknown type %s", type);
item->tagged = NULL;
{
struct ref *ref;
int n = 0;
- struct object_id head_oid;
char *head;
int summary_width = transport_summary_width(refs);
- head = resolve_refdup("HEAD", RESOLVE_REF_READING, head_oid.hash, NULL);
+ head = resolve_refdup("HEAD", RESOLVE_REF_READING, NULL, NULL);
if (verbose) {
for (ref = refs; ref; ref = ref->next)
void wt_status_prepare(struct wt_status *s)
{
- struct object_id oid;
-
memset(s, 0, sizeof(*s));
memcpy(s->color_palette, default_wt_status_colors,
sizeof(default_wt_status_colors));
s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
s->use_color = -1;
s->relative_paths = 1;
- s->branch = resolve_refdup("HEAD", 0, oid.hash, NULL);
+ s->branch = resolve_refdup("HEAD", 0, NULL, NULL);
s->reference = "HEAD";
s->fp = stdout;
s->index_file = get_index_file();