aboutsummaryrefslogtreecommitdiffstats
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/add.c12
-rw-r--r--builtin/am.c1
-rw-r--r--builtin/annotate.c23
-rw-r--r--builtin/archive.c5
-rw-r--r--builtin/bisect.c34
-rw-r--r--builtin/blame.c30
-rw-r--r--builtin/branch.c45
-rw-r--r--builtin/bundle.c18
-rw-r--r--builtin/cat-file.c10
-rw-r--r--builtin/check-ref-format.c2
-rw-r--r--builtin/checkout--worker.c2
-rw-r--r--builtin/checkout-index.c3
-rw-r--r--builtin/checkout.c4
-rw-r--r--builtin/clean.c3
-rw-r--r--builtin/clone.c39
-rw-r--r--builtin/commit-graph.c10
-rw-r--r--builtin/commit.c29
-rw-r--r--builtin/config.c25
-rw-r--r--builtin/count-objects.c2
-rw-r--r--builtin/credential-cache.c5
-rw-r--r--builtin/describe.c18
-rw-r--r--builtin/diff-files.c3
-rw-r--r--builtin/diff-index.c2
-rw-r--r--builtin/diff-tree.c1
-rw-r--r--builtin/diff.c4
-rw-r--r--builtin/difftool.c13
-rw-r--r--builtin/fast-export.c3
-rw-r--r--builtin/fast-import.c51
-rw-r--r--builtin/fetch-pack.c2
-rw-r--r--builtin/fetch.c162
-rw-r--r--builtin/for-each-repo.c5
-rw-r--r--builtin/fsck.c20
-rw-r--r--builtin/fsmonitor--daemon.c2
-rw-r--r--builtin/gc.c47
-rw-r--r--builtin/grep.c16
-rw-r--r--builtin/help.c19
-rw-r--r--builtin/hook.c7
-rw-r--r--builtin/index-pack.c193
-rw-r--r--builtin/init-db.c34
-rw-r--r--builtin/interpret-trailers.c25
-rw-r--r--builtin/log.c11
-rw-r--r--builtin/ls-files.c3
-rw-r--r--builtin/ls-remote.c2
-rw-r--r--builtin/mailsplit.c6
-rw-r--r--builtin/merge-file.c2
-rw-r--r--builtin/merge-index.c2
-rw-r--r--builtin/merge-ours.c2
-rw-r--r--builtin/merge-tree.c6
-rw-r--r--builtin/merge.c6
-rw-r--r--builtin/multi-pack-index.c20
-rw-r--r--builtin/mv.c2
-rw-r--r--builtin/name-rev.c2
-rw-r--r--builtin/notes.c44
-rw-r--r--builtin/pack-objects.c140
-rw-r--r--builtin/pack-redundant.c49
-rw-r--r--builtin/pack-refs.c1
-rw-r--r--builtin/patch-id.c16
-rw-r--r--builtin/prune.c2
-rw-r--r--builtin/pull.c8
-rw-r--r--builtin/push.c15
-rw-r--r--builtin/range-diff.c13
-rw-r--r--builtin/rebase.c3
-rw-r--r--builtin/receive-pack.c11
-rw-r--r--builtin/reflog.c18
-rw-r--r--builtin/refs.c20
-rw-r--r--builtin/remote.c134
-rw-r--r--builtin/repack.c6
-rw-r--r--builtin/replace.c2
-rw-r--r--builtin/replay.c4
-rw-r--r--builtin/rerere.c9
-rw-r--r--builtin/reset.c2
-rw-r--r--builtin/rev-list.c11
-rw-r--r--builtin/rev-parse.c3
-rw-r--r--builtin/revert.c18
-rw-r--r--builtin/rm.c3
-rw-r--r--builtin/send-pack.c1
-rw-r--r--builtin/shortlog.c13
-rw-r--r--builtin/show-branch.c2
-rw-r--r--builtin/show-index.c11
-rw-r--r--builtin/sparse-checkout.c88
-rw-r--r--builtin/stash.c50
-rw-r--r--builtin/submodule--helper.c54
-rw-r--r--builtin/tag.c20
-rw-r--r--builtin/unpack-objects.c2
-rw-r--r--builtin/update-index.c3
-rw-r--r--builtin/update-ref.c6
-rw-r--r--builtin/upload-pack.c5
-rw-r--r--builtin/var.c5
-rw-r--r--builtin/worktree.c65
89 files changed, 1336 insertions, 514 deletions
diff --git a/builtin/add.c b/builtin/add.c
index 773b7224a4..78dfb26577 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2006 Linus Torvalds
*/
+
#include "builtin.h"
#include "advice.h"
#include "config.h"
@@ -39,9 +40,9 @@ static int chmod_pathspec(struct repository *repo,
char flip,
int show_only)
{
- int i, ret = 0;
+ int ret = 0;
- for (i = 0; i < repo->index->cache_nr; i++) {
+ for (size_t i = 0; i < repo->index->cache_nr; i++) {
struct cache_entry *ce = repo->index->cache[i];
int err;
@@ -69,9 +70,9 @@ static int renormalize_tracked_files(struct repository *repo,
const struct pathspec *pathspec,
int flags)
{
- int i, retval = 0;
+ int retval = 0;
- for (i = 0; i < repo->index->cache_nr; i++) {
+ for (size_t i = 0; i < repo->index->cache_nr; i++) {
struct cache_entry *ce = repo->index->cache[i];
if (!include_sparse &&
@@ -385,7 +386,8 @@ int cmd_add(int argc,
char *ps_matched = NULL;
struct lock_file lock_file = LOCK_INIT;
- repo_config(repo, add_config, NULL);
+ if (repo)
+ repo_config(repo, add_config, NULL);
argc = parse_options(argc, argv, prefix, builtin_add_options,
builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
diff --git a/builtin/am.c b/builtin/am.c
index bfa95147cf..1338b606fe 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -5,6 +5,7 @@
*/
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "abspath.h"
#include "advice.h"
diff --git a/builtin/annotate.c b/builtin/annotate.c
index a99179fe4d..7f754f2309 100644
--- a/builtin/annotate.c
+++ b/builtin/annotate.c
@@ -4,7 +4,6 @@
* Copyright (C) 2006 Ryan Anderson
*/
-#define USE_THE_REPOSITORY_VARIABLE
#include "git-compat-util.h"
#include "builtin.h"
#include "strvec.h"
@@ -12,16 +11,26 @@
int cmd_annotate(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
struct strvec args = STRVEC_INIT;
- int i;
+ const char **args_copy;
+ int ret;
strvec_pushl(&args, "annotate", "-c", NULL);
-
- for (i = 1; i < argc; i++) {
+ for (int i = 1; i < argc; i++)
strvec_push(&args, argv[i]);
- }
- return cmd_blame(args.nr, args.v, prefix, the_repository);
+ /*
+ * `cmd_blame()` ends up modifying the array, which causes memory leaks
+ * if we didn't copy the array here.
+ */
+ CALLOC_ARRAY(args_copy, args.nr + 1);
+ COPY_ARRAY(args_copy, args.v, args.nr);
+
+ ret = cmd_blame(args.nr, args_copy, prefix, repo);
+
+ strvec_clear(&args);
+ free(args_copy);
+ return ret;
}
diff --git a/builtin/archive.c b/builtin/archive.c
index dc926d1a3d..13ea7308c8 100644
--- a/builtin/archive.c
+++ b/builtin/archive.c
@@ -2,7 +2,6 @@
* Copyright (c) 2006 Franck Bui-Huu
* Copyright (c) 2006 Rene Scharfe
*/
-#define USE_THE_REPOSITORY_VARIABLE
#include "builtin.h"
#include "archive.h"
#include "gettext.h"
@@ -79,7 +78,7 @@ static int run_remote_archiver(int argc, const char **argv,
int cmd_archive(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
const char *exec = "git-upload-archive";
char *output = NULL;
@@ -110,7 +109,7 @@ int cmd_archive(int argc,
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
- ret = write_archive(argc, argv, prefix, the_repository, output, 0);
+ ret = write_archive(argc, argv, prefix, repo, output, 0);
out:
free(output);
diff --git a/builtin/bisect.c b/builtin/bisect.c
index 21d17a6c1a..8b8d870cd1 100644
--- a/builtin/bisect.c
+++ b/builtin/bisect.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "copy.h"
#include "environment.h"
@@ -1312,7 +1314,8 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv)
return res;
}
-static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNUSED)
+static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNUSED,
+ struct repository *repo UNUSED)
{
if (argc > 1)
return error(_("'%s' requires either no argument or a commit"),
@@ -1320,7 +1323,8 @@ static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNU
return bisect_reset(argc ? argv[0] : NULL);
}
-static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNUSED)
+static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNUSED,
+ struct repository *repo UNUSED)
{
int res;
struct bisect_terms terms = { 0 };
@@ -1333,7 +1337,8 @@ static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNU
return res;
}
-static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNUSED)
+static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNUSED,
+ struct repository *repo UNUSED)
{
int res;
struct bisect_terms terms = { 0 };
@@ -1344,7 +1349,8 @@ static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNU
return res;
}
-static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *prefix)
+static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *prefix,
+ struct repository *repo UNUSED)
{
int res;
struct bisect_terms terms = { 0 };
@@ -1358,12 +1364,15 @@ static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *pref
return res;
}
-static int cmd_bisect__log(int argc UNUSED, const char **argv UNUSED, const char *prefix UNUSED)
+static int cmd_bisect__log(int argc UNUSED, const char **argv UNUSED,
+ const char *prefix UNUSED,
+ struct repository *repo UNUSED)
{
return bisect_log();
}
-static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UNUSED)
+static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UNUSED,
+ struct repository *repo UNUSED)
{
int res;
struct bisect_terms terms = { 0 };
@@ -1376,7 +1385,8 @@ static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UN
return res;
}
-static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUSED)
+static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUSED,
+ struct repository *repo UNUSED)
{
int res;
struct bisect_terms terms = { 0 };
@@ -1388,7 +1398,8 @@ static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUS
return res;
}
-static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix UNUSED)
+static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix UNUSED,
+ struct repository *repo UNUSED)
{
int res;
struct bisect_terms terms = { 0 };
@@ -1399,7 +1410,8 @@ static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix
return res;
}
-static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSED)
+static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSED,
+ struct repository *repo UNUSED)
{
int res;
struct bisect_terms terms = { 0 };
@@ -1415,7 +1427,7 @@ static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSE
int cmd_bisect(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
int res = 0;
parse_opt_subcommand_fn *fn = NULL;
@@ -1451,7 +1463,7 @@ int cmd_bisect(int argc,
} else {
argc--;
argv++;
- res = fn(argc, argv, prefix);
+ res = fn(argc, argv, prefix, repo);
}
return is_bisect_success(res) ? 0 : -res;
diff --git a/builtin/blame.c b/builtin/blame.c
index e407a22da3..7555c445ab 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -4,7 +4,9 @@
* Copyright (c) 2006, 2014 by its authors
* See COPYING for licensing conditions
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "config.h"
#include "color.h"
@@ -465,9 +467,14 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int
reset = GIT_COLOR_RESET;
}
+ if (abbrev < MINIMUM_ABBREV)
+ BUG("abbreviation is smaller than minimum length: %d < %d",
+ abbrev, MINIMUM_ABBREV);
+
for (cnt = 0; cnt < ent->num_lines; cnt++) {
char ch;
- int length = (opt & OUTPUT_LONG_OBJECT_NAME) ? the_hash_algo->hexsz : abbrev;
+ size_t length = (opt & OUTPUT_LONG_OBJECT_NAME) ?
+ the_hash_algo->hexsz : (size_t) abbrev;
if (opt & OUTPUT_COLOR_LINE) {
if (cnt > 0) {
@@ -482,9 +489,9 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int
fputs(color, stdout);
if (suspect->commit->object.flags & UNINTERESTING) {
- if (blank_boundary)
- memset(hex, ' ', length);
- else if (!(opt & OUTPUT_ANNOTATE_COMPAT)) {
+ if (blank_boundary) {
+ memset(hex, ' ', strlen(hex));
+ } else if (!(opt & OUTPUT_ANNOTATE_COMPAT)) {
length--;
putchar('^');
}
@@ -498,7 +505,8 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int
length--;
putchar('?');
}
- printf("%.*s", length, hex);
+
+ printf("%.*s", (int)(length < GIT_MAX_HEXSZ ? length : GIT_MAX_HEXSZ), hex);
if (opt & OUTPUT_ANNOTATE_COMPAT) {
const char *name;
if (opt & OUTPUT_SHOW_EMAIL)
@@ -1216,12 +1224,6 @@ parse_done:
output_option &= ~(OUTPUT_COLOR_LINE | OUTPUT_SHOW_AGE_WITH_COLOR);
output(&sb, output_option);
- free((void *)sb.final_buf);
- for (ent = sb.ent; ent; ) {
- struct blame_entry *e = ent->next;
- free(ent);
- ent = e;
- }
if (show_stats) {
printf("num read blob: %d\n", sb.num_read_blob);
@@ -1230,6 +1232,12 @@ parse_done:
}
cleanup:
+ for (ent = sb.ent; ent; ) {
+ struct blame_entry *e = ent->next;
+ free(ent);
+ ent = e;
+ }
+
free(path);
cleanup_scoreboard(&sb);
release_revisions(&revs);
diff --git a/builtin/branch.c b/builtin/branch.c
index fd1611ebf5..6e7b0cfddb 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -4,7 +4,9 @@
* Copyright (c) 2006 Kristian Høgsberg <krh@redhat.com>
* Based on git-branch.sh by Junio C Hamano.
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "config.h"
#include "color.h"
@@ -257,7 +259,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
char *target = NULL;
int flags = 0;
- strbuf_branchname(&bname, argv[i], allowed_interpret);
+ copy_branchname(&bname, argv[i], allowed_interpret);
free(name);
name = mkpathdup(fmt, bname.buf);
@@ -579,7 +581,7 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
int recovery = 0, oldref_usage = 0;
struct worktree **worktrees = get_worktrees();
- if (strbuf_check_branch_ref(&oldref, oldname)) {
+ if (check_branch_ref(&oldref, oldname)) {
/*
* Bad name --- this could be an attempt to rename a
* ref that we used to allow to be created by accident.
@@ -722,6 +724,7 @@ int cmd_branch(int argc,
static struct ref_sorting *sorting;
struct string_list sorting_options = STRING_LIST_INIT_DUP;
struct ref_format format = REF_FORMAT_INIT;
+ int ret;
struct option options[] = {
OPT_GROUP(N_("Generic options")),
@@ -851,15 +854,15 @@ int cmd_branch(int argc,
if (list)
setup_auto_pager("branch", 1);
- UNLEAK(sorting_options);
-
if (delete) {
if (!argc)
die(_("branch name required"));
- return delete_branches(argc, argv, delete > 1, filter.kind, quiet);
+ ret = delete_branches(argc, argv, delete > 1, filter.kind, quiet);
+ goto out;
} else if (show_current) {
print_current_branch_name();
- return 0;
+ ret = 0;
+ goto out;
} else if (list) {
/* git branch --list also shows HEAD when it is detached */
if ((filter.kind & FILTER_REFS_BRANCHES) && filter.detached)
@@ -882,37 +885,42 @@ int cmd_branch(int argc,
ref_sorting_release(sorting);
ref_filter_clear(&filter);
ref_format_clear(&format);
- return 0;
+
+ ret = 0;
+ goto out;
} else if (edit_description) {
const char *branch_name;
struct strbuf branch_ref = STRBUF_INIT;
struct strbuf buf = STRBUF_INIT;
- int ret = 1; /* assume failure */
if (!argc) {
if (filter.detached)
die(_("cannot give description to detached HEAD"));
branch_name = head;
} else if (argc == 1) {
- strbuf_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
+ copy_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
branch_name = buf.buf;
} else {
die(_("cannot edit description of more than one branch"));
}
strbuf_addf(&branch_ref, "refs/heads/%s", branch_name);
- if (!refs_ref_exists(get_main_ref_store(the_repository), branch_ref.buf))
+ if (!refs_ref_exists(get_main_ref_store(the_repository), branch_ref.buf)) {
error((!argc || branch_checked_out(branch_ref.buf))
? _("no commit on branch '%s' yet")
: _("no branch named '%s'"),
branch_name);
- else if (!edit_branch_description(branch_name))
+ ret = 1;
+ } else if (!edit_branch_description(branch_name)) {
ret = 0; /* happy */
+ } else {
+ ret = 1;
+ }
strbuf_release(&branch_ref);
strbuf_release(&buf);
- return ret;
+ goto out;
} else if (copy || rename) {
if (!argc)
die(_("branch name required"));
@@ -933,7 +941,7 @@ int cmd_branch(int argc,
if (!argc)
branch = branch_get(NULL);
else if (argc == 1) {
- strbuf_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
+ copy_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
branch = branch_get(buf.buf);
} else
die(_("too many arguments to set new upstream"));
@@ -963,7 +971,7 @@ int cmd_branch(int argc,
if (!argc)
branch = branch_get(NULL);
else if (argc == 1) {
- strbuf_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
+ copy_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL);
branch = branch_get(buf.buf);
} else
die(_("too many arguments to unset upstream"));
@@ -1000,12 +1008,17 @@ int cmd_branch(int argc,
create_branches_recursively(the_repository, branch_name,
start_name, NULL, force,
reflog, quiet, track, 0);
- return 0;
+ ret = 0;
+ goto out;
}
create_branch(the_repository, branch_name, start_name, force, 0,
reflog, quiet, track, 0);
} else
usage_with_options(builtin_branch_usage, options);
- return 0;
+ ret = 0;
+
+out:
+ string_list_clear(&sorting_options, 0);
+ return ret;
}
diff --git a/builtin/bundle.c b/builtin/bundle.c
index 127518c2a8..1e170e9278 100644
--- a/builtin/bundle.c
+++ b/builtin/bundle.c
@@ -67,7 +67,8 @@ static int parse_options_cmd_bundle(int argc,
return argc;
}
-static int cmd_bundle_create(int argc, const char **argv, const char *prefix) {
+static int cmd_bundle_create(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED) {
struct strvec pack_opts = STRVEC_INIT;
int version = -1;
int ret;
@@ -123,7 +124,8 @@ static int open_bundle(const char *path, struct bundle_header *header,
return read_bundle_header(path, header);
}
-static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) {
+static int cmd_bundle_verify(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED) {
struct bundle_header header = BUNDLE_HEADER_INIT;
int bundle_fd = -1;
int quiet = 0;
@@ -164,7 +166,8 @@ cleanup:
return ret;
}
-static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix) {
+static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED) {
struct bundle_header header = BUNDLE_HEADER_INIT;
int bundle_fd = -1;
int ret;
@@ -189,7 +192,8 @@ cleanup:
return ret;
}
-static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix) {
+static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED) {
struct bundle_header header = BUNDLE_HEADER_INIT;
int bundle_fd = -1;
int ret;
@@ -218,7 +222,7 @@ static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix)
strvec_pushl(&extra_index_pack_args, "-v", "--progress-title",
_("Unbundling objects"), NULL);
ret = !!unbundle(the_repository, &header, bundle_fd,
- &extra_index_pack_args, 0) ||
+ &extra_index_pack_args, NULL) ||
list_bundle_refs(&header, argc, argv);
bundle_header_release(&header);
@@ -231,7 +235,7 @@ cleanup:
int cmd_bundle(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
parse_opt_subcommand_fn *fn = NULL;
struct option options[] = {
@@ -247,5 +251,5 @@ int cmd_bundle(int argc,
packet_trace_identity("bundle");
- return !!fn(argc, argv, prefix);
+ return !!fn(argc, argv, prefix, repo);
}
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index bfdfb51c7c..b13561cf73 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -3,7 +3,10 @@
*
* Copyright (C) Linus Torvalds, 2005
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "convert.h"
@@ -827,15 +830,16 @@ static int batch_objects(struct batch_options *opt)
cb.seen = &seen;
for_each_loose_object(batch_unordered_loose, &cb, 0);
- for_each_packed_object(batch_unordered_packed, &cb,
- FOR_EACH_OBJECT_PACK_ORDER);
+ for_each_packed_object(the_repository, batch_unordered_packed,
+ &cb, FOR_EACH_OBJECT_PACK_ORDER);
oidset_clear(&seen);
} else {
struct oid_array sa = OID_ARRAY_INIT;
for_each_loose_object(collect_loose_object, &sa, 0);
- for_each_packed_object(collect_packed_object, &sa, 0);
+ for_each_packed_object(the_repository, collect_packed_object,
+ &sa, 0);
oid_array_for_each_unique(&sa, batch_object_cb, &cb);
diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c
index e86d8ef980..cef1ffe3ce 100644
--- a/builtin/check-ref-format.c
+++ b/builtin/check-ref-format.c
@@ -42,7 +42,7 @@ static int check_ref_format_branch(const char *arg)
int nongit;
setup_git_directory_gently(&nongit);
- if (strbuf_check_branch_ref(&sb, arg) ||
+ if (check_branch_ref(&sb, arg) ||
!skip_prefix(sb.buf, "refs/heads/", &name))
die("'%s' is not a valid branch name", arg);
printf("%s\n", name);
diff --git a/builtin/checkout--worker.c b/builtin/checkout--worker.c
index ff6cdccc21..b81002a1df 100644
--- a/builtin/checkout--worker.c
+++ b/builtin/checkout--worker.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "entry.h"
diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c
index 6dd38eb05d..a81501098d 100644
--- a/builtin/checkout-index.c
+++ b/builtin/checkout-index.c
@@ -4,7 +4,10 @@
* Copyright (C) 2005 Linus Torvalds
*
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "gettext.h"
diff --git a/builtin/checkout.c b/builtin/checkout.c
index c449558e66..01ea9ff8b2 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "advice.h"
#include "branch.h"
@@ -742,7 +744,7 @@ static void setup_branch_path(struct branch_info *branch)
&branch->oid, &branch->refname, 0))
repo_get_oid_committish(the_repository, branch->name, &branch->oid);
- strbuf_branchname(&buf, branch->name, INTERPRET_BRANCH_LOCAL);
+ copy_branchname(&buf, branch->name, INTERPRET_BRANCH_LOCAL);
if (strcmp(buf.buf, branch->name)) {
free(branch->name);
branch->name = xstrdup(buf.buf);
diff --git a/builtin/clean.c b/builtin/clean.c
index 9c48dd0271..053c94fc6b 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -5,7 +5,10 @@
*
* Based on git-clean.sh by Pavel Roskin
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "abspath.h"
#include "config.h"
diff --git a/builtin/clone.c b/builtin/clone.c
index e77339c847..fd001d800c 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -7,7 +7,10 @@
*
* Clone a repository into a different directory that does not yet exist.
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "abspath.h"
@@ -147,8 +150,8 @@ static struct option builtin_clone_options[] = {
N_("create a shallow clone of that depth")),
OPT_STRING(0, "shallow-since", &option_since, N_("time"),
N_("create a shallow clone since a specific time")),
- OPT_STRING_LIST(0, "shallow-exclude", &option_not, N_("revision"),
- N_("deepen history of shallow clone, excluding rev")),
+ OPT_STRING_LIST(0, "shallow-exclude", &option_not, N_("ref"),
+ N_("deepen history of shallow clone, excluding ref")),
OPT_BOOL(0, "single-branch", &option_single_branch,
N_("clone only one branch, HEAD or --branch")),
OPT_BOOL(0, "no-tags", &option_no_tags,
@@ -574,7 +577,7 @@ static void write_remote_refs(const struct ref *local_refs)
struct strbuf err = STRBUF_INIT;
t = ref_store_transaction_begin(get_main_ref_store(the_repository),
- &err);
+ REF_TRANSACTION_FLAG_INITIAL, &err);
if (!t)
die("%s", err.buf);
@@ -586,7 +589,7 @@ static void write_remote_refs(const struct ref *local_refs)
die("%s", err.buf);
}
- if (initial_ref_transaction_commit(t, &err))
+ if (ref_transaction_commit(t, &err))
die("%s", err.buf);
strbuf_release(&err);
@@ -1403,8 +1406,17 @@ int cmd_clone(int argc,
* data from the --bundle-uri option.
*/
if (bundle_uri) {
+ struct remote_state *state;
int has_heuristic = 0;
+ /*
+ * We need to save the remote state as our remote's lifetime is
+ * tied to it.
+ */
+ state = the_repository->remote_state;
+ the_repository->remote_state = NULL;
+ repo_clear(the_repository);
+
/* At this point, we need the_repository to match the cloned repo. */
if (repo_init(the_repository, git_dir, work_tree))
warning(_("failed to initialize the repo, skipping bundle URI"));
@@ -1413,6 +1425,10 @@ int cmd_clone(int argc,
bundle_uri);
else if (has_heuristic)
git_config_set_gently("fetch.bundleuri", bundle_uri);
+
+ remote_state_clear(the_repository->remote_state);
+ free(the_repository->remote_state);
+ the_repository->remote_state = state;
} else {
/*
* Populate transport->got_remote_bundle_uri and
@@ -1422,12 +1438,26 @@ int cmd_clone(int argc,
if (transport->bundles &&
hashmap_get_size(&transport->bundles->bundles)) {
+ struct remote_state *state;
+
+ /*
+ * We need to save the remote state as our remote's
+ * lifetime is tied to it.
+ */
+ state = the_repository->remote_state;
+ the_repository->remote_state = NULL;
+ repo_clear(the_repository);
+
/* At this point, we need the_repository to match the cloned repo. */
if (repo_init(the_repository, git_dir, work_tree))
warning(_("failed to initialize the repo, skipping bundle URI"));
else if (fetch_bundle_list(the_repository,
transport->bundles))
warning(_("failed to fetch advertised bundles"));
+
+ remote_state_clear(the_repository->remote_state);
+ free(the_repository->remote_state);
+ the_repository->remote_state = state;
} else {
clear_bundle_list(transport->bundles);
FREE_AND_NULL(transport->bundles);
@@ -1559,7 +1589,6 @@ int cmd_clone(int argc,
free(dir);
free(path);
free(repo_to_free);
- UNLEAK(repo);
junk_mode = JUNK_LEAVE_ALL;
transport_ls_refs_options_release(&transport_ls_refs_options);
diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c
index 7c991db6eb..bd70d052e7 100644
--- a/builtin/commit-graph.c
+++ b/builtin/commit-graph.c
@@ -62,7 +62,8 @@ static struct option *add_common_options(struct option *to)
return parse_options_concat(common_opts, to);
}
-static int graph_verify(int argc, const char **argv, const char *prefix)
+static int graph_verify(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct commit_graph *graph = NULL;
struct object_directory *odb = NULL;
@@ -214,7 +215,8 @@ static int git_commit_graph_write_config(const char *var, const char *value,
return 0;
}
-static int graph_write(int argc, const char **argv, const char *prefix)
+static int graph_write(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct string_list pack_indexes = STRING_LIST_INIT_DUP;
struct strbuf buf = STRBUF_INIT;
@@ -333,7 +335,7 @@ cleanup:
int cmd_commit_graph(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
parse_opt_subcommand_fn *fn = NULL;
struct option builtin_commit_graph_options[] = {
@@ -352,5 +354,5 @@ int cmd_commit_graph(int argc,
builtin_commit_graph_usage, 0);
FREE_AND_NULL(options);
- return fn(argc, argv, prefix);
+ return fn(argc, argv, prefix, repo);
}
diff --git a/builtin/commit.c b/builtin/commit.c
index 8db4e9df0c..ef5e622c07 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -4,7 +4,10 @@
* Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com>
* Based on git-commit.sh by Junio C Hamano and Linus Torvalds
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "advice.h"
#include "config.h"
@@ -135,7 +138,7 @@ static struct strvec trailer_args = STRVEC_INIT;
* is specified explicitly.
*/
static enum commit_msg_cleanup_mode cleanup_mode;
-static char *cleanup_arg;
+static char *cleanup_config;
static enum commit_whence whence;
static int use_editor = 1, include_status = 1;
@@ -728,6 +731,13 @@ static void prepare_amend_commit(struct commit *commit, struct strbuf *sb,
repo_unuse_commit_buffer(the_repository, commit, buffer);
}
+static void change_data_free(void *util, const char *str UNUSED)
+{
+ struct wt_status_change_data *d = util;
+ free(d->rename_source);
+ free(d);
+}
+
static int prepare_to_commit(const char *index_file, const char *prefix,
struct commit *current_head,
struct wt_status *s,
@@ -991,7 +1001,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
s->use_color = 0;
committable = run_status(s->fp, index_file, prefix, 1, s);
s->use_color = saved_color_setting;
- string_list_clear(&s->change, 1);
+ string_list_clear_func(&s->change, change_data_free);
} else {
struct object_id oid;
const char *parent = "HEAD";
@@ -1380,8 +1390,6 @@ static int parse_and_validate_options(int argc, const char *argv[],
if (0 <= edit_flag)
use_editor = edit_flag;
- cleanup_mode = get_cleanup_mode(cleanup_arg, use_editor);
-
handle_untracked_files_arg(s);
if (all && argc > 0)
@@ -1629,8 +1637,10 @@ static int git_commit_config(const char *k, const char *v,
include_status = git_config_bool(k, v);
return 0;
}
- if (!strcmp(k, "commit.cleanup"))
- return git_config_string(&cleanup_arg, k, v);
+ if (!strcmp(k, "commit.cleanup")) {
+ FREE_AND_NULL(cleanup_config);
+ return git_config_string(&cleanup_config, k, v);
+ }
if (!strcmp(k, "commit.gpgsign")) {
sign_commit = git_config_bool(k, v) ? "" : NULL;
return 0;
@@ -1651,6 +1661,7 @@ int cmd_commit(int argc,
struct repository *repo UNUSED)
{
static struct wt_status s;
+ static const char *cleanup_arg = NULL;
static struct option builtin_commit_options[] = {
OPT__QUIET(&quiet, N_("suppress summary after successful commit")),
OPT__VERBOSE(&verbose, N_("show diff in commit message template")),
@@ -1750,6 +1761,12 @@ int cmd_commit(int argc,
if (verbose == -1)
verbose = (config_commit_verbose < 0) ? 0 : config_commit_verbose;
+ if (cleanup_arg) {
+ free(cleanup_config);
+ cleanup_config = xstrdup(cleanup_arg);
+ }
+ cleanup_mode = get_cleanup_mode(cleanup_config, use_editor);
+
if (dry_run)
return dry_run_commit(argv, prefix, current_head, &s);
index_file = prepare_index(argv, prefix, current_head, 0);
diff --git a/builtin/config.c b/builtin/config.c
index cba7022108..16e6e30555 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -826,7 +826,8 @@ static void display_options_init(struct config_display_options *opts)
}
}
-static int cmd_config_list(int argc, const char **argv, const char *prefix)
+static int cmd_config_list(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
struct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT;
@@ -861,7 +862,8 @@ static int cmd_config_list(int argc, const char **argv, const char *prefix)
return 0;
}
-static int cmd_config_get(int argc, const char **argv, const char *prefix)
+static int cmd_config_get(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
struct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT;
@@ -915,7 +917,8 @@ static int cmd_config_get(int argc, const char **argv, const char *prefix)
return ret;
}
-static int cmd_config_set(int argc, const char **argv, const char *prefix)
+static int cmd_config_set(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
const char *value_pattern = NULL, *comment_arg = NULL;
@@ -973,7 +976,8 @@ static int cmd_config_set(int argc, const char **argv, const char *prefix)
return ret;
}
-static int cmd_config_unset(int argc, const char **argv, const char *prefix)
+static int cmd_config_unset(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
const char *value_pattern = NULL;
@@ -1010,7 +1014,8 @@ static int cmd_config_unset(int argc, const char **argv, const char *prefix)
return ret;
}
-static int cmd_config_rename_section(int argc, const char **argv, const char *prefix)
+static int cmd_config_rename_section(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
struct option opts[] = {
@@ -1039,7 +1044,8 @@ out:
return ret;
}
-static int cmd_config_remove_section(int argc, const char **argv, const char *prefix)
+static int cmd_config_remove_section(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
struct option opts[] = {
@@ -1099,7 +1105,8 @@ static int show_editor(struct config_location_options *opts)
return 0;
}
-static int cmd_config_edit(int argc, const char **argv, const char *prefix)
+static int cmd_config_edit(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT;
struct option opts[] = {
@@ -1395,7 +1402,7 @@ out:
int cmd_config(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
parse_opt_subcommand_fn *subcommand = NULL;
struct option subcommand_opts[] = {
@@ -1422,7 +1429,7 @@ int cmd_config(int argc,
if (subcommand) {
argc = parse_options(argc, argv, prefix, subcommand_opts, builtin_config_usage,
PARSE_OPT_SUBCOMMAND_OPTIONAL|PARSE_OPT_KEEP_UNKNOWN_OPT);
- return subcommand(argc, argv, prefix);
+ return subcommand(argc, argv, prefix, repo);
}
return cmd_config_actions(argc, argv, prefix);
diff --git a/builtin/count-objects.c b/builtin/count-objects.c
index 04d80887e0..1e89148ed7 100644
--- a/builtin/count-objects.c
+++ b/builtin/count-objects.c
@@ -67,7 +67,7 @@ static int count_loose(const struct object_id *oid, const char *path,
else {
loose_size += on_disk_bytes(st);
loose++;
- if (verbose && has_object_pack(oid))
+ if (verbose && has_object_pack(the_repository, oid))
packed_loose++;
}
return 0;
diff --git a/builtin/credential-cache.c b/builtin/credential-cache.c
index 5de8b9123b..7f733cb756 100644
--- a/builtin/credential-cache.c
+++ b/builtin/credential-cache.c
@@ -30,7 +30,7 @@ static int connection_fatally_broken(int error)
static int connection_closed(int error)
{
- return (error == ECONNRESET);
+ return error == ECONNRESET || error == ECONNABORTED;
}
static int connection_fatally_broken(int error)
@@ -189,7 +189,8 @@ int cmd_credential_cache(int argc,
#else
-int cmd_credential_cache(int argc, const char **argv, const char *prefix)
+int cmd_credential_cache(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
const char * const usage[] = {
"git credential-cache [options] <action>",
diff --git a/builtin/describe.c b/builtin/describe.c
index 7330a77b38..e2e73f3d75 100644
--- a/builtin/describe.c
+++ b/builtin/describe.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "environment.h"
@@ -366,6 +368,13 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
struct commit_name **slot;
seen_commits++;
+
+ if (match_cnt == max_candidates ||
+ match_cnt == hashmap_get_size(&names)) {
+ gave_up_on = c;
+ break;
+ }
+
slot = commit_names_peek(&commit_names, c);
n = slot ? *slot : NULL;
if (n) {
@@ -381,10 +390,6 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
if (n->prio == 2)
annotated_cnt++;
}
- else {
- gave_up_on = c;
- break;
- }
}
for (cur_match = 0; cur_match < match_cnt; cur_match++) {
struct possible_tag *t = &all_matches[cur_match];
@@ -470,9 +475,8 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
fprintf(stderr, _("traversed %lu commits\n"), seen_commits);
if (gave_up_on) {
fprintf(stderr,
- _("more than %i tags found; listed %i most recent\n"
- "gave up search at %s\n"),
- max_candidates, max_candidates,
+ _("found %i tags; gave up search at %s\n"),
+ max_candidates,
oid_to_hex(&gave_up_on->object.oid));
}
}
diff --git a/builtin/diff-files.c b/builtin/diff-files.c
index e0e0ccec23..604b04bb2c 100644
--- a/builtin/diff-files.c
+++ b/builtin/diff-files.c
@@ -3,7 +3,10 @@
*
* Copyright (C) Linus Torvalds, 2005
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "diff.h"
diff --git a/builtin/diff-index.c b/builtin/diff-index.c
index ad503624c0..ebc824602e 100644
--- a/builtin/diff-index.c
+++ b/builtin/diff-index.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "diff.h"
diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c
index 4b6656bb9f..40804e7b48 100644
--- a/builtin/diff-tree.c
+++ b/builtin/diff-tree.c
@@ -1,4 +1,5 @@
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "config.h"
#include "diff.h"
diff --git a/builtin/diff.c b/builtin/diff.c
index dca52d4221..a4fffee42c 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -3,7 +3,10 @@
*
* Copyright (c) 2006 Junio C Hamano
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "ewah/ewok.h"
@@ -628,6 +631,5 @@ int cmd_diff(int argc,
release_revisions(&rev);
object_array_clear(&ent);
symdiff_release(&sdiff);
- UNLEAK(blob);
return result;
}
diff --git a/builtin/difftool.c b/builtin/difftool.c
index 5772e82106..03a8bb92a9 100644
--- a/builtin/difftool.c
+++ b/builtin/difftool.c
@@ -11,7 +11,9 @@
*
* Copyright (C) 2016 Johannes Schindelin
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "abspath.h"
@@ -340,7 +342,7 @@ static void write_file_in_directory(struct strbuf *dir, size_t dir_len,
/* Write the file contents for the left and right sides of the difftool
* dir-diff representation for submodules and symlinks. Symlinks and submodules
* are written as regular text files so that external diff tools can diff them
- * as text files, resulting in behavior that is analogous to to what "git diff"
+ * as text files, resulting in behavior that is analogous to what "git diff"
* displays for symlink and submodule diffs.
*/
static void write_standin_files(struct pair_entry *entry,
@@ -364,7 +366,8 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
char *lbase_dir = NULL, *rbase_dir = NULL;
size_t ldir_len, rdir_len, wtdir_len;
const char *workdir, *tmp;
- int ret = 0, i;
+ int ret = 0;
+ size_t i;
FILE *fp = NULL;
struct hashmap working_tree_dups = HASHMAP_INIT(working_tree_entry_cmp,
NULL);
@@ -376,7 +379,8 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
struct checkout lstate, rstate;
int err = 0;
struct child_process cmd = CHILD_PROCESS_INIT;
- struct hashmap wt_modified, tmp_modified;
+ struct hashmap wt_modified = HASHMAP_INIT(path_entry_cmp, NULL);
+ struct hashmap tmp_modified = HASHMAP_INIT(path_entry_cmp, NULL);
int indices_loaded = 0;
workdir = repo_get_work_tree(the_repository);
@@ -601,9 +605,6 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
* in the common case of --symlinks and the difftool updating
* files through the symlink.
*/
- hashmap_init(&wt_modified, path_entry_cmp, NULL, wtindex.cache_nr);
- hashmap_init(&tmp_modified, path_entry_cmp, NULL, wtindex.cache_nr);
-
for (i = 0; i < wtindex.cache_nr; i++) {
struct hashmap_entry dummy;
const char *name = wtindex.cache[i]->name;
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index e17f262e8e..a5c82eef1d 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -3,7 +3,10 @@
*
* Copyright (C) 2007 Johannes E. Schindelin
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "gettext.h"
diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index 1e7ab67f6e..0f86392761 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "abspath.h"
#include "environment.h"
@@ -13,6 +15,7 @@
#include "delta.h"
#include "pack.h"
#include "path.h"
+#include "read-cache-ll.h"
#include "refs.h"
#include "csum-file.h"
#include "quote.h"
@@ -179,6 +182,7 @@ static unsigned long branch_load_count;
static int failure;
static FILE *pack_edges;
static unsigned int show_stats = 1;
+static unsigned int quiet;
static int global_argc;
static const char **global_argv;
static const char *global_prefix;
@@ -765,6 +769,7 @@ static void start_packfile(void)
p->pack_fd = pack_fd;
p->do_not_close = 1;
+ p->repo = the_repository;
pack_file = hashfd(pack_fd, p->pack_name);
pack_data = p;
@@ -805,7 +810,7 @@ static char *keep_pack(const char *curr_index_name)
struct strbuf name = STRBUF_INIT;
int keep_fd;
- odb_pack_name(&name, pack_data->hash, "keep");
+ odb_pack_name(pack_data->repo, &name, pack_data->hash, "keep");
keep_fd = odb_pack_keep(name.buf);
if (keep_fd < 0)
die_errno("cannot create keep file");
@@ -813,11 +818,11 @@ static char *keep_pack(const char *curr_index_name)
if (close(keep_fd))
die_errno("failed to write keep file");
- odb_pack_name(&name, pack_data->hash, "pack");
+ odb_pack_name(pack_data->repo, &name, pack_data->hash, "pack");
if (finalize_object_file(pack_data->pack_name, name.buf))
die("cannot store pack file");
- odb_pack_name(&name, pack_data->hash, "idx");
+ odb_pack_name(pack_data->repo, &name, pack_data->hash, "idx");
if (finalize_object_file(curr_index_name, name.buf))
die("cannot store index file");
free((void *)curr_index_name);
@@ -831,7 +836,7 @@ static void unkeep_all_packs(void)
for (k = 0; k < pack_id; k++) {
struct packed_git *p = all_packs[k];
- odb_pack_name(&name, p->hash, "keep");
+ odb_pack_name(p->repo, &name, p->hash, "keep");
unlink_or_warn(name.buf);
}
strbuf_release(&name);
@@ -888,7 +893,7 @@ static void end_packfile(void)
idx_name = keep_pack(create_index());
/* Register the packfile with core git's machinery. */
- new_p = add_packed_git(idx_name, strlen(idx_name), 1);
+ new_p = add_packed_git(pack_data->repo, idx_name, strlen(idx_name), 1);
if (!new_p)
die("core git rejected index %s", idx_name);
all_packs[pack_id] = new_p;
@@ -966,8 +971,7 @@ static int store_object(
if (e->idx.offset) {
duplicate_count_by_type[type]++;
return 1;
- } else if (find_sha1_pack(oid.hash,
- get_all_packs(the_repository))) {
+ } else if (find_oid_pack(&oid, get_all_packs(the_repository))) {
e->type = type;
e->pack_id = MAX_PACK_ID;
e->idx.offset = 1; /* just not zero! */
@@ -1102,7 +1106,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
|| (pack_size + PACK_SIZE_THRESHOLD + len) < pack_size)
cycle_packfile();
- the_hash_algo->init_fn(&checkpoint.ctx);
+ the_hash_algo->unsafe_init_fn(&checkpoint.ctx);
hashfile_checkpoint(pack_file, &checkpoint);
offset = checkpoint.offset;
@@ -1167,8 +1171,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
duplicate_count_by_type[OBJ_BLOB]++;
truncate_pack(&checkpoint);
- } else if (find_sha1_pack(oid.hash,
- get_all_packs(the_repository))) {
+ } else if (find_oid_pack(&oid, get_all_packs(the_repository))) {
e->type = OBJ_BLOB;
e->pack_id = MAX_PACK_ID;
e->idx.offset = 1; /* just not zero! */
@@ -1604,7 +1607,19 @@ static int update_branch(struct branch *b)
struct ref_transaction *transaction;
struct object_id old_oid;
struct strbuf err = STRBUF_INIT;
-
+ static const char *replace_prefix = "refs/replace/";
+
+ if (starts_with(b->name, replace_prefix) &&
+ !strcmp(b->name + strlen(replace_prefix),
+ oid_to_hex(&b->oid))) {
+ if (!quiet)
+ warning("Dropping %s since it would point to "
+ "itself (i.e. to %s)",
+ b->name, oid_to_hex(&b->oid));
+ refs_delete_ref(get_main_ref_store(the_repository),
+ NULL, b->name, NULL, 0);
+ return 0;
+ }
if (is_null_oid(&b->oid)) {
if (b->delete)
refs_delete_ref(get_main_ref_store(the_repository),
@@ -1636,7 +1651,7 @@ static int update_branch(struct branch *b)
}
}
transaction = ref_store_transaction_begin(get_main_ref_store(the_repository),
- &err);
+ 0, &err);
if (!transaction ||
ref_transaction_update(transaction, b->name, &b->oid, &old_oid,
NULL, NULL, 0, msg, &err) ||
@@ -1671,7 +1686,7 @@ static void dump_tags(void)
struct ref_transaction *transaction;
transaction = ref_store_transaction_begin(get_main_ref_store(the_repository),
- &err);
+ 0, &err);
if (!transaction) {
failure |= error("%s", err.buf);
goto cleanup;
@@ -2414,6 +2429,9 @@ static void file_change_m(const char *p, struct branch *b)
tree_content_replace(&b->branch_tree, &oid, mode, NULL);
return;
}
+
+ if (!verify_path(path.buf, mode))
+ die("invalid path '%s'", path.buf);
tree_content_set(&b->branch_tree, path.buf, &oid, mode, NULL);
}
@@ -2451,6 +2469,8 @@ static void file_change_cr(const char *p, struct branch *b, int rename)
leaf.tree);
return;
}
+ if (!verify_path(dest.buf, leaf.versions[1].mode))
+ die("invalid path '%s'", dest.buf);
tree_content_set(&b->branch_tree, dest.buf,
&leaf.versions[1].oid,
leaf.versions[1].mode,
@@ -3390,6 +3410,7 @@ static int parse_one_option(const char *option)
option_export_pack_edges(option);
} else if (!strcmp(option, "quiet")) {
show_stats = 0;
+ quiet = 1;
} else if (!strcmp(option, "stats")) {
show_stats = 1;
} else if (!strcmp(option, "allow-unsafe-features")) {
@@ -3540,7 +3561,7 @@ static void parse_argv(void)
int cmd_fast_import(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
unsigned int i;
@@ -3661,7 +3682,7 @@ int cmd_fast_import(int argc,
fprintf(stderr, " pools: %10lu KiB\n", (unsigned long)((tree_entry_allocd + fi_mem_pool.pool_alloc) /1024));
fprintf(stderr, " objects: %10" PRIuMAX " KiB\n", (alloc_count*sizeof(struct object_entry))/1024);
fprintf(stderr, "---------------------------------------------------------------------\n");
- pack_report();
+ pack_report(repo);
fprintf(stderr, "---------------------------------------------------------------------\n");
fprintf(stderr, "\n");
}
diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c
index 62e8c3aa6b..bed2816c2d 100644
--- a/builtin/fetch-pack.c
+++ b/builtin/fetch-pack.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "gettext.h"
#include "hex.h"
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 80a64d0d26..fe2b26c74a 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -1,7 +1,10 @@
/*
* "git fetch"
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "advice.h"
#include "config.h"
@@ -454,14 +457,10 @@ static void filter_prefetch_refspec(struct refspec *rs)
ref_namespace[NAMESPACE_TAGS].ref))) {
int j;
- free(rs->items[i].src);
- free(rs->items[i].dst);
- free(rs->raw[i]);
+ refspec_item_clear(&rs->items[i]);
- for (j = i + 1; j < rs->nr; j++) {
+ for (j = i + 1; j < rs->nr; j++)
rs->items[j - 1] = rs->items[j];
- rs->raw[j - 1] = rs->raw[j];
- }
rs->nr--;
i--;
continue;
@@ -669,7 +668,7 @@ static int s_update_ref(const char *action,
*/
if (!transaction) {
transaction = our_transaction = ref_store_transaction_begin(get_main_ref_store(the_repository),
- &err);
+ 0, &err);
if (!transaction) {
ret = STORE_REF_ERROR_OTHER;
goto out;
@@ -1578,6 +1577,135 @@ static int backfill_tags(struct display_state *display_state,
return retcode;
}
+static const char *strip_refshead(const char *name){
+ skip_prefix(name, "refs/heads/", &name);
+ return name;
+}
+
+static void set_head_advice_msg(const char *remote, const char *head_name)
+{
+ const char message_advice_set_head[] =
+ N_("Run 'git remote set-head %s %s' to follow the change, or set\n"
+ "'remote.%s.followRemoteHEAD' configuration option to a different value\n"
+ "if you do not want to see this message. Specifically running\n"
+ "'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n"
+ "will disable the warning until the remote changes HEAD to something else.");
+
+ advise_if_enabled(ADVICE_FETCH_SET_HEAD_WARN, _(message_advice_set_head),
+ remote, head_name, remote, remote, head_name);
+}
+
+static void report_set_head(const char *remote, const char *head_name,
+ struct strbuf *buf_prev, int updateres) {
+ struct strbuf buf_prefix = STRBUF_INIT;
+ const char *prev_head = NULL;
+
+ strbuf_addf(&buf_prefix, "refs/remotes/%s/", remote);
+ skip_prefix(buf_prev->buf, buf_prefix.buf, &prev_head);
+
+ if (prev_head && strcmp(prev_head, head_name)) {
+ printf("'HEAD' at '%s' is '%s', but we have '%s' locally.\n",
+ remote, head_name, prev_head);
+ set_head_advice_msg(remote, head_name);
+ }
+ else if (updateres && buf_prev->len) {
+ printf("'HEAD' at '%s' is '%s', "
+ "but we have a detached HEAD pointing to '%s' locally.\n",
+ remote, head_name, buf_prev->buf);
+ set_head_advice_msg(remote, head_name);
+ }
+ strbuf_release(&buf_prefix);
+}
+
+static int set_head(const struct ref *remote_refs, int follow_remote_head,
+ const char *no_warn_branch)
+{
+ int result = 0, create_only, is_bare, was_detached;
+ struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT,
+ b_local_head = STRBUF_INIT;
+ const char *remote = gtransport->remote->name;
+ char *head_name = NULL;
+ struct ref *ref, *matches;
+ struct ref *fetch_map = NULL, **fetch_map_tail = &fetch_map;
+ struct refspec_item refspec = {
+ .force = 0,
+ .pattern = 1,
+ .src = (char *) "refs/heads/*",
+ .dst = (char *) "refs/heads/*",
+ };
+ struct string_list heads = STRING_LIST_INIT_DUP;
+ struct ref_store *refs = get_main_ref_store(the_repository);
+
+ get_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0);
+ matches = guess_remote_head(find_ref_by_name(remote_refs, "HEAD"),
+ fetch_map, 1);
+ for (ref = matches; ref; ref = ref->next) {
+ string_list_append(&heads, strip_refshead(ref->name));
+ }
+
+ if (follow_remote_head == FOLLOW_REMOTE_NEVER)
+ goto cleanup;
+
+ if (!heads.nr)
+ result = 1;
+ else if (heads.nr > 1)
+ result = 1;
+ else
+ head_name = xstrdup(heads.items[0].string);
+
+ if (!head_name)
+ goto cleanup;
+ is_bare = is_bare_repository();
+ create_only = follow_remote_head == FOLLOW_REMOTE_ALWAYS ? 0 : !is_bare;
+ if (is_bare) {
+ strbuf_addstr(&b_head, "HEAD");
+ strbuf_addf(&b_remote_head, "refs/heads/%s", head_name);
+ } else {
+ strbuf_addf(&b_head, "refs/remotes/%s/HEAD", remote);
+ strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", remote, head_name);
+ }
+ /* make sure it's valid */
+ if (!is_bare && !refs_ref_exists(refs, b_remote_head.buf)) {
+ result = 1;
+ goto cleanup;
+ }
+ was_detached = refs_update_symref_extended(refs, b_head.buf, b_remote_head.buf,
+ "fetch", &b_local_head, create_only);
+ if (was_detached == -1) {
+ result = 1;
+ goto cleanup;
+ }
+ if (verbosity >= 0 &&
+ follow_remote_head == FOLLOW_REMOTE_WARN &&
+ (!no_warn_branch || strcmp(no_warn_branch, head_name)))
+ report_set_head(remote, head_name, &b_local_head, was_detached);
+
+cleanup:
+ free(head_name);
+ free_refs(fetch_map);
+ free_refs(matches);
+ string_list_clear(&heads, 0);
+ strbuf_release(&b_head);
+ strbuf_release(&b_local_head);
+ strbuf_release(&b_remote_head);
+ return result;
+}
+
+static int uses_remote_tracking(struct transport *transport, struct refspec *rs)
+{
+ if (!remote_is_configured(transport->remote, 0))
+ return 0;
+
+ if (!rs->nr)
+ rs = &transport->remote->fetch;
+
+ for (int i = 0; i < rs->nr; i++)
+ if (rs->items[i].dst)
+ return 1;
+
+ return 0;
+}
+
static int do_fetch(struct transport *transport,
struct refspec *rs,
const struct fetch_config *config)
@@ -1647,6 +1775,11 @@ static int do_fetch(struct transport *transport,
"refs/tags/");
}
+ if (uses_remote_tracking(transport, rs)) {
+ must_list_refs = 1;
+ strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD");
+ }
+
if (must_list_refs) {
trace2_region_enter("fetch", "remote_refs", the_repository);
remote_refs = transport_get_remote_refs(transport,
@@ -1671,7 +1804,7 @@ static int do_fetch(struct transport *transport,
if (atomic_fetch) {
transaction = ref_store_transaction_begin(get_main_ref_store(the_repository),
- &err);
+ 0, &err);
if (!transaction) {
retcode = -1;
goto cleanup;
@@ -1791,6 +1924,13 @@ static int do_fetch(struct transport *transport,
"you need to specify exactly one branch with the --set-upstream option"));
}
}
+ if (set_head(remote_refs, transport->remote->follow_remote_head,
+ transport->remote->no_warn_branch))
+ ;
+ /*
+ * Way too many cases where this can go wrong
+ * so let's just fail silently for now.
+ */
cleanup:
if (retcode) {
@@ -1981,6 +2121,8 @@ static int fetch_multiple(struct string_list *list, int max_children,
strvec_pushl(&argv, "-c", "fetch.bundleURI=",
"fetch", "--append", "--no-auto-gc",
"--no-write-commit-graph", NULL);
+ for (i = 0; i < server_options.nr; i++)
+ strvec_pushf(&argv, "--server-option=%s", server_options.items[i].string);
add_options_to_argv(&argv, config);
if (max_children != 1 && list->nr != 1) {
@@ -2214,8 +2356,8 @@ int cmd_fetch(int argc,
N_("deepen history of shallow clone")),
OPT_STRING(0, "shallow-since", &deepen_since, N_("time"),
N_("deepen history of shallow repository based on time")),
- OPT_STRING_LIST(0, "shallow-exclude", &deepen_not, N_("revision"),
- N_("deepen history of shallow clone, excluding rev")),
+ OPT_STRING_LIST(0, "shallow-exclude", &deepen_not, N_("ref"),
+ N_("deepen history of shallow clone, excluding ref")),
OPT_INTEGER(0, "deepen", &deepen_relative,
N_("deepen history of shallow clone")),
OPT_SET_INT_F(0, "unshallow", &unshallow,
diff --git a/builtin/for-each-repo.c b/builtin/for-each-repo.c
index fae7f91cf1..325a7925f1 100644
--- a/builtin/for-each-repo.c
+++ b/builtin/for-each-repo.c
@@ -1,4 +1,5 @@
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "config.h"
#include "gettext.h"
@@ -36,7 +37,7 @@ int cmd_for_each_repo(int argc,
{
static const char *config_key = NULL;
int keep_going = 0;
- int i, result = 0;
+ int result = 0;
const struct string_list *values;
int err;
@@ -61,7 +62,7 @@ int cmd_for_each_repo(int argc,
else if (err)
return 0;
- for (i = 0; i < values->nr; i++) {
+ for (size_t i = 0; i < values->nr; i++) {
int ret = run_command_on_repo(values->items[i].string, argc, argv);
if (ret) {
if (!keep_going)
diff --git a/builtin/fsck.c b/builtin/fsck.c
index 7f4e2f0414..0196c54eb6 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -150,7 +150,7 @@ static int mark_object(struct object *obj, enum object_type type,
return 0;
obj->flags |= REACHABLE;
- if (is_promisor_object(&obj->oid))
+ if (is_promisor_object(the_repository, &obj->oid))
/*
* Further recursion does not need to be performed on this
* object since it is a promisor object (so it does not need to
@@ -270,9 +270,9 @@ static void check_reachable_object(struct object *obj)
* do a full fsck
*/
if (!(obj->flags & HAS_OBJ)) {
- if (is_promisor_object(&obj->oid))
+ if (is_promisor_object(the_repository, &obj->oid))
return;
- if (has_object_pack(&obj->oid))
+ if (has_object_pack(the_repository, &obj->oid))
return; /* it is in pack - forget about it */
printf_ln(_("missing %s %s"),
printable_type(&obj->oid, obj->type),
@@ -391,7 +391,10 @@ static void check_connectivity(void)
* traversal.
*/
for_each_loose_object(mark_loose_unreachable_referents, NULL, 0);
- for_each_packed_object(mark_packed_unreachable_referents, NULL, 0);
+ for_each_packed_object(the_repository,
+ mark_packed_unreachable_referents,
+ NULL,
+ 0);
}
/* Look up all the requirements, warn about missing objects.. */
@@ -488,7 +491,7 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
refname, timestamp);
obj->flags |= USED;
mark_object_reachable(obj);
- } else if (!is_promisor_object(oid)) {
+ } else if (!is_promisor_object(the_repository, oid)) {
error(_("%s: invalid reflog entry %s"),
refname, oid_to_hex(oid));
errors_found |= ERROR_REACHABLE;
@@ -531,7 +534,7 @@ static int fsck_handle_ref(const char *refname, const char *referent UNUSED, con
obj = parse_object(the_repository, oid);
if (!obj) {
- if (is_promisor_object(oid)) {
+ if (is_promisor_object(the_repository, oid)) {
/*
* Increment default_refs anyway, because this is a
* valid ref.
@@ -966,7 +969,8 @@ int cmd_fsck(int argc,
if (connectivity_only) {
for_each_loose_object(mark_loose_for_connectivity, NULL, 0);
- for_each_packed_object(mark_packed_for_connectivity, NULL, 0);
+ for_each_packed_object(the_repository,
+ mark_packed_for_connectivity, NULL, 0);
} else {
prepare_alt_odb(the_repository);
for (odb = the_repository->objects->odb; odb; odb = odb->next)
@@ -1011,7 +1015,7 @@ int cmd_fsck(int argc,
&oid);
if (!obj || !(obj->flags & HAS_OBJ)) {
- if (is_promisor_object(&oid))
+ if (is_promisor_object(the_repository, &oid))
continue;
error(_("%s: object missing"), oid_to_hex(&oid));
errors_found |= ERROR_OBJECT;
diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c
index f3f6bd330b..029dc64d6c 100644
--- a/builtin/fsmonitor--daemon.c
+++ b/builtin/fsmonitor--daemon.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "abspath.h"
#include "config.h"
diff --git a/builtin/gc.c b/builtin/gc.c
index d52735354c..a9b1c36de2 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -9,7 +9,10 @@
*
* Copyright (c) 2006 Shawn O. Pearce
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "abspath.h"
#include "date.h"
@@ -138,6 +141,11 @@ struct gc_config {
char *repack_filter_to;
unsigned long big_pack_threshold;
unsigned long max_delta_cache_size;
+ /*
+ * Remove this member from gc_config once repo_settings is passed
+ * through the callchain.
+ */
+ size_t delta_base_cache_limit;
};
#define GC_CONFIG_INIT { \
@@ -153,6 +161,7 @@ struct gc_config {
.prune_expire = xstrdup("2.weeks.ago"), \
.prune_worktrees_expire = xstrdup("3.months.ago"), \
.max_delta_cache_size = DEFAULT_DELTA_CACHE_SIZE, \
+ .delta_base_cache_limit = DEFAULT_DELTA_BASE_CACHE_LIMIT, \
}
static void gc_config_release(struct gc_config *cfg)
@@ -168,6 +177,7 @@ static void gc_config(struct gc_config *cfg)
{
const char *value;
char *owned = NULL;
+ unsigned long ulongval;
if (!git_config_get_value("gc.packrefs", &value)) {
if (value && !strcmp(value, "notbare"))
@@ -206,6 +216,9 @@ static void gc_config(struct gc_config *cfg)
git_config_get_ulong("gc.bigpackthreshold", &cfg->big_pack_threshold);
git_config_get_ulong("pack.deltacachesize", &cfg->max_delta_cache_size);
+ if (!git_config_get_ulong("core.deltabasecachelimit", &ulongval))
+ cfg->delta_base_cache_limit = ulongval;
+
if (!git_config_get_string("gc.repackfilter", &owned)) {
free(cfg->repack_filter);
cfg->repack_filter = owned;
@@ -416,7 +429,7 @@ static uint64_t estimate_repack_memory(struct gc_config *cfg,
* read_sha1_file() (either at delta calculation phase, or
* writing phase) also fills up the delta base cache
*/
- heap += delta_base_cache_limit;
+ heap += cfg->delta_base_cache_limit;
/* and of course pack-objects has its own delta cache */
heap += cfg->max_delta_cache_size;
@@ -1561,7 +1574,8 @@ static int task_option_parse(const struct option *opt UNUSED,
return 0;
}
-static int maintenance_run(int argc, const char **argv, const char *prefix)
+static int maintenance_run(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int i;
struct maintenance_run_opts opts = MAINTENANCE_RUN_OPTS_INIT;
@@ -1623,7 +1637,8 @@ static char const * const builtin_maintenance_register_usage[] = {
NULL
};
-static int maintenance_register(int argc, const char **argv, const char *prefix)
+static int maintenance_register(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
char *config_file = NULL;
struct option options[] = {
@@ -1687,7 +1702,8 @@ static char const * const builtin_maintenance_unregister_usage[] = {
NULL
};
-static int maintenance_unregister(int argc, const char **argv, const char *prefix)
+static int maintenance_unregister(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int force = 0;
char *config_file = NULL;
@@ -2890,8 +2906,17 @@ static int update_background_schedule(const struct maintenance_start_opts *opts,
char *lock_path = xstrfmt("%s/schedule", the_repository->objects->odb->path);
if (hold_lock_file_for_update(&lk, lock_path, LOCK_NO_DEREF) < 0) {
+ if (errno == EEXIST)
+ error(_("unable to create '%s.lock': %s.\n\n"
+ "Another scheduled git-maintenance(1) process seems to be running in this\n"
+ "repository. Please make sure no other maintenance processes are running and\n"
+ "then try again. If it still fails, a git-maintenance(1) process may have\n"
+ "crashed in this repository earlier: remove the file manually to continue."),
+ absolute_path(lock_path), strerror(errno));
+ else
+ error_errno(_("cannot acquire lock for scheduled background maintenance"));
free(lock_path);
- return error(_("another process is scheduling background maintenance"));
+ return -1;
}
for (i = 1; i < ARRAY_SIZE(scheduler_fn); i++) {
@@ -2917,7 +2942,8 @@ static const char *const builtin_maintenance_start_usage[] = {
NULL
};
-static int maintenance_start(int argc, const char **argv, const char *prefix)
+static int maintenance_start(int argc, const char **argv, const char *prefix,
+ struct repository *repo)
{
struct maintenance_start_opts opts = { 0 };
struct option options[] = {
@@ -2940,7 +2966,7 @@ static int maintenance_start(int argc, const char **argv, const char *prefix)
if (update_background_schedule(&opts, 1))
die(_("failed to set up maintenance schedule"));
- if (maintenance_register(ARRAY_SIZE(register_args)-1, register_args, NULL))
+ if (maintenance_register(ARRAY_SIZE(register_args)-1, register_args, NULL, repo))
warning(_("failed to add repo to global config"));
return 0;
}
@@ -2950,7 +2976,8 @@ static const char *const builtin_maintenance_stop_usage[] = {
NULL
};
-static int maintenance_stop(int argc, const char **argv, const char *prefix)
+static int maintenance_stop(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct option options[] = {
OPT_END()
@@ -2970,7 +2997,7 @@ static const char * const builtin_maintenance_usage[] = {
int cmd_maintenance(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
parse_opt_subcommand_fn *fn = NULL;
struct option builtin_maintenance_options[] = {
@@ -2984,5 +3011,5 @@ int cmd_maintenance(int argc,
argc = parse_options(argc, argv, prefix, builtin_maintenance_options,
builtin_maintenance_usage, 0);
- return fn(argc, argv, prefix);
+ return fn(argc, argv, prefix, repo);
}
diff --git a/builtin/grep.c b/builtin/grep.c
index f17d46a06e..d00ee76f24 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -3,7 +3,10 @@
*
* Copyright (c) 2006 Junio C Hamano
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "abspath.h"
#include "gettext.h"
@@ -906,6 +909,7 @@ int cmd_grep(int argc,
int dummy;
int use_index = 1;
int allow_revs;
+ int ret;
struct option options[] = {
OPT_BOOL(0, "cached", &cached,
@@ -1172,8 +1176,10 @@ int cmd_grep(int argc,
* Optimize out the case where the amount of matches is limited to zero.
* We do this to keep results consistent with GNU grep(1).
*/
- if (opt.max_count == 0)
- return 1;
+ if (opt.max_count == 0) {
+ ret = 1;
+ goto out;
+ }
if (show_in_pager) {
if (num_threads > 1)
@@ -1267,10 +1273,14 @@ int cmd_grep(int argc,
hit |= wait_all();
if (hit && show_in_pager)
run_pager(&opt, prefix);
+
+ ret = !hit;
+
+out:
clear_pathspec(&pathspec);
string_list_clear(&path_list, 0);
free_grep_patterns(&opt);
object_array_clear(&list);
free_repos();
- return !hit;
+ return ret;
}
diff --git a/builtin/help.c b/builtin/help.c
index 4a5a079070..05136279cf 100644
--- a/builtin/help.c
+++ b/builtin/help.c
@@ -1,8 +1,9 @@
-
/*
* Builtin help command
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "config.h"
#include "exec-cmd.h"
@@ -129,7 +130,6 @@ static void list_config_help(enum show_config_type type)
struct string_list keys = STRING_LIST_INIT_DUP;
struct string_list keys_uniq = STRING_LIST_INIT_DUP;
struct string_list_item *item;
- int i;
for (p = config_name_list; *p; p++) {
const char *var = *p;
@@ -156,7 +156,7 @@ static void list_config_help(enum show_config_type type)
e->prefix, e->placeholder);
string_list_sort(&keys);
- for (i = 0; i < keys.nr; i++) {
+ for (size_t i = 0; i < keys.nr; i++) {
const char *var = keys.items[i].string;
const char *wildcard, *tag, *cut;
const char *dot = NULL;
@@ -551,12 +551,12 @@ static void show_html_page(const char *page)
open_html(page_path.buf);
}
-static const char *check_git_cmd(const char* cmd)
+static char *check_git_cmd(const char *cmd)
{
char *alias;
if (is_git_command(cmd))
- return cmd;
+ return xstrdup(cmd);
alias = alias_lookup(cmd);
if (alias) {
@@ -589,14 +589,13 @@ static const char *check_git_cmd(const char* cmd)
die(_("bad alias.%s string: %s"), cmd,
split_cmdline_strerror(count));
free(argv);
- UNLEAK(alias);
return alias;
}
if (exclude_guides)
return help_unknown_cmd(cmd);
- return cmd;
+ return xstrdup(cmd);
}
static void no_help_format(const char *opt_mode, enum help_format fmt)
@@ -642,6 +641,7 @@ int cmd_help(int argc,
{
int nongit;
enum help_format parsed_help_format;
+ char *command = NULL;
const char *page;
argc = parse_options(argc, argv, prefix, builtin_help_options,
@@ -713,9 +713,9 @@ int cmd_help(int argc,
if (help_format == HELP_FORMAT_NONE)
help_format = parse_help_format(DEFAULT_HELP_FORMAT);
- argv[0] = check_git_cmd(argv[0]);
+ command = check_git_cmd(argv[0]);
- page = cmd_to_page(argv[0]);
+ page = cmd_to_page(command);
switch (help_format) {
case HELP_FORMAT_NONE:
case HELP_FORMAT_MAN:
@@ -729,5 +729,6 @@ int cmd_help(int argc,
break;
}
+ free(command);
return 0;
}
diff --git a/builtin/hook.c b/builtin/hook.c
index 367ef3e0b8..672d2e37e8 100644
--- a/builtin/hook.c
+++ b/builtin/hook.c
@@ -19,7 +19,8 @@ static const char * const builtin_hook_run_usage[] = {
NULL
};
-static int run(int argc, const char **argv, const char *prefix)
+static int run(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int i;
struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT;
@@ -70,7 +71,7 @@ usage:
int cmd_hook(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
parse_opt_subcommand_fn *fn = NULL;
struct option builtin_hook_options[] = {
@@ -81,5 +82,5 @@ int cmd_hook(int argc,
argc = parse_options(argc, argv, NULL, builtin_hook_options,
builtin_hook_usage, 0);
- return fn(argc, argv, prefix);
+ return fn(argc, argv, prefix, repo);
}
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index e228c56ff2..0b62b2589f 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "delta.h"
@@ -9,6 +11,7 @@
#include "csum-file.h"
#include "blob.h"
#include "commit.h"
+#include "tag.h"
#include "tree.h"
#include "progress.h"
#include "fsck.h"
@@ -20,9 +23,14 @@
#include "object-file.h"
#include "object-store-ll.h"
#include "oid-array.h"
+#include "oidset.h"
+#include "path.h"
#include "replace-object.h"
+#include "tree-walk.h"
#include "promisor-remote.h"
+#include "run-command.h"
#include "setup.h"
+#include "strvec.h"
static const char index_pack_usage[] =
"git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--[no-]rev-index] [--verify] [--strict[=<msg-id>=<severity>...]] [--fsck-objects[=<msg-id>=<severity>...]] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
@@ -94,7 +102,7 @@ static LIST_HEAD(done_head);
static size_t base_cache_used;
static size_t base_cache_limit;
-struct thread_local {
+struct thread_local_data {
pthread_t thread;
int pack_fd;
};
@@ -117,7 +125,7 @@ static struct object_entry *objects;
static struct object_stat *obj_stat;
static struct ofs_delta_entry *ofs_deltas;
static struct ref_delta_entry *ref_deltas;
-static struct thread_local nothread_data;
+static struct thread_local_data nothread_data;
static int nr_objects;
static int nr_ofs_deltas;
static int nr_ref_deltas;
@@ -148,7 +156,14 @@ static uint32_t input_crc32;
static int input_fd, output_fd;
static const char *curr_pack;
-static struct thread_local *thread_data;
+/*
+ * outgoing_links is guarded by read_mutex, and record_outgoing_links is
+ * read-only in a thread.
+ */
+static struct oidset outgoing_links = OIDSET_INIT;
+static int record_outgoing_links;
+
+static struct thread_local_data *thread_data;
static int nr_dispatched;
static int threads_active;
@@ -390,7 +405,7 @@ static NORETURN void bad_object(off_t offset, const char *format, ...)
(uintmax_t)offset, buf);
}
-static inline struct thread_local *get_thread_data(void)
+static inline struct thread_local_data *get_thread_data(void)
{
if (HAVE_THREADS) {
if (threads_active)
@@ -401,7 +416,7 @@ static inline struct thread_local *get_thread_data(void)
return &nothread_data;
}
-static void set_thread_data(struct thread_local *data)
+static void set_thread_data(struct thread_local_data *data)
{
if (threads_active)
pthread_setspecific(key, data);
@@ -799,6 +814,68 @@ static int check_collison(struct object_entry *entry)
return 0;
}
+static void record_outgoing_link(const struct object_id *oid)
+{
+ oidset_insert(&outgoing_links, oid);
+}
+
+static void maybe_record_name_entry(const struct name_entry *entry)
+{
+ /*
+ * Checking only trees here results in a significantly faster packfile
+ * indexing, but the drawback is that if the packfile to be indexed
+ * references a local blob only directly (that is, never through a
+ * local tree), that local blob is in danger of being garbage
+ * collected. Such a situation may arise if we push local commits,
+ * including one with a change to a blob in the root tree, and then the
+ * server incorporates them into its main branch through a "rebase" or
+ * "squash" merge strategy, and then we fetch the new main branch from
+ * the server.
+ *
+ * This situation has not been observed yet - we have only noticed
+ * missing commits, not missing trees or blobs. (In fact, if it were
+ * believed that only missing commits are problematic, one could argue
+ * that we should also exclude trees during the outgoing link check;
+ * but it is safer to include them.)
+ *
+ * Due to the rarity of the situation (it has not been observed to
+ * happen in real life), and because the "penalty" in such a situation
+ * is merely to refetch the missing blob when it's needed (and this
+ * happens only once - when refetched, the blob goes into a promisor
+ * pack, so it won't be GC-ed, the tradeoff seems worth it.
+ */
+ if (S_ISDIR(entry->mode))
+ record_outgoing_link(&entry->oid);
+}
+
+static void do_record_outgoing_links(struct object *obj)
+{
+ if (obj->type == OBJ_TREE) {
+ struct tree *tree = (struct tree *)obj;
+ struct tree_desc desc;
+ struct name_entry entry;
+ if (init_tree_desc_gently(&desc, &tree->object.oid,
+ tree->buffer, tree->size, 0))
+ /*
+ * Error messages are given when packs are
+ * verified, so do not print any here.
+ */
+ return;
+ while (tree_entry_gently(&desc, &entry))
+ maybe_record_name_entry(&entry);
+ } else if (obj->type == OBJ_COMMIT) {
+ struct commit *commit = (struct commit *) obj;
+ struct commit_list *parents = commit->parents;
+
+ record_outgoing_link(get_commit_tree_oid(commit));
+ for (; parents; parents = parents->next)
+ record_outgoing_link(&parents->item->object.oid);
+ } else if (obj->type == OBJ_TAG) {
+ struct tag *tag = (struct tag *) obj;
+ record_outgoing_link(get_tagged_oid(tag));
+ }
+}
+
static void sha1_object(const void *data, struct object_entry *obj_entry,
unsigned long size, enum object_type type,
const struct object_id *oid)
@@ -845,7 +922,7 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
free(has_data);
}
- if (strict || do_fsck_object) {
+ if (strict || do_fsck_object || record_outgoing_links) {
read_lock();
if (type == OBJ_BLOB) {
struct blob *blob = lookup_blob(the_repository, oid);
@@ -877,6 +954,8 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
die(_("fsck error in packed object"));
if (strict && fsck_walk(obj, NULL, &fsck_options))
die(_("Not all child objects of %s are reachable"), oid_to_hex(&obj->oid));
+ if (record_outgoing_links)
+ do_record_outgoing_links(obj);
if (obj->type == OBJ_TREE) {
struct tree *item = (struct tree *) obj;
@@ -1238,7 +1317,7 @@ static void parse_pack_objects(unsigned char *hash)
* recursively checking if the resulting object is used as a base
* for some more deltas.
*/
-static void resolve_deltas(void)
+static void resolve_deltas(struct pack_idx_option *opts)
{
int i;
@@ -1254,10 +1333,9 @@ static void resolve_deltas(void)
nr_ref_deltas + nr_ofs_deltas);
nr_dispatched = 0;
- base_cache_limit = delta_base_cache_limit * nr_threads;
+ base_cache_limit = opts->delta_base_cache_limit * nr_threads;
if (nr_threads > 1 || getenv("GIT_FORCE_THREADS")) {
init_thread();
- work_lock();
for (i = 0; i < nr_threads; i++) {
int ret = pthread_create(&thread_data[i].thread, NULL,
threaded_second_pass, thread_data + i);
@@ -1265,7 +1343,6 @@ static void resolve_deltas(void)
die(_("unable to create thread: %s"),
strerror(ret));
}
- work_unlock();
for (i = 0; i < nr_threads; i++)
pthread_join(thread_data[i].thread, NULL);
cleanup_thread();
@@ -1479,7 +1556,7 @@ static void write_special_file(const char *suffix, const char *msg,
if (pack_name)
filename = derive_filename(pack_name, "pack", suffix, &name_buf);
else
- filename = odb_pack_name(&name_buf, hash, suffix);
+ filename = odb_pack_name(the_repository, &name_buf, hash, suffix);
fd = odb_pack_keep(filename);
if (fd < 0) {
@@ -1505,9 +1582,9 @@ static void rename_tmp_packfile(const char **final_name,
struct strbuf *name, unsigned char *hash,
const char *ext, int make_read_only_if_same)
{
- if (*final_name != curr_name) {
+ if (!*final_name || strcmp(*final_name, curr_name)) {
if (!*final_name)
- *final_name = odb_pack_name(name, hash, ext);
+ *final_name = odb_pack_name(the_repository, name, hash, ext);
if (finalize_object_file(curr_name, *final_name))
die(_("unable to rename temporary '*.%s' file to '%s'"),
ext, *final_name);
@@ -1552,7 +1629,8 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
if (do_fsck_object) {
struct packed_git *p;
- p = add_packed_git(final_index_name, strlen(final_index_name), 0);
+ p = add_packed_git(the_repository, final_index_name,
+ strlen(final_index_name), 0);
if (p)
install_packed_git(the_repository, p);
}
@@ -1603,6 +1681,10 @@ static int git_index_pack_config(const char *k, const char *v,
else
opts->flags &= ~WRITE_REV;
}
+ if (!strcmp(k, "core.deltabasecachelimit")) {
+ opts->delta_base_cache_limit = git_config_ulong(k, v, ctx->kvi);
+ return 0;
+ }
return git_default_config(k, v, ctx, cb);
}
@@ -1650,7 +1732,8 @@ static void read_v2_anomalous_offsets(struct packed_git *p,
static void read_idx_option(struct pack_idx_option *opts, const char *pack_name)
{
- struct packed_git *p = add_packed_git(pack_name, strlen(pack_name), 1);
+ struct packed_git *p = add_packed_git(the_repository, pack_name,
+ strlen(pack_name), 1);
if (!p)
die(_("Cannot open existing pack file '%s'"), pack_name);
@@ -1719,6 +1802,73 @@ static void show_pack_info(int stat_only)
free(chain_histogram);
}
+static void repack_local_links(void)
+{
+ struct child_process cmd = CHILD_PROCESS_INIT;
+ FILE *out;
+ struct strbuf line = STRBUF_INIT;
+ struct oidset_iter iter;
+ struct object_id *oid;
+ char *base_name = NULL;
+
+ if (!oidset_size(&outgoing_links))
+ return;
+
+ oidset_iter_init(&outgoing_links, &iter);
+ while ((oid = oidset_iter_next(&iter))) {
+ struct object_info info = OBJECT_INFO_INIT;
+ if (oid_object_info_extended(the_repository, oid, &info, 0))
+ /* Missing; assume it is a promisor object */
+ continue;
+ if (info.whence == OI_PACKED && info.u.packed.pack->pack_promisor)
+ continue;
+
+ if (!cmd.args.nr) {
+ base_name = mkpathdup(
+ "%s/pack/pack",
+ repo_get_object_directory(the_repository));
+ strvec_push(&cmd.args, "pack-objects");
+ strvec_push(&cmd.args,
+ "--exclude-promisor-objects-best-effort");
+ strvec_push(&cmd.args, base_name);
+ cmd.git_cmd = 1;
+ cmd.in = -1;
+ cmd.out = -1;
+ if (start_command(&cmd))
+ die(_("could not start pack-objects to repack local links"));
+ }
+
+ if (write_in_full(cmd.in, oid_to_hex(oid), the_hash_algo->hexsz) < 0 ||
+ write_in_full(cmd.in, "\n", 1) < 0)
+ die(_("failed to feed local object to pack-objects"));
+ }
+
+ if (!cmd.args.nr)
+ return;
+
+ close(cmd.in);
+
+ out = xfdopen(cmd.out, "r");
+ while (strbuf_getline_lf(&line, out) != EOF) {
+ unsigned char binary[GIT_MAX_RAWSZ];
+ if (line.len != the_hash_algo->hexsz ||
+ !hex_to_bytes(binary, line.buf, line.len))
+ die(_("index-pack: Expecting full hex object ID lines only from pack-objects."));
+
+ /*
+ * pack-objects creates the .pack and .idx files, but not the
+ * .promisor file. Create the .promisor file, which is empty.
+ */
+ write_special_file("promisor", "", NULL, binary, NULL);
+ }
+
+ fclose(out);
+ if (finish_command(&cmd))
+ die(_("could not finish pack-objects to repack local links"));
+ strbuf_release(&line);
+ free(base_name);
+}
+
int cmd_index_pack(int argc,
const char **argv,
const char *prefix,
@@ -1726,7 +1876,7 @@ int cmd_index_pack(int argc,
{
int i, fix_thin_pack = 0, verify = 0, stat_only = 0, rev_index;
const char *curr_index;
- const char *curr_rev_index = NULL;
+ char *curr_rev_index = NULL;
const char *index_name = NULL, *pack_name = NULL, *rev_index_name = NULL;
const char *keep_msg = NULL;
const char *promisor_msg = NULL;
@@ -1794,7 +1944,7 @@ int cmd_index_pack(int argc,
} else if (skip_to_optional_arg(arg, "--keep", &keep_msg)) {
; /* nothing to do */
} else if (skip_to_optional_arg(arg, "--promisor", &promisor_msg)) {
- ; /* already parsed */
+ record_outgoing_links = 1;
} else if (starts_with(arg, "--threads=")) {
char *end;
nr_threads = strtoul(arg+10, &end, 0);
@@ -1865,6 +2015,8 @@ int cmd_index_pack(int argc,
usage(index_pack_usage);
if (fix_thin_pack && !from_stdin)
die(_("the option '%s' requires '%s'"), "--fix-thin", "--stdin");
+ if (promisor_msg && pack_name)
+ die(_("--promisor cannot be used with a pack name"));
if (from_stdin && !startup_info->have_repository)
die(_("--stdin requires a git repository"));
if (from_stdin && hash_algo)
@@ -1928,7 +2080,7 @@ int cmd_index_pack(int argc,
parse_pack_objects(pack_hash);
if (report_end_of_input)
write_in_full(2, "\0", 1);
- resolve_deltas();
+ resolve_deltas(&opts);
conclude_pack(fix_thin_pack, curr_pack, pack_hash);
free(ofs_deltas);
free(ref_deltas);
@@ -1968,8 +2120,9 @@ int cmd_index_pack(int argc,
free((void *) curr_pack);
if (!index_name)
free((void *) curr_index);
- if (!rev_index_name)
- free((void *) curr_rev_index);
+ free(curr_rev_index);
+
+ repack_local_links();
/*
* Let the caller know this pack is not self contained
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 7e00d57d65..096f96b9c4 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -75,10 +75,12 @@ int cmd_init_db(int argc,
const char *prefix,
struct repository *repo UNUSED)
{
- const char *git_dir;
+ char *git_dir;
const char *real_git_dir = NULL;
- const char *work_tree;
+ char *real_git_dir_to_free = NULL;
+ char *work_tree = NULL;
const char *template_dir = NULL;
+ char *template_dir_to_free = NULL;
unsigned int flags = 0;
const char *object_format = NULL;
const char *ref_format = NULL;
@@ -106,6 +108,7 @@ int cmd_init_db(int argc,
N_("specify the reference format to use")),
OPT_END()
};
+ int ret;
argc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0);
@@ -113,12 +116,10 @@ int cmd_init_db(int argc,
die(_("options '%s' and '%s' cannot be used together"), "--separate-git-dir", "--bare");
if (real_git_dir && !is_absolute_path(real_git_dir))
- real_git_dir = real_pathdup(real_git_dir, 1);
+ real_git_dir = real_git_dir_to_free = real_pathdup(real_git_dir, 1);
- if (template_dir && *template_dir && !is_absolute_path(template_dir)) {
- template_dir = absolute_pathdup(template_dir);
- UNLEAK(template_dir);
- }
+ if (template_dir && *template_dir && !is_absolute_path(template_dir))
+ template_dir = template_dir_to_free = absolute_pathdup(template_dir);
if (argc == 1) {
int mkdir_tried = 0;
@@ -192,7 +193,7 @@ int cmd_init_db(int argc,
* Set up the default .git directory contents
*/
if (!git_dir)
- git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
+ git_dir = xstrdup(DEFAULT_GIT_DIR_ENVIRONMENT);
/*
* When --separate-git-dir is used inside a linked worktree, take
@@ -213,6 +214,7 @@ int cmd_init_db(int argc,
if (chdir(mainwt.buf) < 0)
die_errno(_("cannot chdir to %s"), mainwt.buf);
strbuf_release(&mainwt);
+ free(git_dir);
git_dir = strbuf_detach(&sb, NULL);
}
strbuf_release(&sb);
@@ -245,12 +247,14 @@ int cmd_init_db(int argc,
set_git_work_tree(work_tree);
}
- UNLEAK(real_git_dir);
- UNLEAK(git_dir);
- UNLEAK(work_tree);
-
flags |= INIT_DB_EXIST_OK;
- return init_db(git_dir, real_git_dir, template_dir, hash_algo,
- ref_storage_format, initial_branch,
- init_shared_repository, flags);
+ ret = init_db(git_dir, real_git_dir, template_dir, hash_algo,
+ ref_storage_format, initial_branch,
+ init_shared_repository, flags);
+
+ free(template_dir_to_free);
+ free(real_git_dir_to_free);
+ free(work_tree);
+ free(git_dir);
+ return ret;
}
diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c
index c5e56e2cd3..44d8ccddc9 100644
--- a/builtin/interpret-trailers.c
+++ b/builtin/interpret-trailers.c
@@ -141,8 +141,8 @@ static void interpret_trailers(const struct process_trailer_options *opts,
{
LIST_HEAD(head);
struct strbuf sb = STRBUF_INIT;
- struct strbuf trailer_block = STRBUF_INIT;
- struct trailer_info *info;
+ struct strbuf trailer_block_sb = STRBUF_INIT;
+ struct trailer_block *trailer_block;
FILE *outfile = stdout;
trailer_config_init();
@@ -152,13 +152,13 @@ static void interpret_trailers(const struct process_trailer_options *opts,
if (opts->in_place)
outfile = create_in_place_tempfile(file);
- info = parse_trailers(opts, sb.buf, &head);
+ trailer_block = parse_trailers(opts, sb.buf, &head);
- /* Print the lines before the trailers */
+ /* Print the lines before the trailer block */
if (!opts->only_trailers)
- fwrite(sb.buf, 1, trailer_block_start(info), outfile);
+ fwrite(sb.buf, 1, trailer_block_start(trailer_block), outfile);
- if (!opts->only_trailers && !blank_line_before_trailer_block(info))
+ if (!opts->only_trailers && !blank_line_before_trailer_block(trailer_block))
fprintf(outfile, "\n");
@@ -172,15 +172,16 @@ static void interpret_trailers(const struct process_trailer_options *opts,
}
/* Print trailer block. */
- format_trailers(opts, &head, &trailer_block);
+ format_trailers(opts, &head, &trailer_block_sb);
free_trailers(&head);
- fwrite(trailer_block.buf, 1, trailer_block.len, outfile);
- strbuf_release(&trailer_block);
+ fwrite(trailer_block_sb.buf, 1, trailer_block_sb.len, outfile);
+ strbuf_release(&trailer_block_sb);
- /* Print the lines after the trailers as is */
+ /* Print the lines after the trailer block as is. */
if (!opts->only_trailers)
- fwrite(sb.buf + trailer_block_end(info), 1, sb.len - trailer_block_end(info), outfile);
- trailer_info_release(info);
+ fwrite(sb.buf + trailer_block_end(trailer_block), 1,
+ sb.len - trailer_block_end(trailer_block), outfile);
+ trailer_block_release(trailer_block);
if (opts->in_place)
if (rename_tempfile(&trailers_tempfile, file))
diff --git a/builtin/log.c b/builtin/log.c
index 368f6580a6..75e1b34123 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -4,7 +4,10 @@
* (C) Copyright 2006 Linus Torvalds
* 2006 Junio Hamano
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "abspath.h"
#include "config.h"
@@ -528,10 +531,14 @@ static int cmd_log_walk_no_free(struct rev_info *rev)
* but we didn't actually show the commit.
*/
rev->max_count++;
- if (!rev->reflog_info) {
+ if (!rev->reflog_info && !rev->remerge_diff) {
/*
* We may show a given commit multiple times when
- * walking the reflogs.
+ * walking the reflogs. Therefore we still need it.
+ *
+ * Likewise, we potentially still need the parents
+ * of * already shown commits to determine merge
+ * bases when showing remerge diffs.
*/
free_commit_buffer(the_repository->parsed_objects,
commit);
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index e016b0415d..15499cd12b 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -5,7 +5,10 @@
*
* Copyright (C) Linus Torvalds, 2005
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "convert.h"
diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c
index f723b3bf3b..42f34e1236 100644
--- a/builtin/ls-remote.c
+++ b/builtin/ls-remote.c
@@ -166,6 +166,7 @@ int cmd_ls_remote(int argc,
status = 0; /* we found something */
}
+ string_list_clear(&server_options, 0);
ref_sorting_release(sorting);
ref_array_clear(&ref_array);
if (transport_disconnect(transport))
@@ -173,5 +174,6 @@ int cmd_ls_remote(int argc,
transport_ls_refs_options_release(&transport_options);
strvec_clear(&pattern);
+ string_list_clear(&server_options, 0);
return status;
}
diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c
index b8f7150ce9..41dd304731 100644
--- a/builtin/mailsplit.c
+++ b/builtin/mailsplit.c
@@ -4,6 +4,9 @@
* It just splits a mbox into a list of files: "0001" "0002" ..
* so you can process them further from there.
*/
+
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "gettext.h"
#include "string-list.h"
@@ -172,7 +175,6 @@ static int split_maildir(const char *maildir, const char *dir,
char *file = NULL;
FILE *f = NULL;
int ret = -1;
- int i;
struct string_list list = STRING_LIST_INIT_DUP;
list.cmp = maildir_filename_cmp;
@@ -180,7 +182,7 @@ static int split_maildir(const char *maildir, const char *dir,
if (populate_maildir_list(&list, maildir) < 0)
goto out;
- for (i = 0; i < list.nr; i++) {
+ for (size_t i = 0; i < list.nr; i++) {
char *name;
free(file);
diff --git a/builtin/merge-file.c b/builtin/merge-file.c
index cb42865eb5..7e315f374b 100644
--- a/builtin/merge-file.c
+++ b/builtin/merge-file.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "abspath.h"
#include "diff.h"
diff --git a/builtin/merge-index.c b/builtin/merge-index.c
index a5b87ee3c5..342699edb7 100644
--- a/builtin/merge-index.c
+++ b/builtin/merge-index.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "hex.h"
#include "read-cache-ll.h"
diff --git a/builtin/merge-ours.c b/builtin/merge-ours.c
index 1fcf53f005..3ecd9172f1 100644
--- a/builtin/merge-ours.c
+++ b/builtin/merge-ours.c
@@ -7,7 +7,9 @@
*
* Pretend we resolved the heads, but declare our tree trumps everybody else.
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+
#include "git-compat-util.h"
#include "builtin.h"
#include "diff.h"
diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c
index c5ed472967..9a6c8b4e4c 100644
--- a/builtin/merge-tree.c
+++ b/builtin/merge-tree.c
@@ -1,4 +1,5 @@
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "tree-walk.h"
#include "xdiff-interface.h"
@@ -497,10 +498,9 @@ static int real_merge(struct merge_tree_options *o,
if (!result.clean) {
struct string_list conflicted_files = STRING_LIST_INIT_NODUP;
const char *last = NULL;
- int i;
merge_get_conflicted_files(&result, &conflicted_files);
- for (i = 0; i < conflicted_files.nr; i++) {
+ for (size_t i = 0; i < conflicted_files.nr; i++) {
const char *name = conflicted_files.items[i].string;
struct stage_info *c = conflicted_files.items[i].util;
if (!o->name_only)
@@ -584,7 +584,7 @@ int cmd_merge_tree(int argc,
if (xopts.nr && o.mode == MODE_TRIVIAL)
die(_("--trivial-merge is incompatible with all other options"));
- for (int x = 0; x < xopts.nr; x++)
+ for (size_t x = 0; x < xopts.nr; x++)
if (parse_merge_opt(&o.merge_options, xopts.v[x]))
die(_("unknown strategy option: -X%s"), xopts.v[x]);
diff --git a/builtin/merge.c b/builtin/merge.c
index 84d0f3604b..5f67007bba 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -5,7 +5,10 @@
*
* Based on git-merge.sh by Junio C Hamano.
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "abspath.h"
@@ -498,7 +501,7 @@ static void merge_name(const char *remote, struct strbuf *msg)
char *found_ref = NULL;
int len, early;
- strbuf_branchname(&bname, remote, 0);
+ copy_branchname(&bname, remote, 0);
remote = bname.buf;
oidclr(&branch_head, the_repository->hash_algo);
@@ -754,6 +757,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
clean = merge_recursive(&o, head, remoteheads->item,
reversed, &result);
free_commit_list(reversed);
+ strbuf_release(&o.obuf);
if (clean < 0) {
rollback_lock_file(&lock);
diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c
index d159ed1314..2a938466f5 100644
--- a/builtin/multi-pack-index.c
+++ b/builtin/multi-pack-index.c
@@ -119,7 +119,8 @@ static void read_packs_from_stdin(struct string_list *to)
}
static int cmd_multi_pack_index_write(int argc, const char **argv,
- const char *prefix)
+ const char *prefix,
+ struct repository *repo)
{
struct option *options;
static struct option builtin_multi_pack_index_write_options[] = {
@@ -164,7 +165,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
read_packs_from_stdin(&packs);
- ret = write_midx_file_only(opts.object_dir, &packs,
+ ret = write_midx_file_only(repo, opts.object_dir, &packs,
opts.preferred_pack,
opts.refs_snapshot, opts.flags);
@@ -175,7 +176,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
}
- ret = write_midx_file(opts.object_dir, opts.preferred_pack,
+ ret = write_midx_file(repo, opts.object_dir, opts.preferred_pack,
opts.refs_snapshot, opts.flags);
free(opts.refs_snapshot);
@@ -183,7 +184,8 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
}
static int cmd_multi_pack_index_verify(int argc, const char **argv,
- const char *prefix)
+ const char *prefix,
+ struct repository *repo UNUSED)
{
struct option *options;
static struct option builtin_multi_pack_index_verify_options[] = {
@@ -210,7 +212,8 @@ static int cmd_multi_pack_index_verify(int argc, const char **argv,
}
static int cmd_multi_pack_index_expire(int argc, const char **argv,
- const char *prefix)
+ const char *prefix,
+ struct repository *repo UNUSED)
{
struct option *options;
static struct option builtin_multi_pack_index_expire_options[] = {
@@ -237,7 +240,8 @@ static int cmd_multi_pack_index_expire(int argc, const char **argv,
}
static int cmd_multi_pack_index_repack(int argc, const char **argv,
- const char *prefix)
+ const char *prefix,
+ struct repository *repo UNUSED)
{
struct option *options;
static struct option builtin_multi_pack_index_repack_options[] = {
@@ -271,7 +275,7 @@ static int cmd_multi_pack_index_repack(int argc, const char **argv,
int cmd_multi_pack_index(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
int res;
parse_opt_subcommand_fn *fn = NULL;
@@ -297,7 +301,7 @@ int cmd_multi_pack_index(int argc,
builtin_multi_pack_index_usage, 0);
FREE_AND_NULL(options);
- res = fn(argc, argv, prefix);
+ res = fn(argc, argv, prefix, repo);
free(opts.object_dir);
return res;
diff --git a/builtin/mv.c b/builtin/mv.c
index 472a278737..55a7d471dc 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -3,7 +3,9 @@
*
* Copyright (C) 2006 Johannes Schindelin
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
#include "builtin.h"
#include "abspath.h"
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 765eb20a93..beac166b5c 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "environment.h"
#include "gettext.h"
diff --git a/builtin/notes.c b/builtin/notes.c
index 8c26e45526..d051abf6df 100644
--- a/builtin/notes.c
+++ b/builtin/notes.c
@@ -32,9 +32,9 @@
static const char *separator = "\n";
static const char * const git_notes_usage[] = {
N_("git notes [--ref <notes-ref>] [list [<object>]]"),
- N_("git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
+ N_("git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>] [-e]"),
N_("git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>"),
- N_("git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"),
+ N_("git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>] [-e]"),
N_("git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]"),
N_("git notes [--ref <notes-ref>] show [<object>]"),
N_("git notes [--ref <notes-ref>] merge [-v | -q] [-s <strategy>] <notes-ref>"),
@@ -431,7 +431,8 @@ static struct notes_tree *init_notes_check(const char *subcommand,
return t;
}
-static int list(int argc, const char **argv, const char *prefix)
+static int list(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct notes_tree *t;
struct object_id object;
@@ -468,9 +469,11 @@ static int list(int argc, const char **argv, const char *prefix)
return retval;
}
-static int append_edit(int argc, const char **argv, const char *prefix);
+static int append_edit(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED);
-static int add(int argc, const char **argv, const char *prefix)
+static int add(int argc, const char **argv, const char *prefix,
+ struct repository *repo)
{
int force = 0, allow_empty = 0;
const char *object_ref;
@@ -489,6 +492,8 @@ static int add(int argc, const char **argv, const char *prefix)
OPT_CALLBACK_F('c', "reedit-message", &d, N_("object"),
N_("reuse and edit specified note object"), PARSE_OPT_NONEG,
parse_reedit_arg),
+ OPT_BOOL('e', "edit", &d.use_editor,
+ N_("edit note message in editor")),
OPT_CALLBACK_F('C', "reuse-message", &d, N_("object"),
N_("reuse specified note object"), PARSE_OPT_NONEG,
parse_reuse_arg),
@@ -541,7 +546,7 @@ static int add(int argc, const char **argv, const char *prefix)
* argv[0-1].
*/
argv[0] = "edit";
- return append_edit(argc, argv, prefix);
+ return append_edit(argc, argv, prefix, repo);
}
fprintf(stderr, _("Overwriting existing notes for object %s\n"),
oid_to_hex(&object));
@@ -567,7 +572,8 @@ static int add(int argc, const char **argv, const char *prefix)
return 0;
}
-static int copy(int argc, const char **argv, const char *prefix)
+static int copy(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int retval = 0, force = 0, from_stdin = 0;
const struct object_id *from_note, *note;
@@ -644,7 +650,8 @@ out:
return retval;
}
-static int append_edit(int argc, const char **argv, const char *prefix)
+static int append_edit(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int allow_empty = 0;
const char *object_ref;
@@ -667,6 +674,8 @@ static int append_edit(int argc, const char **argv, const char *prefix)
OPT_CALLBACK_F('C', "reuse-message", &d, N_("object"),
N_("reuse specified note object"), PARSE_OPT_NONEG,
parse_reuse_arg),
+ OPT_BOOL('e', "edit", &d.use_editor,
+ N_("edit note message in editor")),
OPT_BOOL(0, "allow-empty", &allow_empty,
N_("allow storing empty note")),
OPT_CALLBACK_F(0, "separator", &separator,
@@ -745,7 +754,8 @@ static int append_edit(int argc, const char **argv, const char *prefix)
return 0;
}
-static int show(int argc, const char **argv, const char *prefix)
+static int show(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
const char *object_ref;
struct notes_tree *t;
@@ -871,7 +881,8 @@ static int git_config_get_notes_strategy(const char *key,
return 0;
}
-static int merge(int argc, const char **argv, const char *prefix)
+static int merge(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct strbuf remote_ref = STRBUF_INIT, msg = STRBUF_INIT;
struct object_id result_oid;
@@ -1012,7 +1023,8 @@ static int remove_one_note(struct notes_tree *t, const char *name, unsigned flag
return (flag & IGNORE_MISSING) ? 0 : status;
}
-static int remove_cmd(int argc, const char **argv, const char *prefix)
+static int remove_cmd(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
unsigned flag = 0;
int from_stdin = 0;
@@ -1055,7 +1067,8 @@ static int remove_cmd(int argc, const char **argv, const char *prefix)
return retval;
}
-static int prune(int argc, const char **argv, const char *prefix)
+static int prune(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct notes_tree *t;
int show_only = 0, verbose = 0;
@@ -1084,7 +1097,8 @@ static int prune(int argc, const char **argv, const char *prefix)
return 0;
}
-static int get_ref(int argc, const char **argv, const char *prefix)
+static int get_ref(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct option options[] = { OPT_END() };
char *notes_ref;
@@ -1105,7 +1119,7 @@ static int get_ref(int argc, const char **argv, const char *prefix)
int cmd_notes(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
const char *override_notes_ref = NULL;
parse_opt_subcommand_fn *fn = NULL;
@@ -1144,5 +1158,5 @@ int cmd_notes(int argc,
strbuf_release(&sb);
}
- return !!fn(argc, argv, prefix);
+ return !!fn(argc, argv, prefix, repo);
}
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 0fc0680b40..1c3b842651 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "environment.h"
#include "gettext.h"
@@ -239,6 +241,7 @@ static enum {
static uint16_t write_bitmap_options = BITMAP_OPT_HASH_CACHE;
static int exclude_promisor_objects;
+static int exclude_promisor_objects_best_effort;
static int use_delta_islands;
@@ -1100,78 +1103,64 @@ static void write_reused_pack_one(struct packed_git *reuse_packfile,
static size_t write_reused_pack_verbatim(struct bitmapped_pack *reuse_packfile,
struct hashfile *out,
- off_t pack_start,
struct pack_window **w_curs)
{
- size_t pos = reuse_packfile->bitmap_pos;
+ size_t pos = 0;
size_t end;
- if (pos % BITS_IN_EWORD) {
- size_t word_pos = (pos / BITS_IN_EWORD);
- size_t offset = pos % BITS_IN_EWORD;
- size_t last;
- eword_t word = reuse_packfile_bitmap->words[word_pos];
-
- if (offset + reuse_packfile->bitmap_nr < BITS_IN_EWORD)
- last = offset + reuse_packfile->bitmap_nr;
- else
- last = BITS_IN_EWORD;
-
- for (; offset < last; offset++) {
- if (word >> offset == 0)
- return word_pos;
- if (!bitmap_get(reuse_packfile_bitmap,
- word_pos * BITS_IN_EWORD + offset))
- return word_pos;
- }
-
- pos += BITS_IN_EWORD - (pos % BITS_IN_EWORD);
+ if (reuse_packfile->bitmap_pos) {
+ /*
+ * We can't reuse whole chunks verbatim out of
+ * non-preferred packs since we can't guarantee that
+ * all duplicate objects were resolved in favor of
+ * that pack.
+ *
+ * Even if we have a whole eword_t worth of bits that
+ * could be reused, there may be objects between the
+ * objects corresponding to the first and last bit of
+ * that word which were selected from a different
+ * pack, causing us to send duplicate or unwanted
+ * objects.
+ *
+ * Handle non-preferred packs from within
+ * write_reused_pack(), which inspects and reuses
+ * individual bits.
+ */
+ return reuse_packfile->bitmap_pos / BITS_IN_EWORD;
}
/*
- * Now we're going to copy as many whole eword_t's as possible.
- * "end" is the index of the last whole eword_t we copy, but
- * there may be additional bits to process. Those are handled
- * individually by write_reused_pack().
+ * Only read through the last word whose bits all correspond
+ * to objects in the given packfile, since we must stop at a
+ * word boundary.
*
- * Begin by advancing to the first word boundary in range of the
- * bit positions occupied by objects in "reuse_packfile". Then
- * pick the last word boundary in the same range. If we have at
- * least one word's worth of bits to process, continue on.
+ * If there is no whole word to read (i.e. the packfile
+ * contains fewer than BITS_IN_EWORD objects), then we'll
+ * inspect bits one-by-one in write_reused_pack().
*/
- end = reuse_packfile->bitmap_pos + reuse_packfile->bitmap_nr;
- if (end % BITS_IN_EWORD)
- end -= end % BITS_IN_EWORD;
- if (pos >= end)
- return reuse_packfile->bitmap_pos / BITS_IN_EWORD;
-
- while (pos < end &&
- reuse_packfile_bitmap->words[pos / BITS_IN_EWORD] == (eword_t)~0)
- pos += BITS_IN_EWORD;
+ end = reuse_packfile->bitmap_nr / BITS_IN_EWORD;
+ if (reuse_packfile_bitmap->word_alloc < end)
+ BUG("fewer words than expected in reuse_packfile_bitmap");
- if (pos > end)
- pos = end;
+ while (pos < end && reuse_packfile_bitmap->words[pos] == (eword_t)~0)
+ pos++;
- if (reuse_packfile->bitmap_pos < pos) {
- off_t pack_start_off = pack_pos_to_offset(reuse_packfile->p, 0);
- off_t pack_end_off = pack_pos_to_offset(reuse_packfile->p,
- pos - reuse_packfile->bitmap_pos);
+ if (pos) {
+ off_t to_write;
- written += pos - reuse_packfile->bitmap_pos;
+ written = (pos * BITS_IN_EWORD);
+ to_write = pack_pos_to_offset(reuse_packfile->p, written)
+ - sizeof(struct pack_header);
/* We're recording one chunk, not one object. */
- record_reused_object(pack_start_off,
- pack_start_off - (hashfile_total(out) - pack_start));
+ record_reused_object(sizeof(struct pack_header), 0);
hashflush(out);
copy_pack_data(out, reuse_packfile->p, w_curs,
- pack_start_off, pack_end_off - pack_start_off);
+ sizeof(struct pack_header), to_write);
display_progress(progress_state, written);
}
- if (pos % BITS_IN_EWORD)
- BUG("attempted to jump past a word boundary to %"PRIuMAX,
- (uintmax_t)pos);
- return pos / BITS_IN_EWORD;
+ return pos;
}
static void write_reused_pack(struct bitmapped_pack *reuse_packfile,
@@ -1183,8 +1172,7 @@ static void write_reused_pack(struct bitmapped_pack *reuse_packfile,
struct pack_window *w_curs = NULL;
if (allow_ofs_delta)
- i = write_reused_pack_verbatim(reuse_packfile, f, pack_start,
- &w_curs);
+ i = write_reused_pack_verbatim(reuse_packfile, f, &w_curs);
for (; i < reuse_packfile_bitmap->word_alloc; ++i) {
eword_t word = reuse_packfile_bitmap->words[i];
@@ -1529,7 +1517,7 @@ static int want_found_object(const struct object_id *oid, int exclude,
return 0;
if (ignore_packed_keep_in_core && p->pack_keep_in_core)
return 0;
- if (has_object_kept_pack(oid, flags))
+ if (has_object_kept_pack(p->repo, oid, flags))
return 0;
}
@@ -1556,7 +1544,7 @@ static int want_object_in_pack_one(struct packed_git *p,
if (p == *found_pack)
offset = *found_offset;
else
- offset = find_pack_entry_one(oid->hash, p);
+ offset = find_pack_entry_one(oid, p);
if (offset) {
if (!*found_pack) {
@@ -3627,7 +3615,7 @@ static void show_cruft_commit(struct commit *commit, void *data)
static int cruft_include_check_obj(struct object *obj, void *data UNUSED)
{
- return !has_object_kept_pack(&obj->oid, IN_CORE_KEEP_PACKS);
+ return !has_object_kept_pack(to_pack.repo, &obj->oid, IN_CORE_KEEP_PACKS);
}
static int cruft_include_check(struct commit *commit, void *data)
@@ -3858,7 +3846,8 @@ static void show_object__ma_allow_promisor(struct object *obj, const char *name,
* Quietly ignore EXPECTED missing objects. This avoids problems with
* staging them now and getting an odd error later.
*/
- if (!has_object(the_repository, &obj->oid, 0) && is_promisor_object(&obj->oid))
+ if (!has_object(the_repository, &obj->oid, 0) &&
+ is_promisor_object(to_pack.repo, &obj->oid))
return;
show_object(obj, name, data);
@@ -3927,7 +3916,9 @@ static int add_object_in_unpacked_pack(const struct object_id *oid,
static void add_objects_in_unpacked_packs(void)
{
- if (for_each_packed_object(add_object_in_unpacked_pack, NULL,
+ if (for_each_packed_object(to_pack.repo,
+ add_object_in_unpacked_pack,
+ NULL,
FOR_EACH_OBJECT_PACK_ORDER |
FOR_EACH_OBJECT_LOCAL_ONLY |
FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS |
@@ -3984,7 +3975,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)
while (p) {
if ((!p->pack_local || p->pack_keep ||
p->pack_keep_in_core) &&
- find_pack_entry_one(oid->hash, p)) {
+ find_pack_entry_one(oid, p)) {
last_found = p;
return 1;
}
@@ -4312,6 +4303,18 @@ static int option_parse_cruft_expiration(const struct option *opt UNUSED,
return 0;
}
+static int is_not_in_promisor_pack_obj(struct object *obj, void *data UNUSED)
+{
+ struct object_info info = OBJECT_INFO_INIT;
+ if (oid_object_info_extended(the_repository, &obj->oid, &info, 0))
+ BUG("should_include_obj should only be called on existing objects");
+ return info.whence != OI_PACKED || !info.u.packed.pack->pack_promisor;
+}
+
+static int is_not_in_promisor_pack(struct commit *commit, void *data) {
+ return is_not_in_promisor_pack_obj((struct object *) commit, data);
+}
+
int cmd_pack_objects(int argc,
const char **argv,
const char *prefix,
@@ -4424,6 +4427,9 @@ int cmd_pack_objects(int argc,
option_parse_missing_action),
OPT_BOOL(0, "exclude-promisor-objects", &exclude_promisor_objects,
N_("do not pack objects in promisor packfiles")),
+ OPT_BOOL(0, "exclude-promisor-objects-best-effort",
+ &exclude_promisor_objects_best_effort,
+ N_("implies --missing=allow-any")),
OPT_BOOL(0, "delta-islands", &use_delta_islands,
N_("respect islands during delta compression")),
OPT_STRING_LIST(0, "uri-protocol", &uri_protocols,
@@ -4504,10 +4510,18 @@ int cmd_pack_objects(int argc,
strvec_push(&rp, "--unpacked");
}
+ if (exclude_promisor_objects && exclude_promisor_objects_best_effort)
+ die(_("options '%s' and '%s' cannot be used together"),
+ "--exclude-promisor-objects", "--exclude-promisor-objects-best-effort");
if (exclude_promisor_objects) {
use_internal_rev_list = 1;
fetch_if_missing = 0;
strvec_push(&rp, "--exclude-promisor-objects");
+ } else if (exclude_promisor_objects_best_effort) {
+ use_internal_rev_list = 1;
+ fetch_if_missing = 0;
+ option_parse_missing_action(NULL, "allow-any", 0);
+ /* revs configured below */
}
if (unpack_unreachable || keep_unreachable || pack_loose_unreachable)
use_internal_rev_list = 1;
@@ -4627,6 +4641,10 @@ int cmd_pack_objects(int argc,
repo_init_revisions(the_repository, &revs, NULL);
list_objects_filter_copy(&revs.filter, &filter_options);
+ if (exclude_promisor_objects_best_effort) {
+ revs.include_check = is_not_in_promisor_pack;
+ revs.include_check_obj = is_not_in_promisor_pack_obj;
+ }
get_object_list(&revs, rp.nr, rp.v);
release_revisions(&revs);
}
diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c
index 81f4494d46..e046575871 100644
--- a/builtin/pack-redundant.c
+++ b/builtin/pack-redundant.c
@@ -5,6 +5,7 @@
* This file is licensed under the GPL v2.
*
*/
+
#define USE_THE_REPOSITORY_VARIABLE
#include "builtin.h"
@@ -13,6 +14,7 @@
#include "packfile.h"
#include "object-store-ll.h"
+#include "strbuf.h"
#define BLKSIZE 512
@@ -69,6 +71,15 @@ static inline void llist_init(struct llist **list)
(*list)->size = 0;
}
+static void llist_free(struct llist *list)
+{
+ for (struct llist_item *i = list->front, *next; i; i = next) {
+ next = i->next;
+ llist_item_put(i);
+ }
+ free(list);
+}
+
static struct llist * llist_copy(struct llist *list)
{
struct llist *ret;
@@ -206,6 +217,14 @@ static inline struct pack_list * pack_list_insert(struct pack_list **pl,
return p;
}
+static void pack_list_free(struct pack_list *pl)
+{
+ for (struct pack_list *next; pl; pl = next) {
+ next = pl->next;
+ free(pl);
+ }
+}
+
static inline size_t pack_list_size(struct pack_list *pl)
{
size_t ret = 0;
@@ -371,7 +390,6 @@ static int cmp_remaining_objects(const void *a, const void *b)
static void sort_pack_list(struct pack_list **pl)
{
struct pack_list **ary, *p;
- int i;
size_t n = pack_list_size(*pl);
if (n < 2)
@@ -385,7 +403,7 @@ static void sort_pack_list(struct pack_list **pl)
QSORT(ary, n, cmp_remaining_objects);
/* link them back again */
- for (i = 0; i < n - 1; i++)
+ for (size_t i = 0; i < n - 1; i++)
ary[i]->next = ary[i + 1];
ary[n - 1]->next = NULL;
*pl = ary[0];
@@ -419,7 +437,8 @@ static void minimize(struct pack_list **min)
/* return if there are no objects missing from the unique set */
if (missing->size == 0) {
- free(missing);
+ llist_free(missing);
+ pack_list_free(non_unique);
return;
}
@@ -434,6 +453,8 @@ static void minimize(struct pack_list **min)
}
while (non_unique) {
+ struct pack_list *next;
+
/* sort the non_unique packs, greater size of remaining_objects first */
sort_pack_list(&non_unique);
if (non_unique->remaining_objects->size == 0)
@@ -444,8 +465,14 @@ static void minimize(struct pack_list **min)
for (pl = non_unique->next; pl && pl->remaining_objects->size > 0; pl = pl->next)
llist_sorted_difference_inplace(pl->remaining_objects, non_unique->remaining_objects);
- non_unique = non_unique->next;
+ next = non_unique->next;
+ free(non_unique);
+ non_unique = next;
}
+
+ pack_list_free(non_unique);
+ llist_free(unique_pack_objects);
+ llist_free(missing);
}
static void load_all_objects(void)
@@ -565,7 +592,7 @@ static void load_all(void)
int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, struct repository *repo UNUSED) {
int i; int i_still_use_this = 0; struct pack_list *min = NULL, *red, *pl;
struct llist *ignore;
- struct object_id *oid;
+ struct strbuf idx_name = STRBUF_INIT;
char buf[GIT_MAX_HEXSZ + 2]; /* hex hash + \n + \0 */
if (argc == 2 && !strcmp(argv[1], "-h"))
@@ -625,11 +652,11 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s
/* ignore objects given on stdin */
llist_init(&ignore);
if (!isatty(0)) {
+ struct object_id oid;
while (fgets(buf, sizeof(buf), stdin)) {
- oid = xmalloc(sizeof(*oid));
- if (get_oid_hex(buf, oid))
+ if (get_oid_hex(buf, &oid))
die("Bad object ID on stdin: %s", buf);
- llist_insert_sorted_unique(ignore, oid, NULL);
+ llist_insert_sorted_unique(ignore, &oid, NULL);
}
}
llist_sorted_difference_inplace(all_objects, ignore);
@@ -663,7 +690,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s
pl = red = pack_list_difference(local_packs, min);
while (pl) {
printf("%s\n%s\n",
- sha1_pack_index_name(pl->pack->hash),
+ odb_pack_name(pl->pack->repo, &idx_name, pl->pack->hash, "idx"),
pl->pack->pack_name);
pl = pl->next;
}
@@ -671,5 +698,9 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s
fprintf(stderr, "%luMB of redundant packs in total.\n",
(unsigned long)pack_set_bytecount(red)/(1024*1024));
+ pack_list_free(red);
+ pack_list_free(min);
+ llist_free(ignore);
+ strbuf_release(&idx_name);
return 0;
}
diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c
index 2d83c1ed2a..4fdd68880e 100644
--- a/builtin/pack-refs.c
+++ b/builtin/pack-refs.c
@@ -1,4 +1,5 @@
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "config.h"
#include "gettext.h"
diff --git a/builtin/patch-id.c b/builtin/patch-id.c
index 93b398e391..f540d8daa7 100644
--- a/builtin/patch-id.c
+++ b/builtin/patch-id.c
@@ -1,4 +1,5 @@
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "config.h"
#include "diff.h"
@@ -8,13 +9,13 @@
#include "parse-options.h"
#include "setup.h"
-static void flush_current_id(int patchlen, struct object_id *id, struct object_id *result)
+static void flush_current_id(size_t patchlen, struct object_id *id, struct object_id *result)
{
if (patchlen)
printf("%s %s\n", oid_to_hex(result), oid_to_hex(id));
}
-static int remove_space(char *line)
+static size_t remove_space(char *line)
{
char *src = line;
char *dst = line;
@@ -61,10 +62,11 @@ static int scan_hunk_header(const char *p, int *p_before, int *p_after)
return 1;
}
-static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
- struct strbuf *line_buf, int stable, int verbatim)
+static size_t get_one_patchid(struct object_id *next_oid, struct object_id *result,
+ struct strbuf *line_buf, int stable, int verbatim)
{
- int patchlen = 0, found_next = 0;
+ size_t patchlen = 0;
+ int found_next = 0;
int before = -1, after = -1;
int diff_is_binary = 0;
char pre_oid_str[GIT_MAX_HEXSZ + 1], post_oid_str[GIT_MAX_HEXSZ + 1];
@@ -76,7 +78,7 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
while (strbuf_getwholeline(line_buf, stdin, '\n') != EOF) {
char *line = line_buf->buf;
const char *p = line;
- int len;
+ size_t len;
/* Possibly skip over the prefix added by "log" or "format-patch" */
if (!skip_prefix(line, "commit ", &p) &&
@@ -177,7 +179,7 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
static void generate_id_list(int stable, int verbatim)
{
struct object_id oid, n, result;
- int patchlen;
+ size_t patchlen;
struct strbuf line_buf = STRBUF_INIT;
oidclr(&oid, the_repository->hash_algo);
diff --git a/builtin/prune.c b/builtin/prune.c
index 2b1de01339..aeff9ca1b3 100644
--- a/builtin/prune.c
+++ b/builtin/prune.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "commit.h"
#include "diff.h"
diff --git a/builtin/pull.c b/builtin/pull.c
index 388ef3d130..9c4a00620a 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -7,6 +7,7 @@
*/
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "advice.h"
#include "config.h"
@@ -218,8 +219,8 @@ static struct option pull_options[] = {
OPT_PASSTHRU_ARGV(0, "shallow-since", &opt_fetch, N_("time"),
N_("deepen history of shallow repository based on time"),
0),
- OPT_PASSTHRU_ARGV(0, "shallow-exclude", &opt_fetch, N_("revision"),
- N_("deepen history of shallow clone, excluding rev"),
+ OPT_PASSTHRU_ARGV(0, "shallow-exclude", &opt_fetch, N_("ref"),
+ N_("deepen history of shallow clone, excluding ref"),
0),
OPT_PASSTHRU_ARGV(0, "deepen", &opt_fetch, N_("n"),
N_("deepen history of shallow clone"),
@@ -941,11 +942,10 @@ static int get_can_ff(struct object_id *orig_head,
static int already_up_to_date(struct object_id *orig_head,
struct oid_array *merge_heads)
{
- int i;
struct commit *ours;
ours = lookup_commit_reference(the_repository, orig_head);
- for (i = 0; i < merge_heads->nr; i++) {
+ for (size_t i = 0; i < merge_heads->nr; i++) {
struct commit_list *list = NULL;
struct commit *theirs;
int ok;
diff --git a/builtin/push.c b/builtin/push.c
index 59d4485603..90de3746b5 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -1,7 +1,9 @@
/*
* "git push"
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "advice.h"
#include "branch.h"
@@ -417,7 +419,7 @@ static int do_push(int flags,
const struct string_list *push_options,
struct remote *remote)
{
- int i, errs;
+ int errs;
struct strvec *url;
struct refspec *push_refspec = &rs;
@@ -432,7 +434,7 @@ static int do_push(int flags,
}
errs = 0;
url = push_url_of_remote(remote);
- for (i = 0; i < url->nr; i++) {
+ for (size_t i = 0; i < url->nr; i++) {
struct transport *transport =
transport_get(remote, url->v[i]);
if (flags & TRANSPORT_PUSH_OPTIONS)
@@ -519,14 +521,7 @@ static int git_push_config(const char *k, const char *v,
RECURSE_SUBMODULES_ON_DEMAND : RECURSE_SUBMODULES_OFF;
recurse_submodules = val;
} else if (!strcmp(k, "push.pushoption")) {
- if (!v)
- return config_error_nonbool(k);
- else
- if (!*v)
- string_list_clear(&push_options_config, 0);
- else
- string_list_append(&push_options_config, v);
- return 0;
+ return parse_transport_option(k, v, &push_options_config);
} else if (!strcmp(k, "color.push")) {
push_use_color = git_config_colorbool(k, v);
return 0;
diff --git a/builtin/range-diff.c b/builtin/range-diff.c
index 1b33ab66a7..32ddb6613f 100644
--- a/builtin/range-diff.c
+++ b/builtin/range-diff.c
@@ -1,4 +1,5 @@
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "gettext.h"
#include "object-name.h"
@@ -21,6 +22,7 @@ int cmd_range_diff(int argc,
{
struct diff_options diffopt = { NULL };
struct strvec other_arg = STRVEC_INIT;
+ struct strvec diff_merges_arg = STRVEC_INIT;
struct range_diff_options range_diff_opts = {
.creation_factor = RANGE_DIFF_CREATION_FACTOR_DEFAULT,
.diffopt = &diffopt,
@@ -36,6 +38,10 @@ int cmd_range_diff(int argc,
OPT_PASSTHRU_ARGV(0, "notes", &other_arg,
N_("notes"), N_("passed to 'git log'"),
PARSE_OPT_OPTARG),
+ OPT_PASSTHRU_ARGV(0, "diff-merges", &diff_merges_arg,
+ N_("style"), N_("passed to 'git log'"), 0),
+ OPT_PASSTHRU_ARGV(0, "remerge-diff", &diff_merges_arg, NULL,
+ N_("passed to 'git log'"), PARSE_OPT_NOARG),
OPT_BOOL(0, "left-only", &left_only,
N_("only emit output related to the first range")),
OPT_BOOL(0, "right-only", &right_only,
@@ -62,6 +68,12 @@ int cmd_range_diff(int argc,
if (!simple_color)
diffopt.use_color = 1;
+ /* If `--diff-merges` was specified, imply `--merges` */
+ if (diff_merges_arg.nr) {
+ range_diff_opts.include_merges = 1;
+ strvec_pushv(&other_arg, diff_merges_arg.v);
+ }
+
for (i = 0; i < argc; i++)
if (!strcmp(argv[i], "--")) {
dash_dash = i;
@@ -155,6 +167,7 @@ int cmd_range_diff(int argc,
res = show_range_diff(range1.buf, range2.buf, &range_diff_opts);
strvec_clear(&other_arg);
+ strvec_clear(&diff_merges_arg);
strbuf_release(&range1);
strbuf_release(&range2);
diff --git a/builtin/rebase.c b/builtin/rebase.c
index bbaca3c5d5..0498fff3c9 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -3,7 +3,10 @@
*
* Copyright (c) 2018 Pratik Karki
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "abspath.h"
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 536d22761d..c2e9103f11 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "abspath.h"
@@ -374,6 +376,7 @@ static void write_head_info(void)
struct command {
struct command *next;
const char *error_string;
+ char *error_string_owned;
struct ref_push_report *report;
unsigned int skip_update:1,
did_not_exist:1,
@@ -1083,7 +1086,7 @@ static int read_proc_receive_report(struct packet_reader *reader,
hint->run_proc_receive |= RUN_PROC_RECEIVE_RETURNED;
if (!strcmp(head, "ng")) {
if (p)
- hint->error_string = xstrdup(p);
+ hint->error_string = hint->error_string_owned = xstrdup(p);
else
hint->error_string = "failed";
code = -1;
@@ -1848,7 +1851,7 @@ static void execute_commands_non_atomic(struct command *commands,
continue;
transaction = ref_store_transaction_begin(get_main_ref_store(the_repository),
- &err);
+ 0, &err);
if (!transaction) {
rp_error("%s", err.buf);
strbuf_reset(&err);
@@ -1877,7 +1880,7 @@ static void execute_commands_atomic(struct command *commands,
const char *reported_error = "atomic push failure";
transaction = ref_store_transaction_begin(get_main_ref_store(the_repository),
- &err);
+ 0, &err);
if (!transaction) {
rp_error("%s", err.buf);
strbuf_reset(&err);
@@ -2054,6 +2057,8 @@ static void free_commands(struct command *commands)
while (commands) {
struct command *next = commands->next;
+ ref_push_report_free(commands->report);
+ free(commands->error_string_owned);
free(commands);
commands = next;
}
diff --git a/builtin/reflog.c b/builtin/reflog.c
index 22df6834f7..95f264989b 100644
--- a/builtin/reflog.c
+++ b/builtin/reflog.c
@@ -1,4 +1,5 @@
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "config.h"
#include "gettext.h"
@@ -234,7 +235,8 @@ static int expire_total_callback(const struct option *opt,
return 0;
}
-static int cmd_reflog_show(int argc, const char **argv, const char *prefix)
+static int cmd_reflog_show(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct option options[] = {
OPT_END()
@@ -253,7 +255,8 @@ static int show_reflog(const char *refname, void *cb_data UNUSED)
return 0;
}
-static int cmd_reflog_list(int argc, const char **argv, const char *prefix)
+static int cmd_reflog_list(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct option options[] = {
OPT_END()
@@ -270,7 +273,8 @@ static int cmd_reflog_list(int argc, const char **argv, const char *prefix)
return refs_for_each_reflog(ref_store, show_reflog, NULL);
}
-static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
+static int cmd_reflog_expire(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct cmd_reflog_expire_cb cmd = { 0 };
timestamp_t now = time(NULL);
@@ -394,7 +398,8 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
return status;
}
-static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)
+static int cmd_reflog_delete(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int i, status = 0;
unsigned int flags = 0;
@@ -424,7 +429,8 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix)
return status;
}
-static int cmd_reflog_exists(int argc, const char **argv, const char *prefix)
+static int cmd_reflog_exists(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct option options[] = {
OPT_END()
@@ -467,7 +473,7 @@ int cmd_reflog(int argc,
PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0 |
PARSE_OPT_KEEP_UNKNOWN_OPT);
if (fn)
- return fn(argc - 1, argv + 1, prefix);
+ return fn(argc - 1, argv + 1, prefix, repository);
else
return cmd_log_reflog(argc, argv, prefix, repository);
}
diff --git a/builtin/refs.c b/builtin/refs.c
index 24978a7b7b..a29f195834 100644
--- a/builtin/refs.c
+++ b/builtin/refs.c
@@ -5,6 +5,7 @@
#include "parse-options.h"
#include "refs.h"
#include "strbuf.h"
+#include "worktree.h"
#define REFS_MIGRATE_USAGE \
N_("git refs migrate --ref-format=<format> [--dry-run]")
@@ -12,7 +13,8 @@
#define REFS_VERIFY_USAGE \
N_("git refs verify [--strict] [--verbose]")
-static int cmd_refs_migrate(int argc, const char **argv, const char *prefix)
+static int cmd_refs_migrate(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
const char * const migrate_usage[] = {
REFS_MIGRATE_USAGE,
@@ -63,9 +65,11 @@ out:
return err;
}
-static int cmd_refs_verify(int argc, const char **argv, const char *prefix)
+static int cmd_refs_verify(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct fsck_options fsck_refs_options = FSCK_REFS_OPTIONS_DEFAULT;
+ struct worktree **worktrees;
const char * const verify_usage[] = {
REFS_VERIFY_USAGE,
NULL,
@@ -75,7 +79,7 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix)
OPT_BOOL(0, "strict", &fsck_refs_options.strict, N_("enable strict checking")),
OPT_END(),
};
- int ret;
+ int ret = 0;
argc = parse_options(argc, argv, prefix, options, verify_usage, 0);
if (argc)
@@ -84,16 +88,20 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix)
git_config(git_fsck_config, &fsck_refs_options);
prepare_repo_settings(the_repository);
- ret = refs_fsck(get_main_ref_store(the_repository), &fsck_refs_options);
+ worktrees = get_worktrees();
+ for (size_t i = 0; worktrees[i]; i++)
+ ret |= refs_fsck(get_worktree_ref_store(worktrees[i]),
+ &fsck_refs_options, worktrees[i]);
fsck_options_clear(&fsck_refs_options);
+ free_worktrees(worktrees);
return ret;
}
int cmd_refs(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
const char * const refs_usage[] = {
REFS_MIGRATE_USAGE,
@@ -108,5 +116,5 @@ int cmd_refs(int argc,
};
argc = parse_options(argc, argv, prefix, opts, refs_usage, 0);
- return fn(argc, argv, prefix);
+ return fn(argc, argv, prefix, repo);
}
diff --git a/builtin/remote.c b/builtin/remote.c
index 76670ddd8b..0435963286 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "gettext.h"
@@ -155,7 +157,8 @@ static int parse_mirror_opt(const struct option *opt, const char *arg, int not)
return 0;
}
-static int add(int argc, const char **argv, const char *prefix)
+static int add(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int fetch = 0, fetch_tags = TAGS_DEFAULT;
unsigned mirror = MIRROR_NONE;
@@ -377,7 +380,7 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
for (i = 0; i < states->remote->fetch.nr; i++)
if (get_fetch_map(remote_refs, &states->remote->fetch.items[i], &tail, 1))
die(_("Could not get fetch map for refspec %s"),
- states->remote->fetch.raw[i]);
+ states->remote->fetch.items[i].raw);
for (ref = fetch_map; ref; ref = ref->next) {
if (omit_name_by_refspec(ref->name, &states->remote->fetch))
@@ -633,12 +636,12 @@ static int migrate_file(struct remote *remote)
git_config_set_multivar(buf.buf, remote->url.v[i], "^$", 0);
strbuf_reset(&buf);
strbuf_addf(&buf, "remote.%s.push", remote->name);
- for (i = 0; i < remote->push.raw_nr; i++)
- git_config_set_multivar(buf.buf, remote->push.raw[i], "^$", 0);
+ for (i = 0; i < remote->push.nr; i++)
+ git_config_set_multivar(buf.buf, remote->push.items[i].raw, "^$", 0);
strbuf_reset(&buf);
strbuf_addf(&buf, "remote.%s.fetch", remote->name);
- for (i = 0; i < remote->fetch.raw_nr; i++)
- git_config_set_multivar(buf.buf, remote->fetch.raw[i], "^$", 0);
+ for (i = 0; i < remote->fetch.nr; i++)
+ git_config_set_multivar(buf.buf, remote->fetch.items[i].raw, "^$", 0);
if (remote->origin == REMOTE_REMOTES)
unlink_or_warn(git_path("remotes/%s", remote->name));
else if (remote->origin == REMOTE_BRANCHES)
@@ -706,7 +709,8 @@ static void handle_push_default(const char* old_name, const char* new_name)
}
-static int mv(int argc, const char **argv, const char *prefix)
+static int mv(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int show_progress = isatty(2);
struct option options[] = {
@@ -759,16 +763,16 @@ static int mv(int argc, const char **argv, const char *prefix)
goto out;
}
- if (oldremote->fetch.raw_nr) {
+ if (oldremote->fetch.nr) {
strbuf_reset(&buf);
strbuf_addf(&buf, "remote.%s.fetch", rename.new_name);
git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE);
strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old_name);
- for (i = 0; i < oldremote->fetch.raw_nr; i++) {
+ for (i = 0; i < oldremote->fetch.nr; i++) {
char *ptr;
strbuf_reset(&buf2);
- strbuf_addstr(&buf2, oldremote->fetch.raw[i]);
+ strbuf_addstr(&buf2, oldremote->fetch.items[i].raw);
ptr = strstr(buf2.buf, old_remote_context.buf);
if (ptr) {
refspec_updated = 1;
@@ -881,7 +885,8 @@ out:
return result;
}
-static int rm(int argc, const char **argv, const char *prefix)
+static int rm(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct option options[] = {
OPT_END()
@@ -1303,7 +1308,8 @@ static int show_all(void)
return result;
}
-static int show(int argc, const char **argv, const char *prefix)
+static int show(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int no_query = 0, result = 0, query_flag = 0;
struct option options[] = {
@@ -1399,11 +1405,42 @@ static int show(int argc, const char **argv, const char *prefix)
return result;
}
-static int set_head(int argc, const char **argv, const char *prefix)
+static void report_set_head_auto(const char *remote, const char *head_name,
+ struct strbuf *b_local_head, int was_detached) {
+ struct strbuf buf_prefix = STRBUF_INIT;
+ const char *prev_head = NULL;
+
+ strbuf_addf(&buf_prefix, "refs/remotes/%s/", remote);
+ skip_prefix(b_local_head->buf, buf_prefix.buf, &prev_head);
+
+ if (prev_head && !strcmp(prev_head, head_name))
+ printf(_("'%s/HEAD' is unchanged and points to '%s'\n"),
+ remote, head_name);
+ else if (prev_head)
+ printf(_("'%s/HEAD' has changed from '%s' and now points to '%s'\n"),
+ remote, prev_head, head_name);
+ else if (!b_local_head->len)
+ printf(_("'%s/HEAD' is now created and points to '%s'\n"),
+ remote, head_name);
+ else if (was_detached && b_local_head->len)
+ printf(_("'%s/HEAD' was detached at '%s' and now points to '%s'\n"),
+ remote, b_local_head->buf, head_name);
+ else
+ printf(_("'%s/HEAD' used to point to '%s' "
+ "(which is not a remote branch), but now points to '%s'\n"),
+ remote, b_local_head->buf, head_name);
+ strbuf_release(&buf_prefix);
+}
+
+static int set_head(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
- int i, opt_a = 0, opt_d = 0, result = 0;
- struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT;
+ int i, opt_a = 0, opt_d = 0, result = 0, was_detached;
+ struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT,
+ b_local_head = STRBUF_INIT;
char *head_name = NULL;
+ struct ref_store *refs = get_main_ref_store(the_repository);
+ struct remote *remote;
struct option options[] = {
OPT_BOOL('a', "auto", &opt_a,
@@ -1414,8 +1451,10 @@ static int set_head(int argc, const char **argv, const char *prefix)
};
argc = parse_options(argc, argv, prefix, options,
builtin_remote_sethead_usage, 0);
- if (argc)
- strbuf_addf(&buf, "refs/remotes/%s/HEAD", argv[0]);
+ if (argc) {
+ strbuf_addf(&b_head, "refs/remotes/%s/HEAD", argv[0]);
+ remote = remote_get(argv[0]);
+ }
if (!opt_a && !opt_d && argc == 2) {
head_name = xstrdup(argv[1]);
@@ -1434,25 +1473,39 @@ static int set_head(int argc, const char **argv, const char *prefix)
head_name = xstrdup(states.heads.items[0].string);
free_remote_ref_states(&states);
} else if (opt_d && !opt_a && argc == 1) {
- if (refs_delete_ref(get_main_ref_store(the_repository), NULL, buf.buf, NULL, REF_NO_DEREF))
- result |= error(_("Could not delete %s"), buf.buf);
+ if (refs_delete_ref(refs, NULL, b_head.buf, NULL, REF_NO_DEREF))
+ result |= error(_("Could not delete %s"), b_head.buf);
} else
usage_with_options(builtin_remote_sethead_usage, options);
- if (head_name) {
- strbuf_addf(&buf2, "refs/remotes/%s/%s", argv[0], head_name);
- /* make sure it's valid */
- if (!refs_ref_exists(get_main_ref_store(the_repository), buf2.buf))
- result |= error(_("Not a valid ref: %s"), buf2.buf);
- else if (refs_update_symref(get_main_ref_store(the_repository), buf.buf, buf2.buf, "remote set-head"))
- result |= error(_("Could not setup %s"), buf.buf);
- else if (opt_a)
- printf("%s/HEAD set to %s\n", argv[0], head_name);
- free(head_name);
+ if (!head_name)
+ goto cleanup;
+ strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", argv[0], head_name);
+ if (!refs_ref_exists(refs, b_remote_head.buf)) {
+ result |= error(_("Not a valid ref: %s"), b_remote_head.buf);
+ goto cleanup;
+ }
+ was_detached = refs_update_symref_extended(refs, b_head.buf, b_remote_head.buf,
+ "remote set-head", &b_local_head, 0);
+ if (was_detached == -1) {
+ result |= error(_("Could not set up %s"), b_head.buf);
+ goto cleanup;
+ }
+ if (opt_a)
+ report_set_head_auto(argv[0], head_name, &b_local_head, was_detached);
+ if (remote->follow_remote_head == FOLLOW_REMOTE_ALWAYS) {
+ struct strbuf config_name = STRBUF_INIT;
+ strbuf_addf(&config_name,
+ "remote.%s.followremotehead", remote->name);
+ git_config_set(config_name.buf, "warn");
+ strbuf_release(&config_name);
}
- strbuf_release(&buf);
- strbuf_release(&buf2);
+cleanup:
+ free(head_name);
+ strbuf_release(&b_head);
+ strbuf_release(&b_remote_head);
+ strbuf_release(&b_local_head);
return result;
}
@@ -1503,7 +1556,8 @@ static int prune_remote(const char *remote, int dry_run)
return result;
}
-static int prune(int argc, const char **argv, const char *prefix)
+static int prune(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int dry_run = 0, result = 0;
struct option options[] = {
@@ -1534,7 +1588,8 @@ static int get_remote_default(const char *key, const char *value UNUSED,
return 0;
}
-static int update(int argc, const char **argv, const char *prefix)
+static int update(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int i, prune = -1;
struct option options[] = {
@@ -1616,7 +1671,8 @@ static int set_remote_branches(const char *remotename, const char **branches,
return 0;
}
-static int set_branches(int argc, const char **argv, const char *prefix)
+static int set_branches(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int add_mode = 0;
struct option options[] = {
@@ -1635,7 +1691,8 @@ static int set_branches(int argc, const char **argv, const char *prefix)
return set_remote_branches(argv[0], argv + 1, add_mode);
}
-static int get_url(int argc, const char **argv, const char *prefix)
+static int get_url(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int i, push_mode = 0, all_mode = 0;
const char *remotename = NULL;
@@ -1674,7 +1731,8 @@ static int get_url(int argc, const char **argv, const char *prefix)
return 0;
}
-static int set_url(int argc, const char **argv, const char *prefix)
+static int set_url(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int i, push_mode = 0, add_mode = 0, delete_mode = 0;
int matches = 0, negative_matches = 0;
@@ -1765,7 +1823,7 @@ out:
int cmd_remote(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
parse_opt_subcommand_fn *fn = NULL;
struct option options[] = {
@@ -1788,7 +1846,7 @@ int cmd_remote(int argc,
PARSE_OPT_SUBCOMMAND_OPTIONAL);
if (fn) {
- return !!fn(argc, argv, prefix);
+ return !!fn(argc, argv, prefix, repo);
} else {
if (argc) {
error(_("unknown subcommand: `%s'"), argv[0]);
diff --git a/builtin/repack.c b/builtin/repack.c
index d6bb37e84a..0c6dad7df4 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "dir.h"
@@ -404,7 +406,7 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
* {type -> existing pack order} ordering when computing deltas instead
* of a {type -> size} ordering, which may produce better deltas.
*/
- for_each_packed_object(write_oid, &cmd,
+ for_each_packed_object(the_repository, write_oid, &cmd,
FOR_EACH_OBJECT_PROMISOR_ONLY);
if (cmd.in == -1) {
@@ -1569,7 +1571,7 @@ int cmd_repack(int argc,
unsigned flags = 0;
if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL, 0))
flags |= MIDX_WRITE_INCREMENTAL;
- write_midx_file(repo_get_object_directory(the_repository),
+ write_midx_file(the_repository, repo_get_object_directory(the_repository),
NULL, NULL, flags);
}
diff --git a/builtin/replace.c b/builtin/replace.c
index a44f4e7ea9..a4eaadff91 100644
--- a/builtin/replace.c
+++ b/builtin/replace.c
@@ -201,7 +201,7 @@ static int replace_object_oid(const char *object_ref,
}
transaction = ref_store_transaction_begin(get_main_ref_store(the_repository),
- &err);
+ 0, &err);
if (!transaction ||
ref_transaction_update(transaction, ref.buf, repl, &prev,
NULL, NULL, 0, NULL, &err) ||
diff --git a/builtin/replay.c b/builtin/replay.c
index 2d12a4e403..1afc6d1ee0 100644
--- a/builtin/replay.c
+++ b/builtin/replay.c
@@ -2,9 +2,11 @@
* "git replay" builtin command
*/
+#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "git-compat-util.h"
-#define USE_THE_REPOSITORY_VARIABLE
#include "builtin.h"
#include "environment.h"
#include "hex.h"
diff --git a/builtin/rerere.c b/builtin/rerere.c
index f7143c3f5d..41127e24e5 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -1,4 +1,5 @@
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "config.h"
#include "gettext.h"
@@ -55,7 +56,7 @@ int cmd_rerere(int argc,
struct repository *repo UNUSED)
{
struct string_list merge_rr = STRING_LIST_INIT_DUP;
- int i, autoupdate = -1, flags = 0;
+ int autoupdate = -1, flags = 0;
struct option options[] = {
OPT_SET_INT(0, "rerere-autoupdate", &autoupdate,
@@ -98,11 +99,11 @@ int cmd_rerere(int argc,
if (setup_rerere(the_repository, &merge_rr,
flags | RERERE_READONLY) < 0)
return 0;
- for (i = 0; i < merge_rr.nr; i++)
+ for (size_t i = 0; i < merge_rr.nr; i++)
printf("%s\n", merge_rr.items[i].string);
} else if (!strcmp(argv[0], "remaining")) {
rerere_remaining(the_repository, &merge_rr);
- for (i = 0; i < merge_rr.nr; i++) {
+ for (size_t i = 0; i < merge_rr.nr; i++) {
if (merge_rr.items[i].util != RERERE_RESOLVED)
printf("%s\n", merge_rr.items[i].string);
else
@@ -114,7 +115,7 @@ int cmd_rerere(int argc,
if (setup_rerere(the_repository, &merge_rr,
flags | RERERE_READONLY) < 0)
return 0;
- for (i = 0; i < merge_rr.nr; i++) {
+ for (size_t i = 0; i < merge_rr.nr; i++) {
const char *path = merge_rr.items[i].string;
const struct rerere_id *id = merge_rr.items[i].util;
if (diff_two(rerere_path(id, "preimage"), path, path, path))
diff --git a/builtin/reset.c b/builtin/reset.c
index 7154f88826..73b4537a9a 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -7,7 +7,9 @@
*
* Copyright (c) 2005, 2006 Linus Torvalds and Junio C Hamano
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "advice.h"
#include "config.h"
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index f62bcbf2b1..3196da7b2d 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "commit.h"
@@ -121,7 +123,7 @@ static inline void finish_object__ma(struct object *obj)
return;
case MA_ALLOW_PROMISOR:
- if (is_promisor_object(&obj->oid))
+ if (is_promisor_object(the_repository, &obj->oid))
return;
die("unexpected missing %s object '%s'",
type_name(obj->type), oid_to_hex(&obj->oid));
@@ -485,6 +487,13 @@ static int try_bitmap_traversal(struct rev_info *revs,
if (revs->max_count >= 0)
return -1;
+ /*
+ * We can't know which commits were left/right in a single traversal,
+ * and we don't yet know how to traverse them separately.
+ */
+ if (revs->left_right)
+ return -1;
+
bitmap_git = prepare_bitmap_walk(revs, filter_provided_objects);
if (!bitmap_git)
return -1;
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 8401b4d7ab..949747a6b6 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -3,7 +3,10 @@
*
* Copyright (C) Linus Torvalds, 2005
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "abspath.h"
diff --git a/builtin/revert.c b/builtin/revert.c
index 55ba1092c5..aca6c293cd 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -1,4 +1,5 @@
#define USE_THE_REPOSITORY_VARIABLE
+
#include "git-compat-util.h"
#include "builtin.h"
#include "parse-options.h"
@@ -110,6 +111,9 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
const char * const * usage_str = revert_or_cherry_pick_usage(opts);
const char *me = action_name(opts);
const char *cleanup_arg = NULL;
+ const char sentinel_value;
+ const char *strategy = &sentinel_value;
+ const char *gpg_sign = &sentinel_value;
enum empty_action empty_opt = EMPTY_COMMIT_UNSPECIFIED;
int cmd = 0;
struct option base_options[] = {
@@ -125,10 +129,10 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
OPT_CALLBACK('m', "mainline", opts, N_("parent-number"),
N_("select mainline parent"), option_parse_m),
OPT_RERERE_AUTOUPDATE(&opts->allow_rerere_auto),
- OPT_STRING(0, "strategy", &opts->strategy, N_("strategy"), N_("merge strategy")),
+ OPT_STRING(0, "strategy", &strategy, N_("strategy"), N_("merge strategy")),
OPT_STRVEC('X', "strategy-option", &opts->xopts, N_("option"),
N_("option for merge strategy")),
- { OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key-id"),
+ { OPTION_STRING, 'S', "gpg-sign", &gpg_sign, N_("key-id"),
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
OPT_END()
};
@@ -240,8 +244,14 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
usage_with_options(usage_str, options);
/* These option values will be free()d */
- opts->gpg_sign = xstrdup_or_null(opts->gpg_sign);
- opts->strategy = xstrdup_or_null(opts->strategy);
+ if (gpg_sign != &sentinel_value) {
+ free(opts->gpg_sign);
+ opts->gpg_sign = xstrdup_or_null(gpg_sign);
+ }
+ if (strategy != &sentinel_value) {
+ free(opts->strategy);
+ opts->strategy = xstrdup_or_null(strategy);
+ }
if (!opts->strategy && getenv("GIT_TEST_MERGE_ALGORITHM"))
opts->strategy = xstrdup(getenv("GIT_TEST_MERGE_ALGORITHM"));
free(options);
diff --git a/builtin/rm.c b/builtin/rm.c
index eaff027258..12ae086a55 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -3,7 +3,10 @@
*
* Copyright (C) Linus Torvalds 2006
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "advice.h"
#include "config.h"
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 8b1d46e79a..59b626aae8 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -340,6 +340,7 @@ int cmd_send_pack(int argc,
/* stable plumbing output; do not modify or localize */
fprintf(stderr, "Everything up-to-date\n");
+ string_list_clear(&push_options, 0);
free_refs(remote_refs);
free_refs(local_refs);
refspec_clear(&rs);
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index 3ed5c46078..30075b67be 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -1,4 +1,5 @@
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "config.h"
#include "commit.h"
@@ -407,6 +408,18 @@ int cmd_shortlog(int argc,
struct parse_opt_ctx_t ctx;
+ /*
+ * NEEDSWORK: Later on we'll call parse_revision_opt which relies on
+ * the hash algorithm being set but since we are operating outside of a
+ * Git repository we cannot determine one. This is only needed because
+ * parse_revision_opt expects hexsz for --abbrev which is irrelevant
+ * for shortlog outside of a git repository. For now explicitly set
+ * SHA1, but ideally the parsing machinery would be split between
+ * git/nongit so that we do not have to do this.
+ */
+ if (nongit && !the_hash_algo)
+ repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
+
git_config(git_default_config, NULL);
shortlog_init(&log);
repo_init_revisions(the_repository, &rev, prefix);
diff --git a/builtin/show-branch.c b/builtin/show-branch.c
index cd6bdf63bc..fce6b404e9 100644
--- a/builtin/show-branch.c
+++ b/builtin/show-branch.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "environment.h"
diff --git a/builtin/show-index.c b/builtin/show-index.c
index f164c01bbe..756d632b51 100644
--- a/builtin/show-index.c
+++ b/builtin/show-index.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "gettext.h"
#include "hash.h"
@@ -38,6 +40,15 @@ int cmd_show_index(int argc,
repo_set_hash_algo(the_repository, hash_algo);
}
+ /*
+ * Fallback to SHA1 if we are running outside of a repository.
+ *
+ * TODO: Figure out and implement a way to detect the hash algorithm in use by the
+ * the index file passed in and use that instead.
+ */
+ if (!the_hash_algo)
+ repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
+
hashsz = the_hash_algo->rawsz;
if (fread(top_index, 2 * 4, 1, stdin) != 1)
diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
index 49aedc1de8..14dcace5f8 100644
--- a/builtin/sparse-checkout.c
+++ b/builtin/sparse-checkout.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "dir.h"
@@ -48,7 +50,8 @@ static char const * const builtin_sparse_checkout_list_usage[] = {
NULL
};
-static int sparse_checkout_list(int argc, const char **argv, const char *prefix)
+static int sparse_checkout_list(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
static struct option builtin_sparse_checkout_list_options[] = {
OPT_END(),
@@ -443,7 +446,8 @@ static struct sparse_checkout_init_opts {
int sparse_index;
} init_opts;
-static int sparse_checkout_init(int argc, const char **argv, const char *prefix)
+static int sparse_checkout_init(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct pattern_list pl;
char *sparse_filename;
@@ -669,7 +673,7 @@ static void add_patterns_literal(int argc, const char **argv,
add_patterns_from_input(pl, argc, argv, use_stdin ? stdin : NULL);
}
-static int modify_pattern_list(int argc, const char **argv, int use_stdin,
+static int modify_pattern_list(struct strvec *args, int use_stdin,
enum modify_type m)
{
int result;
@@ -679,13 +683,13 @@ static int modify_pattern_list(int argc, const char **argv, int use_stdin,
switch (m) {
case ADD:
if (core_sparse_checkout_cone)
- add_patterns_cone_mode(argc, argv, pl, use_stdin);
+ add_patterns_cone_mode(args->nr, args->v, pl, use_stdin);
else
- add_patterns_literal(argc, argv, pl, use_stdin);
+ add_patterns_literal(args->nr, args->v, pl, use_stdin);
break;
case REPLACE:
- add_patterns_from_input(pl, argc, argv,
+ add_patterns_from_input(pl, args->nr, args->v,
use_stdin ? stdin : NULL);
break;
}
@@ -706,12 +710,12 @@ static int modify_pattern_list(int argc, const char **argv, int use_stdin,
return result;
}
-static void sanitize_paths(int argc, const char **argv,
+static void sanitize_paths(struct strvec *args,
const char *prefix, int skip_checks)
{
int i;
- if (!argc)
+ if (!args->nr)
return;
if (prefix && *prefix && core_sparse_checkout_cone) {
@@ -721,8 +725,11 @@ static void sanitize_paths(int argc, const char **argv,
*/
int prefix_len = strlen(prefix);
- for (i = 0; i < argc; i++)
- argv[i] = prefix_path(prefix, prefix_len, argv[i]);
+ for (i = 0; i < args->nr; i++) {
+ char *prefixed_path = prefix_path(prefix, prefix_len, args->v[i]);
+ strvec_replace(args, i, prefixed_path);
+ free(prefixed_path);
+ }
}
if (skip_checks)
@@ -732,20 +739,20 @@ static void sanitize_paths(int argc, const char **argv,
die(_("please run from the toplevel directory in non-cone mode"));
if (core_sparse_checkout_cone) {
- for (i = 0; i < argc; i++) {
- if (argv[i][0] == '/')
+ for (i = 0; i < args->nr; i++) {
+ if (args->v[i][0] == '/')
die(_("specify directories rather than patterns (no leading slash)"));
- if (argv[i][0] == '!')
+ if (args->v[i][0] == '!')
die(_("specify directories rather than patterns. If your directory starts with a '!', pass --skip-checks"));
- if (strpbrk(argv[i], "*?[]"))
+ if (strpbrk(args->v[i], "*?[]"))
die(_("specify directories rather than patterns. If your directory really has any of '*?[]\\' in it, pass --skip-checks"));
}
}
- for (i = 0; i < argc; i++) {
+ for (i = 0; i < args->nr; i++) {
struct cache_entry *ce;
struct index_state *index = the_repository->index;
- int pos = index_name_pos(index, argv[i], strlen(argv[i]));
+ int pos = index_name_pos(index, args->v[i], strlen(args->v[i]));
if (pos < 0)
continue;
@@ -754,9 +761,9 @@ static void sanitize_paths(int argc, const char **argv,
continue;
if (core_sparse_checkout_cone)
- die(_("'%s' is not a directory; to treat it as a directory anyway, rerun with --skip-checks"), argv[i]);
+ die(_("'%s' is not a directory; to treat it as a directory anyway, rerun with --skip-checks"), args->v[i]);
else
- warning(_("pass a leading slash before paths such as '%s' if you want a single file (see NON-CONE PROBLEMS in the git-sparse-checkout manual)."), argv[i]);
+ warning(_("pass a leading slash before paths such as '%s' if you want a single file (see NON-CONE PROBLEMS in the git-sparse-checkout manual)."), args->v[i]);
}
}
@@ -770,7 +777,8 @@ static struct sparse_checkout_add_opts {
int use_stdin;
} add_opts;
-static int sparse_checkout_add(int argc, const char **argv, const char *prefix)
+static int sparse_checkout_add(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
static struct option builtin_sparse_checkout_add_options[] = {
OPT_BOOL_F(0, "skip-checks", &add_opts.skip_checks,
@@ -780,6 +788,8 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix)
N_("read patterns from standard in")),
OPT_END(),
};
+ struct strvec patterns = STRVEC_INIT;
+ int ret;
setup_work_tree();
if (!core_apply_sparse_checkout)
@@ -791,9 +801,14 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix)
builtin_sparse_checkout_add_options,
builtin_sparse_checkout_add_usage, 0);
- sanitize_paths(argc, argv, prefix, add_opts.skip_checks);
+ for (int i = 0; i < argc; i++)
+ strvec_push(&patterns, argv[i]);
+ sanitize_paths(&patterns, prefix, add_opts.skip_checks);
+
+ ret = modify_pattern_list(&patterns, add_opts.use_stdin, ADD);
- return modify_pattern_list(argc, argv, add_opts.use_stdin, ADD);
+ strvec_clear(&patterns);
+ return ret;
}
static char const * const builtin_sparse_checkout_set_usage[] = {
@@ -808,7 +823,8 @@ static struct sparse_checkout_set_opts {
int use_stdin;
} set_opts;
-static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
+static int sparse_checkout_set(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int default_patterns_nr = 2;
const char *default_patterns[] = {"/*", "!/*/", NULL};
@@ -826,6 +842,8 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
PARSE_OPT_NONEG),
OPT_END(),
};
+ struct strvec patterns = STRVEC_INIT;
+ int ret;
setup_work_tree();
repo_read_index(the_repository);
@@ -846,13 +864,18 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
* top-level directory (much as 'init' would do).
*/
if (!core_sparse_checkout_cone && !set_opts.use_stdin && argc == 0) {
- argv = default_patterns;
- argc = default_patterns_nr;
+ for (int i = 0; i < default_patterns_nr; i++)
+ strvec_push(&patterns, default_patterns[i]);
} else {
- sanitize_paths(argc, argv, prefix, set_opts.skip_checks);
+ for (int i = 0; i < argc; i++)
+ strvec_push(&patterns, argv[i]);
+ sanitize_paths(&patterns, prefix, set_opts.skip_checks);
}
- return modify_pattern_list(argc, argv, set_opts.use_stdin, REPLACE);
+ ret = modify_pattern_list(&patterns, set_opts.use_stdin, REPLACE);
+
+ strvec_clear(&patterns);
+ return ret;
}
static char const * const builtin_sparse_checkout_reapply_usage[] = {
@@ -866,7 +889,8 @@ static struct sparse_checkout_reapply_opts {
} reapply_opts;
static int sparse_checkout_reapply(int argc, const char **argv,
- const char *prefix)
+ const char *prefix,
+ struct repository *repo UNUSED)
{
static struct option builtin_sparse_checkout_reapply_options[] = {
OPT_BOOL(0, "cone", &reapply_opts.cone_mode,
@@ -901,7 +925,8 @@ static char const * const builtin_sparse_checkout_disable_usage[] = {
};
static int sparse_checkout_disable(int argc, const char **argv,
- const char *prefix)
+ const char *prefix,
+ struct repository *repo UNUSED)
{
static struct option builtin_sparse_checkout_disable_options[] = {
OPT_END(),
@@ -989,7 +1014,8 @@ static int check_rules(struct pattern_list *pl, int null_terminated) {
return 0;
}
-static int sparse_checkout_check_rules(int argc, const char **argv, const char *prefix)
+static int sparse_checkout_check_rules(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
static struct option builtin_sparse_checkout_check_rules_options[] = {
OPT_BOOL('z', NULL, &check_rules_opts.null_termination,
@@ -1037,7 +1063,7 @@ static int sparse_checkout_check_rules(int argc, const char **argv, const char *
int cmd_sparse_checkout(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
parse_opt_subcommand_fn *fn = NULL;
struct option builtin_sparse_checkout_options[] = {
@@ -1060,5 +1086,5 @@ int cmd_sparse_checkout(int argc,
prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 0;
- return fn(argc, argv, prefix);
+ return fn(argc, argv, prefix, repo);
}
diff --git a/builtin/stash.c b/builtin/stash.c
index f1acc918d0..dbaa999cf1 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -1,4 +1,5 @@
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "abspath.h"
#include "config.h"
@@ -249,7 +250,8 @@ static int do_clear_stash(void)
ref_stash, &obj, 0);
}
-static int clear_stash(int argc, const char **argv, const char *prefix)
+static int clear_stash(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct option options[] = {
OPT_END()
@@ -652,7 +654,8 @@ restore_untracked:
return ret;
}
-static int apply_stash(int argc, const char **argv, const char *prefix)
+static int apply_stash(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int ret = -1;
int quiet = 0;
@@ -726,7 +729,8 @@ static int get_stash_info_assert(struct stash_info *info, int argc,
return 0;
}
-static int drop_stash(int argc, const char **argv, const char *prefix)
+static int drop_stash(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int ret = -1;
int quiet = 0;
@@ -748,7 +752,8 @@ cleanup:
return ret;
}
-static int pop_stash(int argc, const char **argv, const char *prefix)
+static int pop_stash(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int ret = -1;
int index = 0;
@@ -778,7 +783,8 @@ cleanup:
return ret;
}
-static int branch_stash(int argc, const char **argv, const char *prefix)
+static int branch_stash(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int ret = -1;
const char *branch = NULL;
@@ -816,7 +822,8 @@ cleanup:
return ret;
}
-static int list_stash(int argc, const char **argv, const char *prefix)
+static int list_stash(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct child_process cp = CHILD_PROCESS_INIT;
struct option options[] = {
@@ -867,9 +874,8 @@ static void diff_include_untracked(const struct stash_info *info, struct diff_op
struct tree *tree[ARRAY_SIZE(oid)];
struct tree_desc tree_desc[ARRAY_SIZE(oid)];
struct unpack_trees_options unpack_tree_opt = { 0 };
- int i;
- for (i = 0; i < ARRAY_SIZE(oid); i++) {
+ for (size_t i = 0; i < ARRAY_SIZE(oid); i++) {
tree[i] = parse_tree_indirect(oid[i]);
if (parse_tree(tree[i]) < 0)
die(_("failed to parse tree"));
@@ -889,7 +895,8 @@ static void diff_include_untracked(const struct stash_info *info, struct diff_op
do_diff_cache(&info->b_commit, diff_opt);
}
-static int show_stash(int argc, const char **argv, const char *prefix)
+static int show_stash(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int i;
int ret = -1;
@@ -1017,7 +1024,8 @@ static int do_store_stash(const struct object_id *w_commit, const char *stash_ms
return 0;
}
-static int store_stash(int argc, const char **argv, const char *prefix)
+static int store_stash(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int quiet = 0;
const char *stash_msg = NULL;
@@ -1491,7 +1499,8 @@ done:
return ret;
}
-static int create_stash(int argc, const char **argv, const char *prefix UNUSED)
+static int create_stash(int argc, const char **argv, const char *prefix UNUSED,
+ struct repository *repo UNUSED)
{
int ret;
struct strbuf stash_msg_buf = STRBUF_INIT;
@@ -1548,12 +1557,11 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
repo_read_index_preload(the_repository, NULL, 0);
if (!include_untracked && ps->nr) {
- int i;
char *ps_matched = xcalloc(ps->nr, 1);
/* TODO: audit for interaction with sparse-index. */
ensure_full_index(the_repository->index);
- for (i = 0; i < the_repository->index->cache_nr; i++)
+ for (size_t i = 0; i < the_repository->index->cache_nr; i++)
ce_path_match(the_repository->index, the_repository->index->cache[i], ps,
ps_matched);
@@ -1759,7 +1767,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,
int quiet = 0;
int pathspec_file_nul = 0;
const char *stash_msg = NULL;
- const char *pathspec_from_file = NULL;
+ char *pathspec_from_file = NULL;
struct pathspec ps;
struct option options[] = {
OPT_BOOL('k', "keep-index", &keep_index,
@@ -1821,16 +1829,20 @@ static int push_stash(int argc, const char **argv, const char *prefix,
ret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,
include_untracked, only_staged);
+
clear_pathspec(&ps);
+ free(pathspec_from_file);
return ret;
}
-static int push_stash_unassumed(int argc, const char **argv, const char *prefix)
+static int push_stash_unassumed(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
return push_stash(argc, argv, prefix, 0);
}
-static int save_stash(int argc, const char **argv, const char *prefix)
+static int save_stash(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int keep_index = -1;
int only_staged = 0;
@@ -1876,7 +1888,7 @@ static int save_stash(int argc, const char **argv, const char *prefix)
int cmd_stash(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
pid_t pid = getpid();
const char *index_file;
@@ -1914,9 +1926,9 @@ int cmd_stash(int argc,
(uintmax_t)pid);
if (fn)
- return !!fn(argc, argv, prefix);
+ return !!fn(argc, argv, prefix, repo);
else if (!argc)
- return !!push_stash_unassumed(0, NULL, prefix);
+ return !!push_stash_unassumed(0, NULL, prefix, repo);
/* Assume 'stash push' */
strvec_push(&args, "push");
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index b6b5f1ebde..f9b970f8a6 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1,4 +1,5 @@
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "abspath.h"
#include "environment.h"
@@ -194,7 +195,7 @@ static int module_list_compute(const char **argv,
struct pathspec *pathspec,
struct module_list *list)
{
- int i, result = 0;
+ int result = 0;
char *ps_matched = NULL;
parse_pathspec(pathspec, 0,
@@ -207,7 +208,7 @@ static int module_list_compute(const char **argv,
if (repo_read_index(the_repository) < 0)
die(_("index file corrupt"));
- for (i = 0; i < the_repository->index->cache_nr; i++) {
+ for (size_t i = 0; i < the_repository->index->cache_nr; i++) {
const struct cache_entry *ce = the_repository->index->cache[i];
if (!match_pathspec(the_repository->index, pathspec, ce->name, ce_namelen(ce),
@@ -399,7 +400,8 @@ cleanup:
free(displaypath);
}
-static int module_foreach(int argc, const char **argv, const char *prefix)
+static int module_foreach(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct foreach_cb info = FOREACH_CB_INIT;
struct pathspec pathspec = { 0 };
@@ -544,7 +546,8 @@ static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data
info->flags);
}
-static int module_init(int argc, const char **argv, const char *prefix)
+static int module_init(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct init_cb info = INIT_CB_INIT;
struct pathspec pathspec = { 0 };
@@ -738,7 +741,8 @@ static void status_submodule_cb(const struct cache_entry *list_item,
info->prefix, info->super_prefix, info->flags);
}
-static int module_status(int argc, const char **argv, const char *prefix)
+static int module_status(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct status_cb info = STATUS_CB_INIT;
struct pathspec pathspec = { 0 };
@@ -1163,7 +1167,8 @@ cleanup:
return ret;
}
-static int module_summary(int argc, const char **argv, const char *prefix)
+static int module_summary(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct summary_cb info = SUMMARY_CB_INIT;
int cached = 0;
@@ -1339,7 +1344,8 @@ static void sync_submodule_cb(const struct cache_entry *list_item, void *cb_data
info->flags);
}
-static int module_sync(int argc, const char **argv, const char *prefix)
+static int module_sync(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct sync_cb info = SYNC_CB_INIT;
struct pathspec pathspec = { 0 };
@@ -1485,7 +1491,8 @@ static void deinit_submodule_cb(const struct cache_entry *list_item,
deinit_submodule(list_item->name, info->prefix, info->flags);
}
-static int module_deinit(int argc, const char **argv, const char *prefix)
+static int module_deinit(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct deinit_cb info = DEINIT_CB_INIT;
struct pathspec pathspec = { 0 };
@@ -1842,7 +1849,8 @@ static int clone_submodule(const struct module_clone_data *clone_data,
return 0;
}
-static int module_clone(int argc, const char **argv, const char *prefix)
+static int module_clone(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int dissociate = 0, quiet = 0, progress = 0, require_init = 0;
struct module_clone_data clone_data = MODULE_CLONE_DATA_INIT;
@@ -2779,7 +2787,8 @@ cleanup:
return ret;
}
-static int module_update(int argc, const char **argv, const char *prefix)
+static int module_update(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
struct pathspec pathspec = { 0 };
struct pathspec pathspec2 = { 0 };
@@ -2911,7 +2920,8 @@ cleanup:
return ret;
}
-static int push_check(int argc, const char **argv, const char *prefix UNUSED)
+static int push_check(int argc, const char **argv, const char *prefix UNUSED,
+ struct repository *repo UNUSED)
{
struct remote *remote;
const char *superproject_head;
@@ -2991,7 +3001,8 @@ static int push_check(int argc, const char **argv, const char *prefix UNUSED)
return 0;
}
-static int absorb_git_dirs(int argc, const char **argv, const char *prefix)
+static int absorb_git_dirs(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int i;
struct pathspec pathspec = { 0 };
@@ -3024,7 +3035,8 @@ cleanup:
return ret;
}
-static int module_set_url(int argc, const char **argv, const char *prefix)
+static int module_set_url(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int quiet = 0, ret;
const char *newurl;
@@ -3063,7 +3075,8 @@ static int module_set_url(int argc, const char **argv, const char *prefix)
return !!ret;
}
-static int module_set_branch(int argc, const char **argv, const char *prefix)
+static int module_set_branch(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int opt_default = 0, ret;
const char *opt_branch = NULL;
@@ -3113,7 +3126,8 @@ static int module_set_branch(int argc, const char **argv, const char *prefix)
return !!ret;
}
-static int module_create_branch(int argc, const char **argv, const char *prefix)
+static int module_create_branch(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
enum branch_track track;
int quiet = 0, force = 0, reflog = 0, dry_run = 0;
@@ -3383,7 +3397,6 @@ static void die_on_index_match(const char *path, int force)
die(_("index file corrupt"));
if (ps.nr) {
- int i;
char *ps_matched = xcalloc(ps.nr, 1);
/* TODO: audit for interaction with sparse-index. */
@@ -3393,7 +3406,7 @@ static void die_on_index_match(const char *path, int force)
* Since there is only one pathspec, we just need to
* check ps_matched[0] to know if a cache entry matched.
*/
- for (i = 0; i < the_repository->index->cache_nr; i++) {
+ for (size_t i = 0; i < the_repository->index->cache_nr; i++) {
ce_path_match(the_repository->index, the_repository->index->cache[i], &ps,
ps_matched);
@@ -3424,7 +3437,8 @@ static void die_on_repo_without_commits(const char *path)
strbuf_release(&sb);
}
-static int module_add(int argc, const char **argv, const char *prefix)
+static int module_add(int argc, const char **argv, const char *prefix,
+ struct repository *repo UNUSED)
{
int force = 0, quiet = 0, progress = 0, dissociate = 0;
struct add_data add_data = ADD_DATA_INIT;
@@ -3557,7 +3571,7 @@ cleanup:
int cmd_submodule__helper(int argc,
const char **argv,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
parse_opt_subcommand_fn *fn = NULL;
const char *const usage[] = {
@@ -3583,5 +3597,5 @@ int cmd_submodule__helper(int argc,
};
argc = parse_options(argc, argv, prefix, options, usage, 0);
- return fn(argc, argv, prefix);
+ return fn(argc, argv, prefix, repo);
}
diff --git a/builtin/tag.c b/builtin/tag.c
index 93d10d5915..c4bd145831 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -5,7 +5,10 @@
* Carlos Rica <jasampler@gmail.com>
* Based on git-tag.sh and mktag.c by Linus Torvalds.
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "advice.h"
#include "config.h"
@@ -164,7 +167,7 @@ static int do_sign(struct strbuf *buffer, struct object_id **compat_oid,
int ret = -1;
if (sign_buffer(buffer, &sig, keyid))
- return -1;
+ goto out;
if (compat) {
const struct git_hash_algo *algo = the_repository->hash_algo;
@@ -447,17 +450,6 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset)
return 0;
}
-static int strbuf_check_tag_ref(struct strbuf *sb, const char *name)
-{
- if (name[0] == '-')
- return -1;
-
- strbuf_reset(sb);
- strbuf_addf(sb, "refs/tags/%s", name);
-
- return check_refname_format(sb->buf, 0);
-}
-
int cmd_tag(int argc,
const char **argv,
const char *prefix,
@@ -650,7 +642,7 @@ int cmd_tag(int argc,
if (repo_get_oid(the_repository, object_ref, &object))
die(_("Failed to resolve '%s' as a valid ref."), object_ref);
- if (strbuf_check_tag_ref(&ref, tag))
+ if (check_tag_ref(&ref, tag))
die(_("'%s' is not a valid tag name."), tag);
if (refs_read_ref(get_main_ref_store(the_repository), ref.buf, &prev))
@@ -681,7 +673,7 @@ int cmd_tag(int argc,
}
transaction = ref_store_transaction_begin(get_main_ref_store(the_repository),
- &err);
+ 0, &err);
if (!transaction ||
ref_transaction_update(transaction, ref.buf, &object, &prev,
NULL, NULL,
diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c
index 02b8d02f63..2197d6d933 100644
--- a/builtin/unpack-objects.c
+++ b/builtin/unpack-objects.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "bulk-checkin.h"
#include "config.h"
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 45b4a8b555..74bbad9f87 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -3,7 +3,10 @@
*
* Copyright (C) Linus Torvalds, 2005
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "bulk-checkin.h"
#include "config.h"
diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 8a98615dc8..4d35bdc4b4 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "config.h"
#include "gettext.h"
@@ -612,7 +614,7 @@ static void update_refs_stdin(void)
int i, j;
transaction = ref_store_transaction_begin(get_main_ref_store(the_repository),
- &err);
+ 0, &err);
if (!transaction)
die("%s", err.buf);
@@ -680,7 +682,7 @@ static void update_refs_stdin(void)
*/
state = cmd->state;
transaction = ref_store_transaction_begin(get_main_ref_store(the_repository),
- &err);
+ 0, &err);
if (!transaction)
die("%s", err.buf);
diff --git a/builtin/upload-pack.c b/builtin/upload-pack.c
index 3b6c83fbce..dd63d6eadf 100644
--- a/builtin/upload-pack.c
+++ b/builtin/upload-pack.c
@@ -39,6 +39,7 @@ int cmd_upload_pack(int argc,
N_("interrupt transfer after <n> seconds of inactivity")),
OPT_END()
};
+ unsigned enter_repo_flags = ENTER_REPO_ANY_OWNER_OK;
packet_trace_identity("upload-pack");
disable_replace_refs();
@@ -54,7 +55,9 @@ int cmd_upload_pack(int argc,
dir = argv[0];
- if (!enter_repo(dir, strict))
+ if (strict)
+ enter_repo_flags |= ENTER_REPO_STRICT;
+ if (!enter_repo(dir, enter_repo_flags))
die("'%s' does not appear to be a git repository", dir);
switch (determine_protocol_version_server()) {
diff --git a/builtin/var.c b/builtin/var.c
index 2ecaed51b4..1449656cc9 100644
--- a/builtin/var.c
+++ b/builtin/var.c
@@ -3,7 +3,9 @@
*
* Copyright (C) Eric Biederman, 2005
*/
+
#define USE_THE_REPOSITORY_VARIABLE
+
#include "builtin.h"
#include "attr.h"
@@ -178,10 +180,9 @@ static void list_vars(void)
if ((val = ptr->read(0))) {
if (ptr->multivalued && *val) {
struct string_list list = STRING_LIST_INIT_DUP;
- int i;
string_list_split(&list, val, '\n', -1);
- for (i = 0; i < list.nr; i++)
+ for (size_t i = 0; i < list.nr; i++)
printf("%s=%s\n", ptr->name, list.items[i].string);
string_list_clear(&list, 0);
} else {
diff --git a/builtin/worktree.c b/builtin/worktree.c
index fc31d072a6..c043d4d523 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -1,4 +1,6 @@
#define USE_THE_REPOSITORY_VARIABLE
+#define DISABLE_SIGN_COMPARE_WARNINGS
+
#include "builtin.h"
#include "abspath.h"
#include "advice.h"
@@ -120,12 +122,14 @@ struct add_opts {
int quiet;
int checkout;
int orphan;
+ int relative_paths;
const char *keep_locked;
};
static int show_only;
static int verbose;
static int guess_remote;
+static int use_relative_paths;
static timestamp_t expire;
static int git_worktree_config(const char *var, const char *value,
@@ -134,6 +138,9 @@ static int git_worktree_config(const char *var, const char *value,
if (!strcmp(var, "worktree.guessremote")) {
guess_remote = git_config_bool(var, value);
return 0;
+ } else if (!strcmp(var, "worktree.userelativepaths")) {
+ use_relative_paths = git_config_bool(var, value);
+ return 0;
}
return git_default_config(var, value, ctx, cb);
@@ -231,7 +238,8 @@ static void prune_worktrees(void)
strbuf_release(&reason);
}
-static int prune(int ac, const char **av, const char *prefix)
+static int prune(int ac, const char **av, const char *prefix,
+ struct repository *repo UNUSED)
{
struct option options[] = {
OPT__DRY_RUN(&show_only, N_("do not remove, show only")),
@@ -414,7 +422,7 @@ static int add_worktree(const char *path, const char *refname,
const struct add_opts *opts)
{
struct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT;
- struct strbuf sb = STRBUF_INIT, realpath = STRBUF_INIT;
+ struct strbuf sb = STRBUF_INIT;
const char *name;
struct strvec child_env = STRVEC_INIT;
unsigned int counter = 0;
@@ -432,7 +440,7 @@ static int add_worktree(const char *path, const char *refname,
worktrees = NULL;
/* is 'refname' a branch or commit? */
- if (!opts->detach && !strbuf_check_branch_ref(&symref, refname) &&
+ if (!opts->detach && !check_branch_ref(&symref, refname) &&
refs_ref_exists(get_main_ref_store(the_repository), symref.buf)) {
is_branch = 1;
if (!opts->force)
@@ -490,11 +498,7 @@ static int add_worktree(const char *path, const char *refname,
strbuf_reset(&sb);
strbuf_addf(&sb, "%s/gitdir", sb_repo.buf);
- strbuf_realpath(&realpath, sb_git.buf, 1);
- write_file(sb.buf, "%s", realpath.buf);
- strbuf_realpath(&realpath, repo_get_common_dir(the_repository), 1);
- write_file(sb_git.buf, "gitdir: %s/worktrees/%s",
- realpath.buf, name);
+ write_worktree_linking_files(sb_git, sb, opts->relative_paths);
strbuf_reset(&sb);
strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
write_file(sb.buf, "../..");
@@ -582,7 +586,6 @@ done:
strbuf_release(&sb_repo);
strbuf_release(&sb_git);
strbuf_release(&sb_name);
- strbuf_release(&realpath);
free_worktree(wt);
return ret;
}
@@ -604,7 +607,7 @@ static void print_preparing_worktree_line(int detach,
fprintf_ln(stderr, _("Preparing worktree (new branch '%s')"), new_branch);
} else {
struct strbuf s = STRBUF_INIT;
- if (!detach && !strbuf_check_branch_ref(&s, branch) &&
+ if (!detach && !check_branch_ref(&s, branch) &&
refs_ref_exists(get_main_ref_store(the_repository), s.buf))
fprintf_ln(stderr, _("Preparing worktree (checking out '%s')"),
branch);
@@ -745,7 +748,7 @@ static char *dwim_branch(const char *path, char **new_branch)
char *branchname = xstrndup(s, n);
struct strbuf ref = STRBUF_INIT;
- branch_exists = !strbuf_check_branch_ref(&ref, branchname) &&
+ branch_exists = !check_branch_ref(&ref, branchname) &&
refs_ref_exists(get_main_ref_store(the_repository),
ref.buf);
strbuf_release(&ref);
@@ -761,7 +764,8 @@ static char *dwim_branch(const char *path, char **new_branch)
return NULL;
}
-static int add(int ac, const char **av, const char *prefix)
+static int add(int ac, const char **av, const char *prefix,
+ struct repository *repo UNUSED)
{
struct add_opts opts;
const char *new_branch_force = NULL;
@@ -794,12 +798,15 @@ static int add(int ac, const char **av, const char *prefix)
PARSE_OPT_NOARG | PARSE_OPT_OPTARG),
OPT_BOOL(0, "guess-remote", &guess_remote,
N_("try to match the new branch name with a remote-tracking branch")),
+ OPT_BOOL(0, "relative-paths", &opts.relative_paths,
+ N_("use relative paths for worktrees")),
OPT_END()
};
int ret;
memset(&opts, 0, sizeof(opts));
opts.checkout = 1;
+ opts.relative_paths = use_relative_paths;
ac = parse_options(ac, av, prefix, options, git_worktree_add_usage, 0);
if (!!opts.detach + !!new_branch + !!new_branch_force > 1)
die(_("options '%s', '%s', and '%s' cannot be used together"), "-b", "-B", "--detach");
@@ -838,7 +845,7 @@ static int add(int ac, const char **av, const char *prefix)
new_branch = new_branch_force;
if (!opts.force &&
- !strbuf_check_branch_ref(&symref, new_branch) &&
+ !check_branch_ref(&symref, new_branch) &&
refs_ref_exists(get_main_ref_store(the_repository), symref.buf))
die_if_checked_out(symref.buf, 0);
strbuf_release(&symref);
@@ -1037,7 +1044,8 @@ static void pathsort(struct worktree **wt)
QSORT(wt, n, pathcmp);
}
-static int list(int ac, const char **av, const char *prefix)
+static int list(int ac, const char **av, const char *prefix,
+ struct repository *repo UNUSED)
{
int porcelain = 0;
int line_terminator = '\n';
@@ -1082,7 +1090,8 @@ static int list(int ac, const char **av, const char *prefix)
return 0;
}
-static int lock_worktree(int ac, const char **av, const char *prefix)
+static int lock_worktree(int ac, const char **av, const char *prefix,
+ struct repository *repo UNUSED)
{
const char *reason = "", *old_reason;
struct option options[] = {
@@ -1117,7 +1126,8 @@ static int lock_worktree(int ac, const char **av, const char *prefix)
return 0;
}
-static int unlock_worktree(int ac, const char **av, const char *prefix)
+static int unlock_worktree(int ac, const char **av, const char *prefix,
+ struct repository *repo UNUSED)
{
struct option options[] = {
OPT_END()
@@ -1180,13 +1190,16 @@ static void validate_no_submodules(const struct worktree *wt)
die(_("working trees containing submodules cannot be moved or removed"));
}
-static int move_worktree(int ac, const char **av, const char *prefix)
+static int move_worktree(int ac, const char **av, const char *prefix,
+ struct repository *repo UNUSED)
{
int force = 0;
struct option options[] = {
OPT__FORCE(&force,
N_("force move even if worktree is dirty or locked"),
PARSE_OPT_NOCOMPLETE),
+ OPT_BOOL(0, "relative-paths", &use_relative_paths,
+ N_("use relative paths for worktrees")),
OPT_END()
};
struct worktree **worktrees, *wt;
@@ -1239,7 +1252,7 @@ static int move_worktree(int ac, const char **av, const char *prefix)
if (rename(wt->path, dst.buf) == -1)
die_errno(_("failed to move '%s' to '%s'"), wt->path, dst.buf);
- update_worktree_location(wt, dst.buf);
+ update_worktree_location(wt, dst.buf, use_relative_paths);
strbuf_release(&dst);
free_worktrees(worktrees);
@@ -1310,7 +1323,8 @@ static int delete_git_work_tree(struct worktree *wt)
return ret;
}
-static int remove_worktree(int ac, const char **av, const char *prefix)
+static int remove_worktree(int ac, const char **av, const char *prefix,
+ struct repository *repo UNUSED)
{
int force = 0;
struct option options[] = {
@@ -1375,11 +1389,14 @@ static void report_repair(int iserr, const char *path, const char *msg, void *cb
}
}
-static int repair(int ac, const char **av, const char *prefix)
+static int repair(int ac, const char **av, const char *prefix,
+ struct repository *repo UNUSED)
{
const char **p;
const char *self[] = { ".", NULL };
struct option options[] = {
+ OPT_BOOL(0, "relative-paths", &use_relative_paths,
+ N_("use relative paths for worktrees")),
OPT_END()
};
int rc = 0;
@@ -1387,15 +1404,15 @@ static int repair(int ac, const char **av, const char *prefix)
ac = parse_options(ac, av, prefix, options, git_worktree_repair_usage, 0);
p = ac > 0 ? av : self;
for (; *p; p++)
- repair_worktree_at_path(*p, report_repair, &rc);
- repair_worktrees(report_repair, &rc);
+ repair_worktree_at_path(*p, report_repair, &rc, use_relative_paths);
+ repair_worktrees(report_repair, &rc, use_relative_paths);
return rc;
}
int cmd_worktree(int ac,
const char **av,
const char *prefix,
- struct repository *repo UNUSED)
+ struct repository *repo)
{
parse_opt_subcommand_fn *fn = NULL;
struct option options[] = {
@@ -1420,5 +1437,5 @@ int cmd_worktree(int ac,
prepare_repo_settings(the_repository);
the_repository->settings.command_requires_full_index = 0;
- return fn(ac, av, prefix);
+ return fn(ac, av, prefix, repo);
}