author | Junio C Hamano <gitster@pobox.com> | |
Sat, 2 Apr 2011 00:55:55 +0000 (17:55 -0700) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Sat, 2 Apr 2011 00:55:55 +0000 (17:55 -0700) |
* ab/i18n-st: (69 commits)
i18n: git-shortlog basic messages
i18n: git-revert split up "could not revert/apply" message
i18n: git-revert literal "me" messages
i18n: git-revert "Your local changes" message
i18n: git-revert basic messages
i18n: git-notes GIT_NOTES_REWRITE_MODE error message
i18n: git-notes basic commands
i18n: git-gc "Auto packing the repository" message
i18n: git-gc basic messages
i18n: git-describe basic messages
i18n: git-clean clean.requireForce messages
i18n: git-clean basic messages
i18n: git-bundle basic messages
i18n: git-archive basic messages
i18n: git-status "renamed: " message
i18n: git-status "Initial commit" message
i18n: git-status "Changes to be committed" message
i18n: git-status shortstatus messages
i18n: git-status "nothing to commit" messages
i18n: git-status basic messages
...
Conflicts:
builtin/branch.c
builtin/checkout.c
builtin/clone.c
builtin/commit.c
builtin/grep.c
builtin/merge.c
builtin/push.c
builtin/revert.c
t/t3507-cherry-pick-conflict.sh
t/t7607-merge-overwrite.sh
i18n: git-shortlog basic messages
i18n: git-revert split up "could not revert/apply" message
i18n: git-revert literal "me" messages
i18n: git-revert "Your local changes" message
i18n: git-revert basic messages
i18n: git-notes GIT_NOTES_REWRITE_MODE error message
i18n: git-notes basic commands
i18n: git-gc "Auto packing the repository" message
i18n: git-gc basic messages
i18n: git-describe basic messages
i18n: git-clean clean.requireForce messages
i18n: git-clean basic messages
i18n: git-bundle basic messages
i18n: git-archive basic messages
i18n: git-status "renamed: " message
i18n: git-status "Initial commit" message
i18n: git-status "Changes to be committed" message
i18n: git-status shortstatus messages
i18n: git-status "nothing to commit" messages
i18n: git-status basic messages
...
Conflicts:
builtin/branch.c
builtin/checkout.c
builtin/clone.c
builtin/commit.c
builtin/grep.c
builtin/merge.c
builtin/push.c
builtin/revert.c
t/t3507-cherry-pick-conflict.sh
t/t7607-merge-overwrite.sh
27 files changed:
diff --cc builtin/add.c
Simple merge
diff --cc builtin/branch.c
index b9ba011f7b3f37a9448afae909d743249c3d8e1f,244589e73657bf1f2eaa1450c36f59869c0a44d6..9cca1b9afc20caf6333d0269386249f41fa8746f
--- 1/builtin/branch.c
--- 2/builtin/branch.c
+++ b/builtin/branch.c
if ((head_rev != reference_rev) &&
in_merge_bases(rev, &head_rev, 1) != merged) {
if (merged)
- warning("deleting branch '%s' that has been merged to\n"
- " '%s', but not yet been merged to HEAD.",
+ warning(_("deleting branch '%s' that has been merged to\n"
- " '%s', but it is not yet merged to HEAD."),
++ " '%s', but not yet merged to HEAD."),
name, reference_name);
else
- warning("not deleting branch '%s' that is not yet merged to\n"
- " '%s', even though it is merged to HEAD.",
+ warning(_("not deleting branch '%s' that is not yet merged to\n"
+ " '%s', even though it is merged to HEAD."),
name, reference_name);
}
return merged;
diff --cc builtin/checkout.c
index 686d0ffd300e3e23cfd31b12d4267b5930787317,9f8e41e37c271f7c76ac2ec58265414ef8334c39..eece5d6ac0f48ae76dc76c0f2ebda633cc0ded58
--- 1/builtin/checkout.c
--- 2/builtin/checkout.c
+++ b/builtin/checkout.c
strbuf_addf(&msg, "checkout: moving from %s to %s",
old_desc ? old_desc : "(invalid)", new->name);
- if (new->path) {
+ if (!strcmp(new->name, "HEAD") && !new->path && !opts->force_detach) {
+ /* Nothing to do. */
+ } else if (opts->force_detach || !new->path) { /* No longer on any branch. */
+ update_ref(msg.buf, "HEAD", new->commit->object.sha1, NULL,
+ REF_NODEREF, DIE_ON_ERR);
+ if (!opts->quiet) {
+ if (old->path && advice_detached_head)
+ detach_advice(old->path, new->name);
- describe_detached_head("HEAD is now at", new->commit);
++ describe_detached_head(_("HEAD is now at"), new->commit);
+ }
+ } else if (new->path) { /* Switch branches. */
create_symref("HEAD", new->path, msg.buf);
if (!opts->quiet) {
- if (old->path && !strcmp(new->path, old->path))
- fprintf(stderr, "Already on '%s'\n",
- new->name);
- else if (opts->new_branch)
- fprintf(stderr, "Switched to%s branch '%s'\n",
- opts->branch_exists ? " and reset" : " a new",
+ if (old->path && !strcmp(new->path, old->path)) {
+ fprintf(stderr, _("Already on '%s'\n"),
new->name);
- else
- fprintf(stderr, "Switched to branch '%s'\n",
+ } else if (opts->new_branch) {
+ if (opts->branch_exists)
+ fprintf(stderr, _("Switched to and reset branch '%s'\n"), new->name);
+ else
+ fprintf(stderr, _("Switched to a new branch '%s'\n"), new->name);
+ } else {
+ fprintf(stderr, _("Switched to branch '%s'\n"),
new->name);
+ }
}
if (old->path && old->name) {
char log_file[PATH_MAX], ref_file[PATH_MAX];
report_tracking(new);
}
- die("internal error: only -- alone should have been left");
+struct rev_list_args {
+ int argc;
+ int alloc;
+ const char **argv;
+};
+
+static void add_one_rev_list_arg(struct rev_list_args *args, const char *s)
+{
+ ALLOC_GROW(args->argv, args->argc + 1, args->alloc);
+ args->argv[args->argc++] = s;
+}
+
+static int add_one_ref_to_rev_list_arg(const char *refname,
+ const unsigned char *sha1,
+ int flags,
+ void *cb_data)
+{
+ add_one_rev_list_arg(cb_data, refname);
+ return 0;
+}
+
+static int clear_commit_marks_from_one_ref(const char *refname,
+ const unsigned char *sha1,
+ int flags,
+ void *cb_data)
+{
+ struct commit *commit = lookup_commit_reference_gently(sha1, 1);
+ if (commit)
+ clear_commit_marks(commit, -1);
+ return 0;
+}
+
+static void describe_one_orphan(struct strbuf *sb, struct commit *commit)
+{
+ struct pretty_print_context ctx = { 0 };
+
+ parse_commit(commit);
+ strbuf_addstr(sb, " ");
+ strbuf_addstr(sb,
+ find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV));
+ strbuf_addch(sb, ' ');
+ pretty_print_commit(CMIT_FMT_ONELINE, commit, sb, &ctx);
+ strbuf_addch(sb, '\n');
+}
+
+#define ORPHAN_CUTOFF 4
+static void suggest_reattach(struct commit *commit, struct rev_info *revs)
+{
+ struct commit *c, *last = NULL;
+ struct strbuf sb = STRBUF_INIT;
+ int lost = 0;
+ while ((c = get_revision(revs)) != NULL) {
+ if (lost < ORPHAN_CUTOFF)
+ describe_one_orphan(&sb, c);
+ last = c;
+ lost++;
+ }
+ if (ORPHAN_CUTOFF < lost) {
+ int more = lost - ORPHAN_CUTOFF;
+ if (more == 1)
+ describe_one_orphan(&sb, last);
+ else
+ strbuf_addf(&sb, " ... and %d more.\n", more);
+ }
+
+ fprintf(stderr,
+ "Warning: you are leaving %d commit%s behind, "
+ "not connected to\n"
+ "any of your branches:\n\n"
+ "%s\n"
+ "If you want to keep them by creating a new branch, "
+ "this may be a good time\nto do so with:\n\n"
+ " git branch new_branch_name %s\n\n",
+ lost, ((1 < lost) ? "s" : ""),
+ sb.buf,
+ sha1_to_hex(commit->object.sha1));
+ strbuf_release(&sb);
+}
+
+/*
+ * We are about to leave commit that was at the tip of a detached
+ * HEAD. If it is not reachable from any ref, this is the last chance
+ * for the user to do so without resorting to reflog.
+ */
+static void orphaned_commit_warning(struct commit *commit)
+{
+ struct rev_list_args args = { 0, 0, NULL };
+ struct rev_info revs;
+
+ add_one_rev_list_arg(&args, "(internal)");
+ add_one_rev_list_arg(&args, sha1_to_hex(commit->object.sha1));
+ add_one_rev_list_arg(&args, "--not");
+ for_each_ref(add_one_ref_to_rev_list_arg, &args);
+ add_one_rev_list_arg(&args, "--");
+ add_one_rev_list_arg(&args, NULL);
+
+ init_revisions(&revs, NULL);
+ if (setup_revisions(args.argc - 1, args.argv, &revs, NULL) != 1)
- die("internal error in revision walk");
++ die(_("internal error: only -- alone should have been left"));
+ if (prepare_revision_walk(&revs))
- describe_detached_head("Previous HEAD position was", commit);
++ die(_("internal error in revision walk"));
+ if (!(commit->object.flags & UNINTERESTING))
+ suggest_reattach(commit, &revs);
+ else
++ describe_detached_head(_("Previous HEAD position was"), commit);
+
+ clear_commit_marks(commit, -1);
+ for_each_ref(clear_commit_marks_from_one_ref, NULL);
+}
+
static int switch_branches(struct checkout_opts *opts, struct branch_info *new)
{
int ret = 0;
return NULL;
}
- die("invalid reference: %s", arg);
+static int parse_branchname_arg(int argc, const char **argv,
+ int dwim_new_local_branch_ok,
+ struct branch_info *new,
+ struct tree **source_tree,
+ unsigned char rev[20],
+ const char **new_branch)
+{
+ int argcount = 0;
+ unsigned char branch_rev[20];
+ const char *arg;
+ int has_dash_dash;
+
+ /*
+ * case 1: git checkout <ref> -- [<paths>]
+ *
+ * <ref> must be a valid tree, everything after the '--' must be
+ * a path.
+ *
+ * case 2: git checkout -- [<paths>]
+ *
+ * everything after the '--' must be paths.
+ *
+ * case 3: git checkout <something> [<paths>]
+ *
+ * With no paths, if <something> is a commit, that is to
+ * switch to the branch or detach HEAD at it. As a special case,
+ * if <something> is A...B (missing A or B means HEAD but you can
+ * omit at most one side), and if there is a unique merge base
+ * between A and B, A...B names that merge base.
+ *
+ * With no paths, if <something> is _not_ a commit, no -t nor -b
+ * was given, and there is a tracking branch whose name is
+ * <something> in one and only one remote, then this is a short-hand
+ * to fork local <something> from that remote-tracking branch.
+ *
+ * Otherwise <something> shall not be ambiguous.
+ * - If it's *only* a reference, treat it like case (1).
+ * - If it's only a path, treat it like case (2).
+ * - else: fail.
+ *
+ */
+ if (!argc)
+ return 0;
+
+ if (!strcmp(argv[0], "--")) /* case (2) */
+ return 1;
+
+ arg = argv[0];
+ has_dash_dash = (argc > 1) && !strcmp(argv[1], "--");
+
+ if (!strcmp(arg, "-"))
+ arg = "@{-1}";
+
+ if (get_sha1_mb(arg, rev)) {
+ if (has_dash_dash) /* case (1) */
- die("reference is not a tree: %s", arg);
++ die(_("invalid reference: %s"), arg);
+ if (dwim_new_local_branch_ok &&
+ !check_filename(NULL, arg) &&
+ argc == 1) {
+ const char *remote = unique_tracking_name(arg);
+ if (!remote || get_sha1(remote, rev))
+ return argcount;
+ *new_branch = arg;
+ arg = remote;
+ /* DWIMmed to create local branch */
+ } else {
+ return argcount;
+ }
+ }
+
+ /* we can't end up being in (2) anymore, eat the argument */
+ argcount++;
+ argv++;
+ argc--;
+
+ new->name = arg;
+ setup_branch_path(new);
+
+ if (check_ref_format(new->path) == CHECK_REF_FORMAT_OK &&
+ resolve_ref(new->path, branch_rev, 1, NULL))
+ hashcpy(rev, branch_rev);
+ else
+ new->path = NULL; /* not an existing branch */
+
+ new->commit = lookup_commit_reference_gently(rev, 1);
+ if (!new->commit) {
+ /* not a commit */
+ *source_tree = parse_tree_indirect(rev);
+ } else {
+ parse_commit(new->commit);
+ *source_tree = new->commit->tree;
+ }
+
+ if (!*source_tree) /* case (1): want a tree */
++ die(_("reference is not a tree: %s"), arg);
+ if (!has_dash_dash) {/* case (3 -> 1) */
+ /*
+ * Do not complain the most common case
+ * git checkout branch
+ * even if there happen to be a file called 'branch';
+ * it would be extremely annoying.
+ */
+ if (argc)
+ verify_non_filename(NULL, arg);
+ } else {
+ argcount++;
+ argv++;
+ argc--;
+ }
+
+ return argcount;
+}
+
int cmd_checkout(int argc, const char **argv, const char *prefix)
{
struct checkout_opts opts;
opts.new_branch = opts.new_branch_force;
if (patch_mode && (opts.track > 0 || opts.new_branch
- || opts.new_branch_log || opts.merge || opts.force))
+ || opts.new_branch_log || opts.merge || opts.force
+ || opts.force_detach))
- die ("--patch is incompatible with all other options");
+ die (_("--patch is incompatible with all other options"));
+ if (opts.force_detach && (opts.new_branch || opts.new_orphan_branch))
+ die("--detach cannot be used with -b/-B/--orphan");
+ if (opts.force_detach && 0 < opts.track)
+ die("--detach cannot be used with -t");
+
/* --track without -b should DWIM */
if (0 < opts.track && !opts.new_branch) {
const char *argv0 = argv[0];
}
if (opts.force && opts.merge)
- die("git checkout: -f and -m are incompatible");
+ die(_("git checkout: -f and -m are incompatible"));
/*
- * case 1: git checkout <ref> -- [<paths>]
+ * Extract branch name from command line arguments, so
+ * all that is left is pathspecs.
*
- * <ref> must be a valid tree, everything after the '--' must be
- * a path.
- *
- * case 2: git checkout -- [<paths>]
- *
- * everything after the '--' must be paths.
- *
- * case 3: git checkout <something> [<paths>]
- *
- * With no paths, if <something> is a commit, that is to
- * switch to the branch or detach HEAD at it. As a special case,
- * if <something> is A...B (missing A or B means HEAD but you can
- * omit at most one side), and if there is a unique merge base
- * between A and B, A...B names that merge base.
- *
- * With no paths, if <something> is _not_ a commit, no -t nor -b
- * was given, and there is a remote-tracking branch whose name is
- * <something> in one and only one remote, then this is a short-hand
- * to fork local <something> from that remote-tracking branch.
+ * Handle
*
- * Otherwise <something> shall not be ambiguous.
- * - If it's *only* a reference, treat it like case (1).
- * - If it's only a path, treat it like case (2).
- * - else: fail.
+ * 1) git checkout <tree> -- [<paths>]
+ * 2) git checkout -- [<paths>]
+ * 3) git checkout <something> [<paths>]
*
+ * including "last branch" syntax and DWIM-ery for names of
+ * remote branches, erroring out for invalid or ambiguous cases.
*/
if (argc) {
- if (!strcmp(argv[0], "--")) { /* case (2) */
- argv++;
- argc--;
- goto no_reference;
- }
-
- arg = argv[0];
- has_dash_dash = (argc > 1) && !strcmp(argv[1], "--");
-
- if (!strcmp(arg, "-"))
- arg = "@{-1}";
-
- if (get_sha1_mb(arg, rev)) {
- if (has_dash_dash) /* case (1) */
- die(_("invalid reference: %s"), arg);
- if (!patch_mode &&
- dwim_new_local_branch &&
- opts.track == BRANCH_TRACK_UNSPECIFIED &&
- !opts.new_branch &&
- !check_filename(NULL, arg) &&
- argc == 1) {
- const char *remote = unique_tracking_name(arg);
- if (!remote || get_sha1(remote, rev))
- goto no_reference;
- opts.new_branch = arg;
- arg = remote;
- /* DWIMmed to create local branch */
- }
- else
- goto no_reference;
- }
-
- /* we can't end up being in (2) anymore, eat the argument */
- argv++;
- argc--;
-
- new.name = arg;
- if ((new.commit = lookup_commit_reference_gently(rev, 1))) {
- setup_branch_path(&new);
-
- if ((check_ref_format(new.path) == CHECK_REF_FORMAT_OK) &&
- resolve_ref(new.path, rev, 1, NULL))
- ;
- else
- new.path = NULL;
- parse_commit(new.commit);
- source_tree = new.commit->tree;
- } else
- source_tree = parse_tree_indirect(rev);
-
- if (!source_tree) /* case (1): want a tree */
- die(_("reference is not a tree: %s"), arg);
- if (!has_dash_dash) {/* case (3 -> 1) */
- /*
- * Do not complain the most common case
- * git checkout branch
- * even if there happen to be a file called 'branch';
- * it would be extremely annoying.
- */
- if (argc)
- verify_non_filename(NULL, arg);
- }
- else {
- argv++;
- argc--;
- }
+ int dwim_ok =
+ !patch_mode &&
+ dwim_new_local_branch &&
+ opts.track == BRANCH_TRACK_UNSPECIFIED &&
+ !opts.new_branch;
+ int n = parse_branchname_arg(argc, argv, dwim_ok,
+ &new, &source_tree, rev, &opts.new_branch);
+ argv += n;
+ argc -= n;
}
-no_reference:
-
if (opts.track == BRANCH_TRACK_UNSPECIFIED)
opts.track = git_branch_track;
}
}
+ if (opts.force_detach)
+ die("git checkout: --detach does not take a path argument");
+
if (1 < !!opts.writeout_stage + !!opts.force + !!opts.merge)
- die("git checkout: --ours/--theirs, --force and --merge are incompatible when\nchecking out of the index.");
+ die(_("git checkout: --ours/--theirs, --force and --merge are incompatible when\nchecking out of the index."));
return checkout_paths(source_tree, pathspec, &opts);
}
diff --cc builtin/clone.c
index c6e10bb9e916a21ad5c71018d6380ad85540dc65,b9394c41520407379b16297efac35c781cc0475f..0b5601a9b080e079ec077a8a765be24f2bf9bd29
--- 1/builtin/clone.c
--- 2/builtin/clone.c
+++ b/builtin/clone.c
setenv(CONFIG_ENVIRONMENT, mkpath("%s/config", git_dir), 1);
if (safe_create_leading_directories_const(git_dir) < 0)
- die("could not create leading directories of '%s'", git_dir);
+ die(_("could not create leading directories of '%s'"), git_dir);
- set_git_dir(make_absolute_path(git_dir));
+ set_git_dir(real_path(git_dir));
- if (0 <= option_verbosity)
- printf("Cloning into %s%s...\n",
- option_bare ? "bare repository " : "", dir);
+ if (0 <= option_verbosity) {
+ if (option_bare)
+ printf(_("Cloning into bare repository %s...\n"), dir);
+ else
+ printf(_("Cloning into %s...\n"), dir);
+ }
init_db(option_template, INIT_DB_QUIET);
/*
diff --cc builtin/commit.c
index 54b20497b120bc2bf5ee6e4904eca0ca5d83ff4f,271f31127cc338359fddf423d266bc2abba9dc23..67757e999fba514b62767d3351031e9eb6ef8c10
--- 1/builtin/commit.c
--- 2/builtin/commit.c
+++ b/builtin/commit.c
"\n"
"After doing this, you may fix the identity used for this commit with:\n"
"\n"
- " git commit --amend --reset-author\n";
+ " git commit --amend --reset-author\n");
static const char empty_amend_advice[] =
- "You asked to amend the most recent commit, but doing so would make\n"
+ N_("You asked to amend the most recent commit, but doing so would make\n"
"it empty. You can repeat your command with --allow-empty, or you can\n"
- "remove the commit entirely with \"git reset HEAD^\".\n";
+ "remove the commit entirely with \"git reset HEAD^\".\n");
- "The previous cherry-pick is now empty, possibly due to conflict resolution.\n"
+static const char empty_cherry_pick_advice[] =
- "Otherwise, please use 'git reset'\n";
++N_("The previous cherry-pick is now empty, possibly due to conflict resolution.\n"
+"If you wish to commit it anyway, use:\n"
+"\n"
+" git commit --allow-empty\n"
+"\n"
++"Otherwise, please use 'git reset'\n");
+
static unsigned char head_sha1[20];
-static char *use_message_buffer;
+static const char *use_message_buffer;
static const char commit_editmsg[] = "COMMIT_EDITMSG";
static struct lock_file index_lock; /* real index */
static struct lock_file false_lock; /* used only for partial commits */
*/
commit_style = COMMIT_PARTIAL;
- if (in_merge)
- die(_("cannot do a partial commit during a merge."));
+ if (whence != FROM_COMMIT)
- die("cannot do a partial commit during a %s.", whence_s());
++ die(_("cannot do a partial commit during a %s."), whence_s());
memset(&partial, 0, sizeof(partial));
partial.strdup_strings = 1;
email = getenv("GIT_AUTHOR_EMAIL");
date = getenv("GIT_AUTHOR_DATE");
- if (use_message && !renew_authorship) {
+ if (author_message) {
const char *a, *lb, *rb, *eol;
- a = strstr(use_message_buffer, "\nauthor ");
+ a = strstr(author_message_buffer, "\nauthor ");
if (!a)
- die("invalid commit: %s", author_message);
- die(_("invalid commit: %s"), use_message);
++ die(_("invalid commit: %s"), author_message);
lb = strchrnul(a + strlen("\nauthor "), '<');
rb = strchrnul(lb, '>');
eol = strchrnul(rb, '\n');
if (!*lb || !*rb || !*eol)
- die("invalid commit: %s", author_message);
- die(_("invalid commit: %s"), use_message);
++ die(_("invalid commit: %s"), author_message);
if (lb == a + strlen("\nauthor "))
/* \nauthor <foo@example.com> */
hook_arg1 = "merge";
} else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
- die_errno("could not read SQUASH_MSG");
+ die_errno(_("could not read SQUASH_MSG"));
hook_arg1 = "squash";
- } else if (template_file && !stat(template_file, &statbuf)) {
+ } else if (template_file) {
if (strbuf_read_file(&sb, template_file, 0) < 0)
- die_errno("could not read '%s'", template_file);
+ die_errno(_("could not read '%s'"), template_file);
hook_arg1 = "template";
}
strbuf_addstr(&committer_ident, git_committer_info(0));
if (use_editor && include_status) {
char *ai_tmp, *ci_tmp;
- if (in_merge)
+ if (whence != FROM_COMMIT)
status_printf_ln(s, GIT_COLOR_NORMAL,
- "\n"
+ _("\n"
- "It looks like you may be committing a MERGE.\n"
+ "It looks like you may be committing a %s.\n"
"If this is not correct, please remove the file\n"
" %s\n"
"and try again.\n"
- "",
+ ""),
- git_path("MERGE_HEAD"));
+ whence_s(),
+ git_path(whence == FROM_MERGE
+ ? "MERGE_HEAD"
+ : "CHERRY_PICK_HEAD"));
fprintf(s->fp, "\n");
status_printf(s, GIT_COLOR_NORMAL,
!(amend && is_a_merge(head_sha1))) {
run_status(stdout, index_file, prefix, 0, s);
if (amend)
- fputs(empty_amend_advice, stderr);
+ fputs(_(empty_amend_advice), stderr);
+ else if (whence == FROM_CHERRY_PICK)
- fputs(empty_cherry_pick_advice, stderr);
++ fputs(_(empty_cherry_pick_advice), stderr);
return 0;
}
else if (!strcmp(untracked_files_arg, "all"))
s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
else
- die("Invalid untracked files mode '%s'", untracked_files_arg);
+ die(_("Invalid untracked files mode '%s'"), untracked_files_arg);
}
- die("could not lookup commit %s", name);
+static const char *read_commit_message(const char *name)
+{
+ const char *out_enc, *out;
+ struct commit *commit;
+
+ commit = lookup_commit_reference_by_name(name);
+ if (!commit)
++ die(_("could not lookup commit %s"), name);
+ out_enc = get_commit_output_encoding();
+ out = logmsg_reencode(commit, out_enc);
+
+ /*
+ * If we failed to reencode the buffer, just copy it
+ * byte for byte so the user can try to fix it up.
+ * This also handles the case where input and output
+ * encodings are identical.
+ */
+ if (out == NULL)
+ out = xstrdup(commit->buffer);
+ return out;
+}
+
static int parse_and_validate_options(int argc, const char *argv[],
const char * const usage[],
const char *prefix,
/* Sanity check options */
if (amend && initial_commit)
- die("You have nothing to amend.");
+ die(_("You have nothing to amend."));
- if (amend && in_merge)
- die(_("You are in the middle of a merge -- cannot amend."));
+ if (amend && whence != FROM_COMMIT)
- die("You are in the middle of a %s -- cannot amend.", whence_s());
++ die(_("You are in the middle of a %s -- cannot amend."), whence_s());
if (fixup_message && squash_message)
- die("Options --squash and --fixup cannot be used together");
+ die(_("Options --squash and --fixup cannot be used together"));
if (use_message)
f++;
if (edit_message)
use_message = edit_message;
if (amend && !use_message && !fixup_message)
use_message = "HEAD";
- if (!use_message && renew_authorship)
+ if (!use_message && whence != FROM_CHERRY_PICK && renew_authorship)
- die("--reset-author can be used only with -C, -c or --amend.");
+ die(_("--reset-author can be used only with -C, -c or --amend."));
if (use_message) {
- const char *out_enc;
- struct commit *commit;
-
- commit = lookup_commit_reference_by_name(use_message);
- if (!commit)
- die(_("could not lookup commit %s"), use_message);
- out_enc = get_commit_output_encoding();
- use_message_buffer = logmsg_reencode(commit, out_enc);
-
- /*
- * If we failed to reencode the buffer, just copy it
- * byte for byte so the user can try to fix it up.
- * This also handles the case where input and output
- * encodings are identical.
- */
- if (use_message_buffer == NULL)
- use_message_buffer = xstrdup(commit->buffer);
+ use_message_buffer = read_commit_message(use_message);
+ if (!renew_authorship) {
+ author_message = use_message;
+ author_message_buffer = use_message_buffer;
+ }
+ }
+ if (whence == FROM_CHERRY_PICK && !renew_authorship) {
+ author_message = "CHERRY_PICK_HEAD";
+ author_message_buffer = read_commit_message(author_message);
}
if (!!also + !!only + !!all + !!interactive > 1)
}
if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0) {
rollback_index_files();
- die("cannot update HEAD ref");
+ die(_("cannot update HEAD ref"));
}
+ unlink(git_path("CHERRY_PICK_HEAD"));
unlink(git_path("MERGE_HEAD"));
unlink(git_path("MERGE_MSG"));
unlink(git_path("MERGE_MODE"));
diff --cc builtin/describe.c
index 4afd1504a666d670ec71bdbd61b09bc0530ed04b,037691e3d30ef2c6b80b23fa0fbcad67759560e2..66fc291c8a81de71dee7b597c9ab0dc9d70e8e29
--- 1/builtin/describe.c
--- 2/builtin/describe.c
+++ b/builtin/describe.c
}
if (!max_candidates)
- die("no tag exactly matches '%s'", sha1_to_hex(cmit->object.sha1));
+ die(_("no tag exactly matches '%s'"), sha1_to_hex(cmit->object.sha1));
if (debug)
- fprintf(stderr, "searching to describe %s\n", arg);
+ fprintf(stderr, _("searching to describe %s\n"), arg);
if (!have_util) {
- for_each_hash(&names, set_util);
+ for_each_hash(&names, set_util, NULL);
have_util = 1;
}
diff --cc builtin/diff.c
index 655a013ed05edd369225aa9ee9f39f347d687172,00342730b651c89d38e3f8af14f350a1077ffde2..717fa1a3414e18cbdd4c6eb1e0785761687688d7
--- 1/builtin/diff.c
--- 2/builtin/diff.c
+++ b/builtin/diff.c
continue;
}
- die("unhandled object '%s' given.", name);
+ die(_("unhandled object '%s' given."), name);
}
- if (rev.prune_data) {
- const char **pathspec = rev.prune_data;
- while (*pathspec) {
- if (!path)
- path = *pathspec;
- paths++;
- pathspec++;
- }
+ if (rev.prune_data.nr) {
+ if (!path)
+ path = rev.prune_data.items[0].match;
+ paths += rev.prune_data.nr;
}
/*
diff --cc builtin/fetch.c
Simple merge
diff --cc builtin/grep.c
index 85e9583a1335330f8e852d7937abb10c97798bc0,dfc32fbe6f87cb2959098640d583990552815607..5b8f30d3ed472bb74f1b992b5098a08f5d5377a1
--- 1/builtin/grep.c
--- 2/builtin/grep.c
+++ b/builtin/grep.c
data = lock_and_read_sha1_file(entry.sha1, &type, &size);
if (!data)
- die("unable to read tree (%s)",
+ die(_("unable to read tree (%s)"),
sha1_to_hex(entry.sha1));
+
+ strbuf_addch(base, '/');
init_tree_desc(&sub, data, size);
- hit |= grep_tree(opt, paths, &sub, tree_name, down);
+ hit |= grep_tree(opt, pathspec, &sub, base, tn_len);
free(data);
}
+ strbuf_setlen(base, old_baselen);
+
if (hit && opt->status_only)
break;
}
data = read_object_with_reference(obj->sha1, tree_type,
&size, NULL);
if (!data)
- die("unable to read tree (%s)", sha1_to_hex(obj->sha1));
+ die(_("unable to read tree (%s)"), sha1_to_hex(obj->sha1));
+
+ len = name ? strlen(name) : 0;
+ strbuf_init(&base, PATH_MAX + len + 1);
+ if (len) {
+ strbuf_add(&base, name, len);
+ strbuf_addch(&base, ':');
+ }
init_tree_desc(&tree, data, size);
- hit = grep_tree(opt, paths, &tree, name, "");
+ hit = grep_tree(opt, pathspec, &tree, &base, base.len);
+ strbuf_release(&base);
free(data);
return hit;
}
- die("unable to grep from object of type %s", typename(obj->type));
+ die(_("unable to grep from object of type %s"), typename(obj->type));
}
-static int grep_objects(struct grep_opt *opt, const char **paths,
+static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
const struct object_array *list)
{
unsigned int i;
int lno = 0;
struct strbuf sb = STRBUF_INIT;
- patterns = fopen(arg, "r");
+ patterns = from_stdin ? stdin : fopen(arg, "r");
if (!patterns)
- die_errno("cannot open '%s'", arg);
+ die_errno(_("cannot open '%s'"), arg);
while (strbuf_getline(&sb, patterns, '\n') == 0) {
char *s;
size_t len;
paths[0] = prefix;
paths[1] = NULL;
}
+ init_pathspec(&pathspec, paths);
+ pathspec.max_depth = opt.max_depth;
+ pathspec.recursive = 1;
if (show_in_pager && (cached || list.nr))
- die("--open-files-in-pager only works on the worktree");
+ die(_("--open-files-in-pager only works on the worktree"));
if (show_in_pager && opt.pattern_list && !opt.pattern_list->next) {
const char *pager = path_list.items[0].string;
if (!use_index) {
if (cached)
- die("--cached cannot be used with --no-index.");
+ die(_("--cached cannot be used with --no-index."));
if (list.nr)
- die("--no-index cannot be used with revs.");
+ die(_("--no-index cannot be used with revs."));
- hit = grep_directory(&opt, paths);
+ hit = grep_directory(&opt, &pathspec);
} else if (!list.nr) {
if (!cached)
setup_work_tree();
- hit = grep_cache(&opt, paths, cached);
+ hit = grep_cache(&opt, &pathspec, cached);
} else {
if (cached)
- die("both --cached and trees are given.");
+ die(_("both --cached and trees are given."));
- hit = grep_objects(&opt, paths, &list);
+ hit = grep_objects(&opt, &pathspec, &list);
}
if (use_threads)
diff --cc builtin/init-db.c
index 8f5cfd712243975dacd08cb51c69c2e174e470b1,e0e5ce3b1985cd2aba66d8c00d134d5c7a5a62ef..6621e5671cbc4cbe5631a40f918aa4f0f05bb62e
--- 1/builtin/init-db.c
--- 2/builtin/init-db.c
+++ b/builtin/init-db.c
if (!git_work_tree_cfg) {
git_work_tree_cfg = xcalloc(PATH_MAX, 1);
if (!getcwd(git_work_tree_cfg, PATH_MAX))
- die_errno ("Cannot access current working directory");
+ die_errno (_("Cannot access current working directory"));
}
if (work_tree)
- set_git_work_tree(make_absolute_path(work_tree));
+ set_git_work_tree(real_path(work_tree));
else
set_git_work_tree(git_work_tree_cfg);
if (access(get_git_work_tree(), X_OK))
diff --cc builtin/log.c
Simple merge
diff --cc builtin/merge.c
index c8d028cbccdc001efed2991e477b898606396114,f9982066139de64a3ad536b5970cb04e1c9f53cf..1e0bcfd792e4fb550fea8786ff2f84e7925aca86
--- 1/builtin/merge.c
--- 2/builtin/merge.c
+++ b/builtin/merge.c
}
- die_errno("Could not open '%s' for writing",
+static void write_merge_msg(void)
+{
+ int fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666);
+ if (fd < 0)
- die_errno("Could not write to '%s'", git_path("MERGE_MSG"));
++ die_errno(_("Could not open '%s' for writing"),
+ git_path("MERGE_MSG"));
+ if (write_in_full(fd, merge_msg.buf, merge_msg.len) != merge_msg.len)
++ die_errno(_("Could not write to '%s'"), git_path("MERGE_MSG"));
+ close(fd);
+}
+
+static void read_merge_msg(void)
+{
+ strbuf_reset(&merge_msg);
+ if (strbuf_read_file(&merge_msg, git_path("MERGE_MSG"), 0) < 0)
+ die_errno("Could not read from '%s'", git_path("MERGE_MSG"));
+}
+
+static void run_prepare_commit_msg(void)
+{
+ write_merge_msg();
+ run_hook(get_index_file(), "prepare-commit-msg",
+ git_path("MERGE_MSG"), "merge", NULL, NULL);
+ read_merge_msg();
+}
+
static int merge_trivial(void)
{
unsigned char result_tree[20], result_commit[20];
* add/rm <file>', just 'git commit'.
*/
if (advice_resolve_conflict)
- die("You have not concluded your merge (MERGE_HEAD exists).\n"
- "Please, commit your changes before you can merge.");
+ die(_("You have not concluded your merge (MERGE_HEAD exists).\n"
+ "Please, commit your changes before you can merge."));
else
- die("You have not concluded your merge (MERGE_HEAD exists).");
+ die(_("You have not concluded your merge (MERGE_HEAD exists)."));
}
+ if (file_exists(git_path("CHERRY_PICK_HEAD"))) {
+ if (advice_resolve_conflict)
+ die("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
+ "Please, commit your changes before you can merge.");
+ else
+ die("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).");
+ }
resolve_undo_clear();
if (verbosity < 0)
* We do the same for "git pull".
*/
if (argc != 1)
- die("Can merge only exactly one commit into "
- "empty head");
+ die(_("Can merge only exactly one commit into "
+ "empty head"));
if (squash)
- die("Squash commit into empty head not supported yet");
+ die(_("Squash commit into empty head not supported yet"));
if (!allow_fast_forward)
- die("Non-fast-forward commit does not make sense into "
- "an empty head");
+ die(_("Non-fast-forward commit does not make sense into "
+ "an empty head"));
remote_head = peel_to_type(argv[0], 0, NULL, OBJ_COMMIT);
if (!remote_head)
- die("%s - not something we can merge", argv[0]);
+ die(_("%s - not something we can merge"), argv[0]);
+ read_empty(remote_head->sha1, 0);
update_ref("initial pull", "HEAD", remote_head->sha1, NULL, 0,
DIE_ON_ERR);
- read_empty(remote_head->sha1, 0);
return 0;
} else {
struct strbuf merge_names = STRBUF_INIT;
sha1_to_hex(j->item->object.sha1));
fd = open(git_path("MERGE_HEAD"), O_WRONLY | O_CREAT, 0666);
if (fd < 0)
- die_errno("Could not open '%s' for writing",
+ die_errno(_("Could not open '%s' for writing"),
git_path("MERGE_HEAD"));
if (write_in_full(fd, buf.buf, buf.len) != buf.len)
- die_errno("Could not write to '%s'", git_path("MERGE_HEAD"));
+ die_errno(_("Could not write to '%s'"), git_path("MERGE_HEAD"));
close(fd);
strbuf_addch(&merge_msg, '\n');
- fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666);
- if (fd < 0)
- die_errno(_("Could not open '%s' for writing"),
- git_path("MERGE_MSG"));
- if (write_in_full(fd, merge_msg.buf, merge_msg.len) !=
- merge_msg.len)
- die_errno(_("Could not write to '%s'"), git_path("MERGE_MSG"));
- close(fd);
+ write_merge_msg();
fd = open(git_path("MERGE_MODE"), O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd < 0)
- die_errno("Could not open '%s' for writing",
+ die_errno(_("Could not open '%s' for writing"),
git_path("MERGE_MODE"));
strbuf_reset(&buf);
if (!allow_fast_forward)
diff --cc builtin/notes.c
Simple merge
diff --cc builtin/push.c
index 6f6a66f9862d5ee5eaf4a4ce07934832569eacf9,8c8d8c717be6be5b4c701d6af53307ac684c54a5..9cebf9ea234d968eab638f7dcdc65370f77c0047
--- 1/builtin/push.c
--- 2/builtin/push.c
+++ b/builtin/push.c
struct strbuf refspec = STRBUF_INIT;
struct branch *branch = branch_get(NULL);
if (!branch)
- die("You are not currently on a branch.\n"
- die(_("You are not currently on a branch."));
++ die(_("You are not currently on a branch.\n"
+ "To push the history leading to the current (detached HEAD)\n"
+ "state now, use\n"
+ "\n"
- " git push %s HEAD:<name-of-remote-branch>\n",
++ " git push %s HEAD:<name-of-remote-branch>\n"),
+ remote->name);
if (!branch->merge_nr || !branch->merge)
- die("The current branch %s has no upstream branch.\n"
- die(_("The current branch %s is not tracking anything."),
++ die(_("The current branch %s has no upstream branch.\n"
+ "To push the current branch and set the remote as upstream, use\n"
+ "\n"
- " git push --set-upstream %s %s\n",
++ " git push --set-upstream %s %s\n"),
+ branch->name,
+ remote->name,
branch->name);
if (branch->merge_nr != 1)
- die("The current branch %s has multiple upstream branches, "
- "refusing to push.", branch->name);
- die(_("The current branch %s is tracking multiple branches, "
++ die(_("The current branch %s has multiple upstream branches, "
+ "refusing to push."), branch->name);
strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src);
add_refspec(refspec.buf);
}
if (!remote) {
if (repo)
- die("bad repository '%s'", repo);
- die("No configured push destination.\n"
+ die(_("bad repository '%s'"), repo);
- die(_("No destination configured to push to."));
++ die(_("No configured push destination.\n"
+ "Either specify the URL from the command-line or configure a remote repository using\n"
+ "\n"
+ " git remote add <name> <url>\n"
+ "\n"
+ "and then push using the remote name\n"
+ "\n"
- " git push <name>\n");
++ " git push <name>\n"));
}
if (remote->mirror)
diff --cc builtin/reset.c
Simple merge
diff --cc builtin/revert.c
index c57b872fe114145ec82bf33717c2a8d7f0982204,98dfd4d131444e0b1893d734b16a231781024321..2bb13ebb1de48e793e01d18ced29a468aa273b34
--- 1/builtin/revert.c
--- 2/builtin/revert.c
+++ b/builtin/revert.c
strbuf_addstr(msgbuf, p);
}
-static void set_author_ident_env(const char *message)
+static void write_cherry_pick_head(void)
{
- const char *p = message;
- if (!p)
- die (_("Could not read commit message of %s"),
- sha1_to_hex(commit->object.sha1));
- while (*p && *p != '\n') {
- const char *eol;
-
- for (eol = p; *eol && *eol != '\n'; eol++)
- ; /* do nothing */
- if (!prefixcmp(p, "author ")) {
- char *line, *pend, *email, *timestamp;
-
- p += 7;
- line = xmemdupz(p, eol - p);
- email = strchr(line, '<');
- if (!email)
- die (_("Could not extract author email from %s"),
- sha1_to_hex(commit->object.sha1));
- if (email == line)
- pend = line;
- else
- for (pend = email; pend != line + 1 &&
- isspace(pend[-1]); pend--);
- ; /* do nothing */
- *pend = '\0';
- email++;
- timestamp = strchr(email, '>');
- if (!timestamp)
- die (_("Could not extract author time from %s"),
- sha1_to_hex(commit->object.sha1));
- *timestamp = '\0';
- for (timestamp++; *timestamp && isspace(*timestamp);
- timestamp++)
- ; /* do nothing */
- setenv("GIT_AUTHOR_NAME", line, 1);
- setenv("GIT_AUTHOR_EMAIL", email, 1);
- setenv("GIT_AUTHOR_DATE", timestamp, 1);
- free(line);
- return;
- }
- p = eol;
- if (*p == '\n')
- p++;
- }
- die (_("No author information found in %s"),
- sha1_to_hex(commit->object.sha1));
+ int fd;
+ struct strbuf buf = STRBUF_INIT;
+
+ strbuf_addf(&buf, "%s\n", sha1_to_hex(commit->object.sha1));
+
+ fd = open(git_path("CHERRY_PICK_HEAD"), O_WRONLY | O_CREAT, 0666);
+ if (fd < 0)
- die_errno("Could not open '%s' for writing",
++ die_errno(_("Could not open '%s' for writing"),
+ git_path("CHERRY_PICK_HEAD"));
+ if (write_in_full(fd, buf.buf, buf.len) != buf.len || close(fd))
- die_errno("Could not write to '%s'", git_path("CHERRY_PICK_HEAD"));
++ die_errno(_("Could not write to '%s'"), git_path("CHERRY_PICK_HEAD"));
+ strbuf_release(&buf);
}
static void advise(const char *advice, ...)
diff --cc builtin/tag.c
Simple merge
diff --cc t/t0001-init.sh
Simple merge
diff --cc t/t3200-branch.sh
Simple merge
diff --cc t/t3507-cherry-pick-conflict.sh
index 95741801b0007b6ecbf22f665c4dcf3c744d5221,f7e40723198b6935b306409033241cfdd3a014a8..c0c8330c20e80f26d51b62c8999533c5692094de
test "$head" = "$newhead"
'
- test_expect_success 'advice from failed cherry-pick' "
+ test_expect_success C_LOCALE_OUTPUT 'advice from failed cherry-pick' "
- git checkout -f initial^0 &&
- git read-tree -u --reset HEAD &&
- git clean -d -f -f -q -x &&
-
- git update-index --refresh &&
- git diff-index --exit-code HEAD &&
+ pristine_detach initial &&
picked=\$(git rev-parse --short picked) &&
cat <<-EOF >expected &&
diff --cc t/t4014-format-patch.sh
Simple merge
diff --cc t/t5601-clone.sh
Simple merge
diff --cc t/t6040-tracking-info.sh
Simple merge
diff --cc t/t7201-co.sh
Simple merge
diff --cc t/t7500-commit.sh
Simple merge
diff --cc t/t7607-merge-overwrite.sh
index b54e840ee2ab09a67afc663a2f475bfc9fcb9d8b,0a9b90b33f4bc5b66c7e5d9b1334eab9f84c5118..ef84f04102ed067768c66ea9608b98d47851eb8b
git rm -fr . &&
git checkout --orphan new &&
cp important c0.c &&
- test_must_fail git merge c0 2>out &&
- test_cmp out expect &&
+ test_must_fail git merge c0 2>out
+ '
+
+ test_expect_success C_LOCALE_OUTPUT 'will not overwrite untracked file on unborn branch: output' '
+ test_cmp out expect
+ '
+
+ test_expect_success 'will not overwrite untracked file on unborn branch .git/MERGE_HEAD sanity etc.' '
+ test_when_finished "rm c0.c" &&
test_path_is_missing .git/MERGE_HEAD &&
test_cmp important c0.c
'
diff --cc wt-status.c
index 53558d7e5f517479af478e375076718189c2d2d5,9ff059012249821fe36cb2060f19a77db16efcc0..9f4e0ba9c17120ca2903b30b95b6d8fbcc62cd9c
--- 1/wt-status.c
--- 2/wt-status.c
+++ b/wt-status.c
{
const char *c = color(WT_STATUS_HEADER, s);
- status_printf_ln(s, c, "Unmerged paths:");
+ status_printf_ln(s, c, _("Unmerged paths:"));
if (!advice_status_hints)
return;
- if (s->in_merge)
+ if (s->whence != FROM_COMMIT)
;
else if (!s->is_initial)
- status_printf_ln(s, c, " (use \"git reset %s <file>...\" to unstage)", s->reference);
+ status_printf_ln(s, c, _(" (use \"git reset %s <file>...\" to unstage)"), s->reference);
else
- status_printf_ln(s, c, " (use \"git rm --cached <file>...\" to unstage)");
- status_printf_ln(s, c, " (use \"git add/rm <file>...\" as appropriate to mark resolution)");
+ status_printf_ln(s, c, _(" (use \"git rm --cached <file>...\" to unstage)"));
+ status_printf_ln(s, c, _(" (use \"git add/rm <file>...\" as appropriate to mark resolution)"));
status_printf_ln(s, c, "");
}
{
const char *c = color(WT_STATUS_HEADER, s);
- status_printf_ln(s, c, "Changes to be committed:");
+ status_printf_ln(s, c, _("Changes to be committed:"));
if (!advice_status_hints)
return;
- if (s->in_merge)
+ if (s->whence != FROM_COMMIT)
; /* NEEDSWORK: use "git reset --unresolve"??? */
else if (!s->is_initial)
- status_printf_ln(s, c, " (use \"git reset %s <file>...\" to unstage)", s->reference);
+ status_printf_ln(s, c, _(" (use \"git reset %s <file>...\" to unstage)"), s->reference);
else
- status_printf_ln(s, c, " (use \"git rm --cached <file>...\" to unstage)");
+ status_printf_ln(s, c, _(" (use \"git rm --cached <file>...\" to unstage)"));
status_printf_ln(s, c, "");
}