summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
Diffstat (limited to 'builtin')
-rw-r--r--builtin/branch.c8
-rw-r--r--builtin/bugreport.c3
-rw-r--r--builtin/checkout.c6
-rw-r--r--builtin/clone.c17
-rw-r--r--builtin/config.c81
-rw-r--r--builtin/credential-store.c8
-rw-r--r--builtin/fast-export.c1
-rw-r--r--builtin/gc.c27
-rw-r--r--builtin/grep.c1
-rw-r--r--builtin/index-pack.c2
-rw-r--r--builtin/init-db.c8
-rw-r--r--builtin/log.c1
-rw-r--r--builtin/name-rev.c4
-rw-r--r--builtin/pack-objects.c1
-rw-r--r--builtin/pack-redundant.c6
-rw-r--r--builtin/pull.c118
-rw-r--r--builtin/rebase.c4
-rw-r--r--builtin/receive-pack.c15
-rw-r--r--builtin/remote.c8
-rw-r--r--builtin/repack.c153
-rw-r--r--builtin/rev-parse.c106
-rw-r--r--builtin/stash.c2
-rw-r--r--builtin/update-ref.c15
-rw-r--r--builtin/worktree.c6
24 files changed, 386 insertions, 215 deletions
diff --git a/builtin/branch.c b/builtin/branch.c
index efb30b8820..9b68591add 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -538,7 +538,9 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
strbuf_addf(&logmsg, "Branch: renamed %s to %s",
oldref.buf, newref.buf);
- if (!copy && rename_ref(oldref.buf, newref.buf, logmsg.buf))
+ if (!copy &&
+ (!head || strcmp(oldname, head) || !is_null_oid(&head_oid)) &&
+ rename_ref(oldref.buf, newref.buf, logmsg.buf))
die(_("Branch rename failed"));
if (copy && copy_existing_ref(oldref.buf, newref.buf, logmsg.buf))
die(_("Branch copy failed"));
@@ -829,10 +831,10 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
die(_("Branch '%s' has no upstream information"), branch->name);
strbuf_addf(&buf, "branch.%s.remote", branch->name);
- git_config_set_multivar(buf.buf, NULL, NULL, 1);
+ git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE);
strbuf_reset(&buf);
strbuf_addf(&buf, "branch.%s.merge", branch->name);
- git_config_set_multivar(buf.buf, NULL, NULL, 1);
+ git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE);
strbuf_release(&buf);
} else if (argc > 0 && argc <= 2) {
if (filter.kind != FILTER_REFS_BRANCHES)
diff --git a/builtin/bugreport.c b/builtin/bugreport.c
index 3ad4b9b62e..ad3cc9c02f 100644
--- a/builtin/bugreport.c
+++ b/builtin/bugreport.c
@@ -125,6 +125,7 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix)
struct strbuf report_path = STRBUF_INIT;
int report = -1;
time_t now = time(NULL);
+ struct tm tm;
char *option_output = NULL;
char *option_suffix = "%Y-%m-%d-%H%M";
const char *user_relative_path = NULL;
@@ -147,7 +148,7 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix)
strbuf_complete(&report_path, '/');
strbuf_addstr(&report_path, "git-bugreport-");
- strbuf_addftime(&report_path, option_suffix, localtime(&now), 0, 0);
+ strbuf_addftime(&report_path, option_suffix, localtime_r(&now, &tm), 0, 0);
strbuf_addstr(&report_path, ".txt");
switch (safe_create_leading_directories(report_path.buf)) {
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 9b82119129..c9ba23c279 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -480,9 +480,11 @@ static int checkout_paths(const struct checkout_opts *opts,
* with the hex of the commit (whether it's in `...` form or
* not) for the run_add_interactive() machinery to work
* properly. However, there is special logic for the HEAD case
- * so we mustn't replace that.
+ * so we mustn't replace that. Also, when we were given a
+ * tree-object, new_branch_info->commit would be NULL, but we
+ * do not have to do any replacement, either.
*/
- if (rev && strcmp(rev, "HEAD"))
+ if (rev && new_branch_info->commit && strcmp(rev, "HEAD"))
rev = oid_to_hex_r(rev_oid, &new_branch_info->commit->object.oid);
if (opts->checkout_index && opts->checkout_worktree)
diff --git a/builtin/clone.c b/builtin/clone.c
index a0841923cf..e335734b4c 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1293,8 +1293,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
break;
}
- if (!is_local && !complete_refs_before_fetch)
- transport_fetch_refs(transport, mapped_refs);
+ if (!is_local && !complete_refs_before_fetch) {
+ err = transport_fetch_refs(transport, mapped_refs);
+ if (err)
+ goto cleanup;
+ }
remote_head = find_ref_by_name(refs, "HEAD");
remote_head_points_at =
@@ -1323,7 +1326,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
remote_head = NULL;
option_no_checkout = 1;
if (!option_bare) {
- const char *branch = git_default_branch_name();
+ const char *branch = git_default_branch_name(0);
char *ref = xstrfmt("refs/heads/%s", branch);
install_branch_config(0, branch, remote_name, ref);
@@ -1339,8 +1342,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
if (is_local)
clone_local(path, git_dir);
- else if (refs && complete_refs_before_fetch)
- transport_fetch_refs(transport, mapped_refs);
+ else if (refs && complete_refs_before_fetch) {
+ err = transport_fetch_refs(transport, mapped_refs);
+ if (err)
+ goto cleanup;
+ }
update_remote_refs(refs, mapped_refs, remote_head_points_at,
branch_top.buf, reflog_msg.buf, transport,
@@ -1367,6 +1373,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
junk_mode = JUNK_LEAVE_REPO;
err = checkout(submodule_progress);
+cleanup:
free(remote_name);
strbuf_release(&reflog_msg);
strbuf_release(&branch_top);
diff --git a/builtin/config.c b/builtin/config.c
index 963d65fd3f..f71fa39b38 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -14,6 +14,7 @@ static const char *const builtin_config_usage[] = {
static char *key;
static regex_t *key_regexp;
+static const char *value_pattern;
static regex_t *regexp;
static int show_keys;
static int omit_values;
@@ -34,6 +35,7 @@ static int respect_includes_opt = -1;
static struct config_options config_options;
static int show_origin;
static int show_scope;
+static int fixed_value;
#define ACTION_GET (1<<0)
#define ACTION_GET_ALL (1<<1)
@@ -133,17 +135,18 @@ static struct option builtin_config_options[] = {
OPT_STRING('f', "file", &given_config_source.file, N_("file"), N_("use given config file")),
OPT_STRING(0, "blob", &given_config_source.blob, N_("blob-id"), N_("read config from given blob object")),
OPT_GROUP(N_("Action")),
- OPT_BIT(0, "get", &actions, N_("get value: name [value-regex]"), ACTION_GET),
- OPT_BIT(0, "get-all", &actions, N_("get all values: key [value-regex]"), ACTION_GET_ALL),
- OPT_BIT(0, "get-regexp", &actions, N_("get values for regexp: name-regex [value-regex]"), ACTION_GET_REGEXP),
+ OPT_BIT(0, "get", &actions, N_("get value: name [value-pattern]"), ACTION_GET),
+ OPT_BIT(0, "get-all", &actions, N_("get all values: key [value-pattern]"), ACTION_GET_ALL),
+ OPT_BIT(0, "get-regexp", &actions, N_("get values for regexp: name-regex [value-pattern]"), ACTION_GET_REGEXP),
OPT_BIT(0, "get-urlmatch", &actions, N_("get value specific for the URL: section[.var] URL"), ACTION_GET_URLMATCH),
- OPT_BIT(0, "replace-all", &actions, N_("replace all matching variables: name value [value_regex]"), ACTION_REPLACE_ALL),
+ OPT_BIT(0, "replace-all", &actions, N_("replace all matching variables: name value [value-pattern]"), ACTION_REPLACE_ALL),
OPT_BIT(0, "add", &actions, N_("add a new variable: name value"), ACTION_ADD),
- OPT_BIT(0, "unset", &actions, N_("remove a variable: name [value-regex]"), ACTION_UNSET),
- OPT_BIT(0, "unset-all", &actions, N_("remove all matches: name [value-regex]"), ACTION_UNSET_ALL),
+ OPT_BIT(0, "unset", &actions, N_("remove a variable: name [value-pattern]"), ACTION_UNSET),
+ OPT_BIT(0, "unset-all", &actions, N_("remove all matches: name [value-pattern]"), ACTION_UNSET_ALL),
OPT_BIT(0, "rename-section", &actions, N_("rename section: old-name new-name"), ACTION_RENAME_SECTION),
OPT_BIT(0, "remove-section", &actions, N_("remove a section: name"), ACTION_REMOVE_SECTION),
OPT_BIT('l', "list", &actions, N_("list all"), ACTION_LIST),
+ OPT_BOOL(0, "fixed-value", &fixed_value, N_("use string equality when comparing values to 'value-pattern'")),
OPT_BIT('e', "edit", &actions, N_("open an editor"), ACTION_EDIT),
OPT_BIT(0, "get-color", &actions, N_("find the color configured: slot [default]"), ACTION_GET_COLOR),
OPT_BIT(0, "get-colorbool", &actions, N_("find the color setting: slot [stdout-is-tty]"), ACTION_GET_COLORBOOL),
@@ -296,6 +299,8 @@ static int collect_config(const char *key_, const char *value_, void *cb)
return 0;
if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0))
return 0;
+ if (fixed_value && strcmp(value_pattern, (value_?value_:"")))
+ return 0;
if (regexp != NULL &&
(do_not_match ^ !!regexec(regexp, (value_?value_:""), 0, NULL, 0)))
return 0;
@@ -306,7 +311,7 @@ static int collect_config(const char *key_, const char *value_, void *cb)
return format_config(&values->items[values->nr++], key_, value_);
}
-static int get_value(const char *key_, const char *regex_)
+static int get_value(const char *key_, const char *regex_, unsigned flags)
{
int ret = CONFIG_GENERIC_ERROR;
struct strbuf_list values = {NULL};
@@ -343,7 +348,9 @@ static int get_value(const char *key_, const char *regex_)
}
}
- if (regex_) {
+ if (regex_ && (flags & CONFIG_FLAGS_FIXED_VALUE))
+ value_pattern = regex_;
+ else if (regex_) {
if (regex_[0] == '!') {
do_not_match = 1;
regex_++;
@@ -631,6 +638,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
{
int nongit = !startup_info->have_repository;
char *value;
+ int flags = 0;
given_config_source.file = xstrdup_or_null(getenv(CONFIG_ENVIRONMENT));
@@ -766,6 +774,42 @@ int cmd_config(int argc, const char **argv, const char *prefix)
usage_builtin_config();
}
+ /* check usage of --fixed-value */
+ if (fixed_value) {
+ int allowed_usage = 0;
+
+ switch (actions) {
+ /* git config --get <name> <value-pattern> */
+ case ACTION_GET:
+ /* git config --get-all <name> <value-pattern> */
+ case ACTION_GET_ALL:
+ /* git config --get-regexp <name-pattern> <value-pattern> */
+ case ACTION_GET_REGEXP:
+ /* git config --unset <name> <value-pattern> */
+ case ACTION_UNSET:
+ /* git config --unset-all <name> <value-pattern> */
+ case ACTION_UNSET_ALL:
+ allowed_usage = argc > 1 && !!argv[1];
+ break;
+
+ /* git config <name> <value> <value-pattern> */
+ case ACTION_SET_ALL:
+ /* git config --replace-all <name> <value> <value-pattern> */
+ case ACTION_REPLACE_ALL:
+ allowed_usage = argc > 2 && !!argv[2];
+ break;
+
+ /* other options don't allow --fixed-value */
+ }
+
+ if (!allowed_usage) {
+ error(_("--fixed-value only applies with 'value-pattern'"));
+ usage_builtin_config();
+ }
+
+ flags |= CONFIG_FLAGS_FIXED_VALUE;
+ }
+
if (actions & PAGING_ACTIONS)
setup_auto_pager("config", 1);
@@ -827,7 +871,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
value = normalize_value(argv[0], argv[1]);
UNLEAK(value);
return git_config_set_multivar_in_file_gently(given_config_source.file,
- argv[0], value, argv[2], 0);
+ argv[0], value, argv[2],
+ flags);
}
else if (actions == ACTION_ADD) {
check_write();
@@ -836,7 +881,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
UNLEAK(value);
return git_config_set_multivar_in_file_gently(given_config_source.file,
argv[0], value,
- CONFIG_REGEX_NONE, 0);
+ CONFIG_REGEX_NONE,
+ flags);
}
else if (actions == ACTION_REPLACE_ALL) {
check_write();
@@ -844,23 +890,24 @@ int cmd_config(int argc, const char **argv, const char *prefix)
value = normalize_value(argv[0], argv[1]);
UNLEAK(value);
return git_config_set_multivar_in_file_gently(given_config_source.file,
- argv[0], value, argv[2], 1);
+ argv[0], value, argv[2],
+ flags | CONFIG_FLAGS_MULTI_REPLACE);
}
else if (actions == ACTION_GET) {
check_argc(argc, 1, 2);
- return get_value(argv[0], argv[1]);
+ return get_value(argv[0], argv[1], flags);
}
else if (actions == ACTION_GET_ALL) {
do_all = 1;
check_argc(argc, 1, 2);
- return get_value(argv[0], argv[1]);
+ return get_value(argv[0], argv[1], flags);
}
else if (actions == ACTION_GET_REGEXP) {
show_keys = 1;
use_key_regexp = 1;
do_all = 1;
check_argc(argc, 1, 2);
- return get_value(argv[0], argv[1]);
+ return get_value(argv[0], argv[1], flags);
}
else if (actions == ACTION_GET_URLMATCH) {
check_argc(argc, 2, 2);
@@ -871,7 +918,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
check_argc(argc, 1, 2);
if (argc == 2)
return git_config_set_multivar_in_file_gently(given_config_source.file,
- argv[0], NULL, argv[1], 0);
+ argv[0], NULL, argv[1],
+ flags);
else
return git_config_set_in_file_gently(given_config_source.file,
argv[0], NULL);
@@ -880,7 +928,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
check_write();
check_argc(argc, 1, 2);
return git_config_set_multivar_in_file_gently(given_config_source.file,
- argv[0], NULL, argv[1], 1);
+ argv[0], NULL, argv[1],
+ flags | CONFIG_FLAGS_MULTI_REPLACE);
}
else if (actions == ACTION_RENAME_SECTION) {
int ret;
diff --git a/builtin/credential-store.c b/builtin/credential-store.c
index 5331ab151a..ae3c1ba75f 100644
--- a/builtin/credential-store.c
+++ b/builtin/credential-store.c
@@ -1,4 +1,5 @@
#include "builtin.h"
+#include "config.h"
#include "lockfile.h"
#include "credential.h"
#include "string-list.h"
@@ -58,8 +59,11 @@ static void print_line(struct strbuf *buf)
static void rewrite_credential_file(const char *fn, struct credential *c,
struct strbuf *extra)
{
- if (hold_lock_file_for_update(&credential_lock, fn, 0) < 0)
- die_errno("unable to get credential storage lock");
+ int timeout_ms = 1000;
+
+ git_config_get_int("credentialstore.locktimeoutms", &timeout_ms);
+ if (hold_lock_file_for_update_timeout(&credential_lock, fn, 0, timeout_ms) < 0)
+ die_errno(_("unable to get credential storage lock in %d ms"), timeout_ms);
if (extra)
print_line(extra);
parse_credential_file(fn, c, NULL, print_line);
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index d2e33f5005..0a60356b06 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -923,7 +923,6 @@ static struct commit *get_commit(struct rev_cmdline_entry *e, char *full_name)
if (!tag)
die("Tag %s points nowhere?", e->name);
return (struct commit *)tag;
- break;
}
default:
return NULL;
diff --git a/builtin/gc.c b/builtin/gc.c
index bc25ad52c7..4c24f41852 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -534,7 +534,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
const char *name;
pid_t pid;
int daemonized = 0;
- int keep_base_pack = -1;
+ int keep_largest_pack = -1;
timestamp_t dummy;
struct option builtin_gc_options[] = {
@@ -548,7 +548,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
OPT_BOOL_F(0, "force", &force,
N_("force running gc even if there may be another gc running"),
PARSE_OPT_NOCOMPLETE),
- OPT_BOOL(0, "keep-largest-pack", &keep_base_pack,
+ OPT_BOOL(0, "keep-largest-pack", &keep_largest_pack,
N_("repack all other packs except the largest pack")),
OPT_END()
};
@@ -625,8 +625,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
} else {
struct string_list keep_pack = STRING_LIST_INIT_NODUP;
- if (keep_base_pack != -1) {
- if (keep_base_pack)
+ if (keep_largest_pack != -1) {
+ if (keep_largest_pack)
find_base_packs(&keep_pack, 0);
} else if (big_pack_threshold) {
find_base_packs(&keep_pack, big_pack_threshold);
@@ -1446,10 +1446,6 @@ static int maintenance_register(void)
struct child_process config_set = CHILD_PROCESS_INIT;
struct child_process config_get = CHILD_PROCESS_INIT;
- /* There is no current repository, so skip registering it */
- if (!the_repository || !the_repository->gitdir)
- return 0;
-
/* Disable foreground maintenance */
git_config_set("maintenance.auto", "false");
@@ -1460,7 +1456,8 @@ static int maintenance_register(void)
git_config_set("maintenance.strategy", "incremental");
config_get.git_cmd = 1;
- strvec_pushl(&config_get.args, "config", "--global", "--get", "maintenance.repo",
+ strvec_pushl(&config_get.args, "config", "--global", "--get",
+ "--fixed-value", "maintenance.repo",
the_repository->worktree ? the_repository->worktree
: the_repository->gitdir,
NULL);
@@ -1486,12 +1483,9 @@ static int maintenance_unregister(void)
{
struct child_process config_unset = CHILD_PROCESS_INIT;
- if (!the_repository || !the_repository->gitdir)
- return error(_("no current repository to unregister"));
-
config_unset.git_cmd = 1;
strvec_pushl(&config_unset.args, "config", "--global", "--unset",
- "maintenance.repo",
+ "--fixed-value", "maintenance.repo",
the_repository->worktree ? the_repository->worktree
: the_repository->gitdir,
NULL);
@@ -1560,11 +1554,10 @@ static int update_background_schedule(int run_maintenance)
while (!strbuf_getline_lf(&line, cron_list)) {
if (!in_old_region && !strcmp(line.buf, BEGIN_LINE))
in_old_region = 1;
- if (in_old_region)
- continue;
- fprintf(cron_in, "%s\n", line.buf);
- if (in_old_region && !strcmp(line.buf, END_LINE))
+ else if (in_old_region && !strcmp(line.buf, END_LINE))
in_old_region = 0;
+ else if (!in_old_region)
+ fprintf(cron_in, "%s\n", line.buf);
}
if (run_maintenance) {
diff --git a/builtin/grep.c b/builtin/grep.c
index e58e57504c..ca259af441 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -950,7 +950,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
OPT_END()
};
- init_grep_defaults(the_repository);
git_config(grep_cmd_config, NULL);
grep_init(&opt, the_repository, prefix);
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 4b8d86e0ad..557bd2f348 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -1641,7 +1641,7 @@ static void read_idx_option(struct pack_idx_option *opts, const char *pack_name)
/*
* Get rid of the idx file as we do not need it anymore.
* NEEDSWORK: extract this bit from free_pack_by_name() in
- * sha1-file.c, perhaps? It shouldn't matter very much as we
+ * object-file.c, perhaps? It shouldn't matter very much as we
* know we haven't installed this pack (hence we never have
* read anything from it).
*/
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 01bc648d41..dcc45bef51 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -202,7 +202,8 @@ void initialize_repository_version(int hash_algo, int reinit)
static int create_default_files(const char *template_path,
const char *original_git_dir,
const char *initial_branch,
- const struct repository_format *fmt)
+ const struct repository_format *fmt,
+ int quiet)
{
struct stat st1;
struct strbuf buf = STRBUF_INIT;
@@ -267,7 +268,7 @@ static int create_default_files(const char *template_path,
char *ref;
if (!initial_branch)
- initial_branch = git_default_branch_name();
+ initial_branch = git_default_branch_name(quiet);
ref = xstrfmt("refs/heads/%s", initial_branch);
if (check_refname_format(ref, 0) < 0)
@@ -438,7 +439,8 @@ int init_db(const char *git_dir, const char *real_git_dir,
validate_hash_algorithm(&repo_fmt, hash);
reinit = create_default_files(template_dir, original_git_dir,
- initial_branch, &repo_fmt);
+ initial_branch, &repo_fmt,
+ flags & INIT_DB_QUIET);
if (reinit && initial_branch)
warning(_("re-init: ignored --initial-branch=%s"),
initial_branch);
diff --git a/builtin/log.c b/builtin/log.c
index 08204e3196..bd6ff4f9f9 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -133,7 +133,6 @@ static int log_line_range_callback(const struct option *option, const char *arg,
static void init_log_defaults(void)
{
- init_grep_defaults(the_repository);
init_diff_ui_defaults();
decoration_style = auto_decoration_style();
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 725dd04519..3fe71a8c01 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -7,7 +7,7 @@
#include "refs.h"
#include "parse-options.h"
#include "prio-queue.h"
-#include "sha1-lookup.h"
+#include "hash-lookup.h"
#include "commit-slab.h"
/*
@@ -408,7 +408,7 @@ static const char *get_exact_ref_match(const struct object *o)
tip_table.sorted = 1;
}
- found = sha1_pos(o->oid.hash, tip_table.table, tip_table.nr,
+ found = hash_pos(o->oid.hash, tip_table.table, tip_table.nr,
nth_tip_table_ent);
if (0 <= found)
return tip_table.table[found].refname;
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 5617c01b5a..2a00358f34 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -1104,7 +1104,6 @@ static void write_pack_file(void)
stop_progress(&progress_state);
bitmap_writer_show_progress(progress);
- bitmap_writer_reuse_bitmaps(&to_pack);
bitmap_writer_select_commits(indexed_commits, indexed_commits_nr, -1);
bitmap_writer_build(&to_pack);
bitmap_writer_finish(written_list, nr_written,
diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c
index 3e70f2a4c1..9fcea3e253 100644
--- a/builtin/pack-redundant.c
+++ b/builtin/pack-redundant.c
@@ -473,6 +473,12 @@ static void cmp_local_packs(void)
{
struct pack_list *subset, *pl = local_packs;
+ /* only one packfile */
+ if (!pl->next) {
+ llist_init(&pl->unique_objects);
+ return;
+ }
+
while ((subset = pl)) {
while ((subset = subset->next))
cmp_two_packs(pl, subset);
diff --git a/builtin/pull.c b/builtin/pull.c
index 17aa63cd35..e8927fc2ff 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -324,7 +324,7 @@ static const char *config_get_ff(void)
* looks for the value of "pull.rebase". If both configuration keys do not
* exist, returns REBASE_FALSE.
*/
-static enum rebase_type config_get_rebase(void)
+static enum rebase_type config_get_rebase(int *rebase_unspecified)
{
struct branch *curr_branch = branch_get("HEAD");
const char *value;
@@ -344,20 +344,7 @@ static enum rebase_type config_get_rebase(void)
if (!git_config_get_value("pull.rebase", &value))
return parse_config_rebase("pull.rebase", value, 1);
- if (opt_verbosity >= 0 && !opt_ff) {
- warning(_("Pulling without specifying how to reconcile divergent branches is\n"
- "discouraged. You can squelch this message by running one of the following\n"
- "commands sometime before your next pull:\n"
- "\n"
- " git config pull.rebase false # merge (the default strategy)\n"
- " git config pull.rebase true # rebase\n"
- " git config pull.ff only # fast-forward only\n"
- "\n"
- "You can replace \"git config\" with \"git config --global\" to set a default\n"
- "preference for all repositories. You can also pass --rebase, --no-rebase,\n"
- "or --ff-only on the command line to override the configured default per\n"
- "invocation.\n"));
- }
+ *rebase_unspecified = 1;
return REBASE_FALSE;
}
@@ -852,21 +839,42 @@ static int get_octopus_merge_base(struct object_id *merge_base,
/**
* Given the current HEAD oid, the merge head returned from git-fetch and the
- * fork point calculated by get_rebase_fork_point(), runs git-rebase with the
- * appropriate arguments and returns its exit status.
+ * fork point calculated by get_rebase_fork_point(), compute the <newbase> and
+ * <upstream> arguments to use for the upcoming git-rebase invocation.
*/
-static int run_rebase(const struct object_id *curr_head,
+static int get_rebase_newbase_and_upstream(struct object_id *newbase,
+ struct object_id *upstream,
+ const struct object_id *curr_head,
const struct object_id *merge_head,
const struct object_id *fork_point)
{
- int ret;
struct object_id oct_merge_base;
- struct strvec args = STRVEC_INIT;
if (!get_octopus_merge_base(&oct_merge_base, curr_head, merge_head, fork_point))
if (!is_null_oid(fork_point) && oideq(&oct_merge_base, fork_point))
fork_point = NULL;
+ if (fork_point && !is_null_oid(fork_point))
+ oidcpy(upstream, fork_point);
+ else
+ oidcpy(upstream, merge_head);
+
+ oidcpy(newbase, merge_head);
+
+ return 0;
+}
+
+/**
+ * Given the <newbase> and <upstream> calculated by
+ * get_rebase_newbase_and_upstream(), runs git-rebase with the
+ * appropriate arguments and returns its exit status.
+ */
+static int run_rebase(const struct object_id *newbase,
+ const struct object_id *upstream)
+{
+ int ret;
+ struct strvec args = STRVEC_INIT;
+
strvec_push(&args, "rebase");
/* Shared options */
@@ -894,18 +902,45 @@ static int run_rebase(const struct object_id *curr_head,
warning(_("ignoring --verify-signatures for rebase"));
strvec_push(&args, "--onto");
- strvec_push(&args, oid_to_hex(merge_head));
+ strvec_push(&args, oid_to_hex(newbase));
- if (fork_point && !is_null_oid(fork_point))
- strvec_push(&args, oid_to_hex(fork_point));
- else
- strvec_push(&args, oid_to_hex(merge_head));
+ strvec_push(&args, oid_to_hex(upstream));
ret = run_command_v_opt(args.v, RUN_GIT_CMD);
strvec_clear(&args);
return ret;
}
+static int get_can_ff(struct object_id *orig_head, struct object_id *orig_merge_head)
+{
+ int ret;
+ struct commit_list *list = NULL;
+ struct commit *merge_head, *head;
+
+ head = lookup_commit_reference(the_repository, orig_head);
+ commit_list_insert(head, &list);
+ merge_head = lookup_commit_reference(the_repository, orig_merge_head);
+ ret = repo_is_descendant_of(the_repository, merge_head, list);
+ free_commit_list(list);
+ return ret;
+}
+
+static void show_advice_pull_non_ff(void)
+{
+ advise(_("Pulling without specifying how to reconcile divergent branches is\n"
+ "discouraged. You can squelch this message by running one of the following\n"
+ "commands sometime before your next pull:\n"
+ "\n"
+ " git config pull.rebase false # merge (the default strategy)\n"
+ " git config pull.rebase true # rebase\n"
+ " git config pull.ff only # fast-forward only\n"
+ "\n"
+ "You can replace \"git config\" with \"git config --global\" to set a default\n"
+ "preference for all repositories. You can also pass --rebase, --no-rebase,\n"
+ "or --ff-only on the command line to override the configured default per\n"
+ "invocation.\n"));
+}
+
int cmd_pull(int argc, const char **argv, const char *prefix)
{
const char *repo, **refspecs;
@@ -913,6 +948,8 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
struct object_id orig_head, curr_head;
struct object_id rebase_fork_point;
int autostash;
+ int rebase_unspecified = 0;
+ int can_ff;
if (!getenv("GIT_REFLOG_ACTION"))
set_reflog_message(argc, argv);
@@ -934,7 +971,7 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
opt_ff = xstrdup_or_null(config_get_ff());
if (opt_rebase < 0)
- opt_rebase = config_get_rebase();
+ opt_rebase = config_get_rebase(&rebase_unspecified);
if (read_cache_unmerged())
die_resolve_conflict("pull");
@@ -1008,33 +1045,36 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
if (opt_rebase && merge_heads.nr > 1)
die(_("Cannot rebase onto multiple branches."));
+ can_ff = get_can_ff(&orig_head, &merge_heads.oid[0]);
+
+ if (rebase_unspecified && !opt_ff && !can_ff) {
+ if (opt_verbosity >= 0)
+ show_advice_pull_non_ff();
+ }
+
if (opt_rebase) {
int ret = 0;
int ran_ff = 0;
+
+ struct object_id newbase;
+ struct object_id upstream;
+ get_rebase_newbase_and_upstream(&newbase, &upstream, &curr_head,
+ merge_heads.oid, &rebase_fork_point);
+
if ((recurse_submodules == RECURSE_SUBMODULES_ON ||
recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND) &&
- submodule_touches_in_range(the_repository, &rebase_fork_point, &curr_head))
+ submodule_touches_in_range(the_repository, &upstream, &curr_head))
die(_("cannot rebase with locally recorded submodule modifications"));
if (!autostash) {
- struct commit_list *list = NULL;
- struct commit *merge_head, *head;
-
- head = lookup_commit_reference(the_repository,
- &orig_head);
- commit_list_insert(head, &list);
- merge_head = lookup_commit_reference(the_repository,
- &merge_heads.oid[0]);
- if (repo_is_descendant_of(the_repository,
- merge_head, list)) {
+ if (can_ff) {
/* we can fast-forward this without invoking rebase */
opt_ff = "--ff-only";
ran_ff = 1;
ret = run_merge();
}
- free_commit_list(list);
}
if (!ran_ff)
- ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point);
+ ret = run_rebase(&newbase, &upstream);
if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON ||
recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND))
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 19c7b377aa..840dbd7eb7 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -1917,7 +1917,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
die_if_checked_out(buf.buf, 1);
options.head_name = xstrdup(buf.buf);
/* If not is it a valid ref (branch or commit)? */
- } else if (!get_oid(branch_name, &options.orig_head))
+ } else if (!get_oid(branch_name, &options.orig_head) &&
+ lookup_commit_reference(the_repository,
+ &options.orig_head))
options.head_name = NULL;
else
die(_("fatal: no such branch/commit '%s'"),
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index f1f0f7bef6..d49d050e6e 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -54,6 +54,7 @@ static int receive_unpack_limit = -1;
static int transfer_unpack_limit = -1;
static int advertise_atomic_push = 1;
static int advertise_push_options;
+static int advertise_sid;
static int unpack_limit = 100;
static off_t max_input_size;
static int report_status;
@@ -248,6 +249,11 @@ static int receive_pack_config(const char *var, const char *value, void *cb)
return 0;
}
+ if (strcmp(var, "transfer.advertisesid") == 0) {
+ advertise_sid = git_config_bool(var, value);
+ return 0;
+ }
+
return git_default_config(var, value, cb);
}
@@ -268,6 +274,8 @@ static void show_ref(const char *path, const struct object_id *oid)
strbuf_addf(&cap, " push-cert=%s", push_cert_nonce);
if (advertise_push_options)
strbuf_addstr(&cap, " push-options");
+ if (advertise_sid)
+ strbuf_addf(&cap, " session-id=%s", trace2_session_id());
strbuf_addf(&cap, " object-format=%s", the_hash_algo->name);
strbuf_addf(&cap, " agent=%s", git_user_agent_sanitized());
packet_write_fmt(1, "%s %s%c%s\n",
@@ -2075,6 +2083,7 @@ static struct command *read_head_info(struct packet_reader *reader,
if (linelen < reader->pktlen) {
const char *feature_list = reader->line + linelen + 1;
const char *hash = NULL;
+ const char *client_sid;
int len = 0;
if (parse_feature_request(feature_list, "report-status"))
report_status = 1;
@@ -2097,6 +2106,12 @@ static struct command *read_head_info(struct packet_reader *reader,
}
if (xstrncmpz(the_hash_algo->name, hash, len))
die("error: unsupported object format '%s'", hash);
+ client_sid = parse_feature_value(feature_list, "session-id", &len, NULL);
+ if (client_sid) {
+ char *sid = xstrndup(client_sid, len);
+ trace2_data_string("transfer", NULL, "client-sid", client_sid);
+ free(sid);
+ }
}
if (!strcmp(reader->line, "push-cert")) {
diff --git a/builtin/remote.c b/builtin/remote.c
index c1b211b272..d11a5589e4 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -712,7 +712,7 @@ static int mv(int argc, const char **argv)
strbuf_reset(&buf);
strbuf_addf(&buf, "remote.%s.fetch", rename.new_name);
- git_config_set_multivar(buf.buf, NULL, NULL, 1);
+ 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++) {
char *ptr;
@@ -1491,7 +1491,8 @@ static int update(int argc, const char **argv)
static int remove_all_fetch_refspecs(const char *key)
{
- return git_config_set_multivar_gently(key, NULL, NULL, 1);
+ return git_config_set_multivar_gently(key, NULL, NULL,
+ CONFIG_FLAGS_MULTI_REPLACE);
}
static void add_branches(struct remote *remote, const char **branches,
@@ -1686,7 +1687,8 @@ static int set_url(int argc, const char **argv)
if (!delete_mode)
git_config_set_multivar(name_buf.buf, newurl, oldurl, 0);
else
- git_config_set_multivar(name_buf.buf, NULL, oldurl, 1);
+ git_config_set_multivar(name_buf.buf, NULL, oldurl,
+ CONFIG_FLAGS_MULTI_REPLACE);
out:
strbuf_release(&name_buf);
return 0;
diff --git a/builtin/repack.c b/builtin/repack.c
index 01e7767c79..279be11a16 100644
--- a/builtin/repack.c
+++ b/builtin/repack.c
@@ -202,6 +202,37 @@ static int write_oid(const struct object_id *oid, struct packed_git *pack,
return 0;
}
+static struct {
+ const char *name;
+ unsigned optional:1;
+} exts[] = {
+ {".pack"},
+ {".idx"},
+ {".bitmap", 1},
+ {".promisor", 1},
+};
+
+static unsigned populate_pack_exts(char *name)
+{
+ struct stat statbuf;
+ struct strbuf path = STRBUF_INIT;
+ unsigned ret = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(exts); i++) {
+ strbuf_reset(&path);
+ strbuf_addf(&path, "%s-%s%s", packtmp, name, exts[i].name);
+
+ if (stat(path.buf, &statbuf))
+ continue;
+
+ ret |= (1 << i);
+ }
+
+ strbuf_release(&path);
+ return ret;
+}
+
static void repack_promisor_objects(const struct pack_objects_args *args,
struct string_list *names)
{
@@ -230,11 +261,12 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
out = xfdopen(cmd.out, "r");
while (strbuf_getline_lf(&line, out) != EOF) {
+ struct string_list_item *item;
char *promisor_name;
int fd;
if (line.len != the_hash_algo->hexsz)
die(_("repack: Expecting full hex object ID lines only from pack-objects."));
- string_list_append(names, line.buf);
+ item = string_list_append(names, line.buf);
/*
* pack-objects creates the .pack and .idx files, but not the
@@ -253,6 +285,9 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
if (fd < 0)
die_errno(_("unable to create '%s'"), promisor_name);
close(fd);
+
+ item->util = (void *)(uintptr_t)populate_pack_exts(item->string);
+
free(promisor_name);
}
fclose(out);
@@ -265,22 +300,13 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
int cmd_repack(int argc, const char **argv, const char *prefix)
{
- struct {
- const char *name;
- unsigned optional:1;
- } exts[] = {
- {".pack"},
- {".idx"},
- {".bitmap", 1},
- {".promisor", 1},
- };
struct child_process cmd = CHILD_PROCESS_INIT;
struct string_list_item *item;
struct string_list names = STRING_LIST_INIT_DUP;
struct string_list rollback = STRING_LIST_INIT_NODUP;
struct string_list existing_packs = STRING_LIST_INIT_DUP;
struct strbuf line = STRBUF_INIT;
- int i, ext, ret, failed;
+ int i, ext, ret;
FILE *out;
/* variables to be filled by option parsing */
@@ -429,113 +455,42 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
if (!names.nr && !po_args.quiet)
printf_ln(_("Nothing new to pack."));
+ for_each_string_list_item(item, &names) {
+ item->util = (void *)(uintptr_t)populate_pack_exts(item->string);
+ }
+
close_object_store(the_repository->objects);
/*
* Ok we have prepared all new packfiles.
- * First see if there are packs of the same name and if so
- * if we can move them out of the way (this can happen if we
- * repacked immediately after packing fully.
*/
- failed = 0;
for_each_string_list_item(item, &names) {
for (ext = 0; ext < ARRAY_SIZE(exts); ext++) {
char *fname, *fname_old;
- fname = mkpathdup("%s/pack-%s%s", packdir,
- item->string, exts[ext].name);
- if (!file_exists(fname)) {
- free(fname);
- continue;
- }
-
- fname_old = mkpathdup("%s/old-%s%s", packdir,
- item->string, exts[ext].name);
- if (file_exists(fname_old))
- if (unlink(fname_old))
- failed = 1;
-
- if (!failed && rename(fname, fname_old)) {
- free(fname);
- free(fname_old);
- failed = 1;
- break;
- } else {
- string_list_append(&rollback, fname);
- free(fname_old);
- }
- }
- if (failed)
- break;
- }
- if (failed) {
- struct string_list rollback_failure = STRING_LIST_INIT_DUP;
- for_each_string_list_item(item, &rollback) {
- char *fname, *fname_old;
- fname = mkpathdup("%s/%s", packdir, item->string);
- fname_old = mkpathdup("%s/old-%s", packdir, item->string);
- if (rename(fname_old, fname))
- string_list_append(&rollback_failure, fname);
- free(fname);
- free(fname_old);
- }
-
- if (rollback_failure.nr) {
- int i;
- fprintf(stderr,
- _("WARNING: Some packs in use have been renamed by\n"
- "WARNING: prefixing old- to their name, in order to\n"
- "WARNING: replace them with the new version of the\n"
- "WARNING: file. But the operation failed, and the\n"
- "WARNING: attempt to rename them back to their\n"
- "WARNING: original names also failed.\n"
- "WARNING: Please rename them in %s manually:\n"), packdir);
- for (i = 0; i < rollback_failure.nr; i++)
- fprintf(stderr, "WARNING: old-%s -> %s\n",
- rollback_failure.items[i].string,
- rollback_failure.items[i].string);
- }
- exit(1);
- }
-
- /* Now the ones with the same name are out of the way... */
- for_each_string_list_item(item, &names) {
- for (ext = 0; ext < ARRAY_SIZE(exts); ext++) {
- char *fname, *fname_old;
- struct stat statbuffer;
- int exists = 0;
fname = mkpathdup("%s/pack-%s%s",
packdir, item->string, exts[ext].name);
fname_old = mkpathdup("%s-%s%s",
packtmp, item->string, exts[ext].name);
- if (!stat(fname_old, &statbuffer)) {
- statbuffer.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
- chmod(fname_old, statbuffer.st_mode);
- exists = 1;
- }
- if (exists || !exts[ext].optional) {
+
+ if (((uintptr_t)item->util) & (1 << ext)) {
+ struct stat statbuffer;
+ if (!stat(fname_old, &statbuffer)) {
+ statbuffer.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
+ chmod(fname_old, statbuffer.st_mode);
+ }
+
if (rename(fname_old, fname))
die_errno(_("renaming '%s' failed"), fname_old);
- }
- free(fname);
- free(fname_old);
- }
- }
+ } else if (!exts[ext].optional)
+ die(_("missing required file: %s"), fname_old);
+ else if (unlink(fname) < 0 && errno != ENOENT)
+ die_errno(_("could not unlink: %s"), fname);
- /* Remove the "old-" files */
- for_each_string_list_item(item, &names) {
- for (ext = 0; ext < ARRAY_SIZE(exts); ext++) {
- char *fname;
- fname = mkpathdup("%s/old-%s%s",
- packdir,
- item->string,
- exts[ext].name);
- if (remove_path(fname))
- warning(_("failed to remove '%s'"), fname);
free(fname);
+ free(fname_old);
}
}
-
/* End of pack replacement. */
reprepare_packed_git(the_repository);
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 69ba7326cf..85bad9052e 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -583,6 +583,75 @@ static void handle_ref_opt(const char *pattern, const char *prefix)
clear_ref_exclusion(&ref_excludes);
}
+enum format_type {
+ /* We would like a relative path. */
+ FORMAT_RELATIVE,
+ /* We would like a canonical absolute path. */
+ FORMAT_CANONICAL,
+ /* We would like the default behavior. */
+ FORMAT_DEFAULT,
+};
+
+enum default_type {
+ /* Our default is a relative path. */
+ DEFAULT_RELATIVE,
+ /* Our default is a relative path if there's a shared root. */
+ DEFAULT_RELATIVE_IF_SHARED,
+ /* Our default is a canonical absolute path. */
+ DEFAULT_CANONICAL,
+ /* Our default is not to modify the item. */
+ DEFAULT_UNMODIFIED,
+};
+
+static void print_path(const char *path, const char *prefix, enum format_type format, enum default_type def)
+{
+ char *cwd = NULL;
+ /*
+ * We don't ever produce a relative path if prefix is NULL, so set the
+ * prefix to the current directory so that we can produce a relative
+ * path whenever possible. If we're using RELATIVE_IF_SHARED mode, then
+ * we want an absolute path unless the two share a common prefix, so don't
+ * set it in that case, since doing so causes a relative path to always
+ * be produced if possible.
+ */
+ if (!prefix && (format != FORMAT_DEFAULT || def != DEFAULT_RELATIVE_IF_SHARED))
+ prefix = cwd = xgetcwd();
+ if (format == FORMAT_DEFAULT && def == DEFAULT_UNMODIFIED) {
+ puts(path);
+ } else if (format == FORMAT_RELATIVE ||
+ (format == FORMAT_DEFAULT && def == DEFAULT_RELATIVE)) {
+ /*
+ * In order for relative_path to work as expected, we need to
+ * make sure that both paths are absolute paths. If we don't,
+ * we can end up with an unexpected absolute path that the user
+ * didn't want.
+ */
+ struct strbuf buf = STRBUF_INIT, realbuf = STRBUF_INIT, prefixbuf = STRBUF_INIT;
+ if (!is_absolute_path(path)) {
+ strbuf_realpath_forgiving(&realbuf, path, 1);
+ path = realbuf.buf;
+ }
+ if (!is_absolute_path(prefix)) {
+ strbuf_realpath_forgiving(&prefixbuf, prefix, 1);
+ prefix = prefixbuf.buf;
+ }
+ puts(relative_path(path, prefix, &buf));
+ strbuf_release(&buf);
+ strbuf_release(&realbuf);
+ strbuf_release(&prefixbuf);
+ } else if (format == FORMAT_DEFAULT && def == DEFAULT_RELATIVE_IF_SHARED) {
+ struct strbuf buf = STRBUF_INIT;
+ puts(relative_path(path, prefix, &buf));
+ strbuf_release(&buf);
+ } else {
+ struct strbuf buf = STRBUF_INIT;
+ strbuf_realpath_forgiving(&buf, path, 1);
+ puts(buf.buf);
+ strbuf_release(&buf);
+ }
+ free(cwd);
+}
+
int cmd_rev_parse(int argc, const char **argv, const char *prefix)
{
int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0;
@@ -596,6 +665,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
struct strbuf buf = STRBUF_INIT;
const int hexsz = the_hash_algo->hexsz;
int seen_end_of_options = 0;
+ enum format_type format = FORMAT_DEFAULT;
if (argc > 1 && !strcmp("--parseopt", argv[1]))
return cmd_parseopt(argc - 1, argv + 1, prefix);
@@ -668,8 +738,9 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
if (!argv[i + 1])
die("--git-path requires an argument");
strbuf_reset(&buf);
- puts(relative_path(git_path("%s", argv[i + 1]),
- prefix, &buf));
+ print_path(git_path("%s", argv[i + 1]), prefix,
+ format,
+ DEFAULT_RELATIVE_IF_SHARED);
i++;
continue;
}
@@ -687,6 +758,16 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
show(arg);
continue;
}
+ if (opt_with_value(arg, "--path-format", &arg)) {
+ if (!strcmp(arg, "absolute")) {
+ format = FORMAT_CANONICAL;
+ } else if (!strcmp(arg, "relative")) {
+ format = FORMAT_RELATIVE;
+ } else {
+ die("unknown argument to --path-format: %s", arg);
+ }
+ continue;
+ }
if (!strcmp(arg, "--default")) {
def = argv[++i];
if (!def)
@@ -807,7 +888,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
if (!strcmp(arg, "--show-toplevel")) {
const char *work_tree = get_git_work_tree();
if (work_tree)
- puts(work_tree);
+ print_path(work_tree, prefix, format, DEFAULT_UNMODIFIED);
else
die("this operation must be run in a work tree");
continue;
@@ -815,7 +896,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
if (!strcmp(arg, "--show-superproject-working-tree")) {
struct strbuf superproject = STRBUF_INIT;
if (get_superproject_working_tree(&superproject))
- puts(superproject.buf);
+ print_path(superproject.buf, prefix, format, DEFAULT_UNMODIFIED);
strbuf_release(&superproject);
continue;
}
@@ -850,16 +931,18 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
char *cwd;
int len;
+ enum format_type wanted = format;
if (arg[2] == 'g') { /* --git-dir */
if (gitdir) {
- puts(gitdir);
+ print_path(gitdir, prefix, format, DEFAULT_UNMODIFIED);
continue;
}
if (!prefix) {
- puts(".git");
+ print_path(".git", prefix, format, DEFAULT_UNMODIFIED);
continue;
}
} else { /* --absolute-git-dir */
+ wanted = FORMAT_CANONICAL;
if (!gitdir && !prefix)
gitdir = ".git";
if (gitdir) {
@@ -872,14 +955,14 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
}
cwd = xgetcwd();
len = strlen(cwd);
- printf("%s%s.git\n", cwd, len && cwd[len-1] != '/' ? "/" : "");
+ strbuf_reset(&buf);
+ strbuf_addf(&buf, "%s%s.git", cwd, len && cwd[len-1] != '/' ? "/" : "");
free(cwd);
+ print_path(buf.buf, prefix, wanted, DEFAULT_CANONICAL);
continue;
}
if (!strcmp(arg, "--git-common-dir")) {
- strbuf_reset(&buf);
- puts(relative_path(get_git_common_dir(),
- prefix, &buf));
+ print_path(get_git_common_dir(), prefix, format, DEFAULT_RELATIVE_IF_SHARED);
continue;
}
if (!strcmp(arg, "--is-inside-git-dir")) {
@@ -909,8 +992,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
if (the_index.split_index) {
const struct object_id *oid = &the_index.split_index->base_oid;
const char *path = git_path("sharedindex.%s", oid_to_hex(oid));
- strbuf_reset(&buf);
- puts(relative_path(path, prefix, &buf));
+ print_path(path, prefix, format, DEFAULT_RELATIVE);
}
continue;
}
diff --git a/builtin/stash.c b/builtin/stash.c
index 24ddb1bffa..e1f8235fdd 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -419,7 +419,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
ret = apply_cached(&out);
strbuf_release(&out);
if (ret)
- return error(_("conflicts in index."
+ return error(_("conflicts in index. "
"Try without --index."));
discard_cache();
diff --git a/builtin/update-ref.c b/builtin/update-ref.c
index 8a2df4459c..6029a80544 100644
--- a/builtin/update-ref.c
+++ b/builtin/update-ref.c
@@ -436,6 +436,8 @@ static void update_refs_stdin(void)
switch (state) {
case UPDATE_REFS_OPEN:
case UPDATE_REFS_STARTED:
+ if (state == UPDATE_REFS_STARTED && cmd->state == UPDATE_REFS_STARTED)
+ die("cannot restart ongoing transaction");
/* Do not downgrade a transaction to a non-transaction. */
if (cmd->state >= state)
state = cmd->state;
@@ -446,7 +448,18 @@ static void update_refs_stdin(void)
state = cmd->state;
break;
case UPDATE_REFS_CLOSED:
- die("transaction is closed");
+ if (cmd->state != UPDATE_REFS_STARTED)
+ die("transaction is closed");
+
+ /*
+ * Open a new transaction if we're currently closed and
+ * get a "start".
+ */
+ state = cmd->state;
+ transaction = ref_transaction_begin(&err);
+ if (!transaction)
+ die("%s", err.buf);
+
break;
}
diff --git a/builtin/worktree.c b/builtin/worktree.c
index ce56fdaaa9..71287b2da6 100644
--- a/builtin/worktree.c
+++ b/builtin/worktree.c
@@ -304,9 +304,9 @@ static void check_candidate_path(const char *path,
}
if (locked)
- die(_("'%s' is a missing but locked worktree;\nuse '%s -f -f' to override, or 'unlock' and 'prune' or 'remove' to clear"), cmd, path);
+ die(_("'%s' is a missing but locked worktree;\nuse '%s -f -f' to override, or 'unlock' and 'prune' or 'remove' to clear"), path, cmd);
else
- die(_("'%s' is a missing but already registered worktree;\nuse '%s -f' to override, or 'prune' or 'remove' to clear"), cmd, path);
+ die(_("'%s' is a missing but already registered worktree;\nuse '%s -f' to override, or 'prune' or 'remove' to clear"), path, cmd);
}
static int add_worktree(const char *path, const char *refname,
@@ -1052,10 +1052,10 @@ static int repair(int ac, const char **av, const char *prefix)
int rc = 0;
ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
- repair_worktrees(report_repair, &rc);
p = ac > 0 ? av : self;
for (; *p; p++)
repair_worktree_at_path(*p, report_repair, &rc);
+ repair_worktrees(report_repair, &rc);
return rc;
}