revert(3p/git): Revert merge of git upstream at v2.26.2
This causes cgit to serve error pages, which is undesirable. This reverts commit5229c9b232, reversing changes made tof2b211131f.
This commit is contained in:
parent
6f8fbf4aa4
commit
93ba78d6f4
1006 changed files with 60537 additions and 148724 deletions
112
third_party/git/builtin/add.c
vendored
112
third_party/git/builtin/add.c
vendored
|
|
@ -20,7 +20,6 @@
|
|||
#include "bulk-checkin.h"
|
||||
#include "argv-array.h"
|
||||
#include "submodule.h"
|
||||
#include "add-interactive.h"
|
||||
|
||||
static const char * const builtin_add_usage[] = {
|
||||
N_("git add [<options>] [--] <pathspec>..."),
|
||||
|
|
@ -29,9 +28,6 @@ static const char * const builtin_add_usage[] = {
|
|||
static int patch_interactive, add_interactive, edit_interactive;
|
||||
static int take_worktree_changes;
|
||||
static int add_renormalize;
|
||||
static int pathspec_file_nul;
|
||||
static const char *pathspec_from_file;
|
||||
static int legacy_stash_p; /* support for the scripted `git stash` */
|
||||
|
||||
struct update_callback_data {
|
||||
int flags;
|
||||
|
|
@ -189,34 +185,6 @@ int run_add_interactive(const char *revision, const char *patch_mode,
|
|||
{
|
||||
int status, i;
|
||||
struct argv_array argv = ARGV_ARRAY_INIT;
|
||||
int use_builtin_add_i =
|
||||
git_env_bool("GIT_TEST_ADD_I_USE_BUILTIN", -1);
|
||||
|
||||
if (use_builtin_add_i < 0)
|
||||
git_config_get_bool("add.interactive.usebuiltin",
|
||||
&use_builtin_add_i);
|
||||
|
||||
if (use_builtin_add_i == 1) {
|
||||
enum add_p_mode mode;
|
||||
|
||||
if (!patch_mode)
|
||||
return !!run_add_i(the_repository, pathspec);
|
||||
|
||||
if (!strcmp(patch_mode, "--patch"))
|
||||
mode = ADD_P_ADD;
|
||||
else if (!strcmp(patch_mode, "--patch=stash"))
|
||||
mode = ADD_P_STASH;
|
||||
else if (!strcmp(patch_mode, "--patch=reset"))
|
||||
mode = ADD_P_RESET;
|
||||
else if (!strcmp(patch_mode, "--patch=checkout"))
|
||||
mode = ADD_P_CHECKOUT;
|
||||
else if (!strcmp(patch_mode, "--patch=worktree"))
|
||||
mode = ADD_P_WORKTREE;
|
||||
else
|
||||
die("'%s' not supported", patch_mode);
|
||||
|
||||
return !!run_add_p(the_repository, mode, revision, pathspec);
|
||||
}
|
||||
|
||||
argv_array_push(&argv, "add--interactive");
|
||||
if (patch_mode)
|
||||
|
|
@ -341,10 +309,6 @@ static struct option builtin_add_options[] = {
|
|||
N_("override the executable bit of the listed files")),
|
||||
OPT_HIDDEN_BOOL(0, "warn-embedded-repo", &warn_on_embedded_repo,
|
||||
N_("warn when adding an embedded repository")),
|
||||
OPT_HIDDEN_BOOL(0, "legacy-stash-p", &legacy_stash_p,
|
||||
N_("backend for `git stash -p`")),
|
||||
OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
|
||||
OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
|
|
@ -355,7 +319,6 @@ static int add_config(const char *var, const char *value, void *cb)
|
|||
ignore_add_errors = git_config_bool(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return git_default_config(var, value, cb);
|
||||
}
|
||||
|
||||
|
|
@ -406,10 +369,7 @@ static int add_files(struct dir_struct *dir, int flags)
|
|||
fprintf(stderr, _(ignore_error));
|
||||
for (i = 0; i < dir->ignored_nr; i++)
|
||||
fprintf(stderr, "%s\n", dir->ignored[i]->name);
|
||||
if (advice_add_ignored_file)
|
||||
advise(_("Use -f if you really want to add them.\n"
|
||||
"Turn this message off by running\n"
|
||||
"\"git config advice.addIgnoredFile false\""));
|
||||
fprintf(stderr, _("Use -f if you really want to add them.\n"));
|
||||
exit_status = 1;
|
||||
}
|
||||
|
||||
|
|
@ -442,28 +402,11 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
|||
builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
|
||||
if (patch_interactive)
|
||||
add_interactive = 1;
|
||||
if (add_interactive) {
|
||||
if (pathspec_from_file)
|
||||
die(_("--pathspec-from-file is incompatible with --interactive/--patch"));
|
||||
if (add_interactive)
|
||||
exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
|
||||
}
|
||||
if (legacy_stash_p) {
|
||||
struct pathspec pathspec;
|
||||
|
||||
parse_pathspec(&pathspec, 0,
|
||||
PATHSPEC_PREFER_FULL |
|
||||
PATHSPEC_SYMLINK_LEADING_PATH |
|
||||
PATHSPEC_PREFIX_ORIGIN,
|
||||
prefix, argv);
|
||||
|
||||
return run_add_interactive(NULL, "--patch=stash", &pathspec);
|
||||
}
|
||||
|
||||
if (edit_interactive) {
|
||||
if (pathspec_from_file)
|
||||
die(_("--pathspec-from-file is incompatible with --edit"));
|
||||
if (edit_interactive)
|
||||
return(edit_patch(argc, argv, prefix));
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
|
|
@ -475,6 +418,10 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
|||
if (addremove && take_worktree_changes)
|
||||
die(_("-A and -u are mutually incompatible"));
|
||||
|
||||
if (!take_worktree_changes && addremove_explicit < 0 && argc)
|
||||
/* Turn "git add pathspec..." to "git add -A pathspec..." */
|
||||
addremove = 1;
|
||||
|
||||
if (!show_only && ignore_missing)
|
||||
die(_("Option --ignore-missing can only be used together with --dry-run"));
|
||||
|
||||
|
|
@ -487,6 +434,19 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
|||
|
||||
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
|
||||
|
||||
flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
|
||||
(show_only ? ADD_CACHE_PRETEND : 0) |
|
||||
(intent_to_add ? ADD_CACHE_INTENT : 0) |
|
||||
(ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
|
||||
(!(addremove || take_worktree_changes)
|
||||
? ADD_CACHE_IGNORE_REMOVAL : 0));
|
||||
|
||||
if (require_pathspec && argc == 0) {
|
||||
fprintf(stderr, _("Nothing specified, nothing added.\n"));
|
||||
fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the "pathspec '%s' did not match any files" block
|
||||
* below before enabling new magic.
|
||||
|
|
@ -496,38 +456,6 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
|||
PATHSPEC_SYMLINK_LEADING_PATH,
|
||||
prefix, argv);
|
||||
|
||||
if (pathspec_from_file) {
|
||||
if (pathspec.nr)
|
||||
die(_("--pathspec-from-file is incompatible with pathspec arguments"));
|
||||
|
||||
parse_pathspec_file(&pathspec, PATHSPEC_ATTR,
|
||||
PATHSPEC_PREFER_FULL |
|
||||
PATHSPEC_SYMLINK_LEADING_PATH,
|
||||
prefix, pathspec_from_file, pathspec_file_nul);
|
||||
} else if (pathspec_file_nul) {
|
||||
die(_("--pathspec-file-nul requires --pathspec-from-file"));
|
||||
}
|
||||
|
||||
if (require_pathspec && pathspec.nr == 0) {
|
||||
fprintf(stderr, _("Nothing specified, nothing added.\n"));
|
||||
if (advice_add_empty_pathspec)
|
||||
advise( _("Maybe you wanted to say 'git add .'?\n"
|
||||
"Turn this message off by running\n"
|
||||
"\"git config advice.addEmptyPathspec false\""));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!take_worktree_changes && addremove_explicit < 0 && pathspec.nr)
|
||||
/* Turn "git add pathspec..." to "git add -A pathspec..." */
|
||||
addremove = 1;
|
||||
|
||||
flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
|
||||
(show_only ? ADD_CACHE_PRETEND : 0) |
|
||||
(intent_to_add ? ADD_CACHE_INTENT : 0) |
|
||||
(ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
|
||||
(!(addremove || take_worktree_changes)
|
||||
? ADD_CACHE_IGNORE_REMOVAL : 0));
|
||||
|
||||
if (read_cache_preload(&pathspec) < 0)
|
||||
die(_("index file corrupt"));
|
||||
|
||||
|
|
|
|||
119
third_party/git/builtin/am.c
vendored
119
third_party/git/builtin/am.c
vendored
|
|
@ -24,6 +24,7 @@
|
|||
#include "sequencer.h"
|
||||
#include "revision.h"
|
||||
#include "merge-recursive.h"
|
||||
#include "revision.h"
|
||||
#include "log-tree.h"
|
||||
#include "notes-utils.h"
|
||||
#include "rerere.h"
|
||||
|
|
@ -81,11 +82,6 @@ enum signoff_type {
|
|||
SIGNOFF_EXPLICIT /* --signoff was set on the command-line */
|
||||
};
|
||||
|
||||
enum show_patch_type {
|
||||
SHOW_PATCH_RAW = 0,
|
||||
SHOW_PATCH_DIFF = 1,
|
||||
};
|
||||
|
||||
struct am_state {
|
||||
/* state directory path */
|
||||
char *dir;
|
||||
|
|
@ -1075,6 +1071,19 @@ static const char *msgnum(const struct am_state *state)
|
|||
return sb.buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh and write index.
|
||||
*/
|
||||
static void refresh_and_write_cache(void)
|
||||
{
|
||||
struct lock_file lock_file = LOCK_INIT;
|
||||
|
||||
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
|
||||
refresh_cache(REFRESH_QUIET);
|
||||
if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
|
||||
die(_("unable to write index file"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dies with a user-friendly message on how to proceed after resolving the
|
||||
* problem. This message can be overridden with state->resolvemsg.
|
||||
|
|
@ -1263,9 +1272,7 @@ static void get_commit_info(struct am_state *state, struct commit *commit)
|
|||
buffer = logmsg_reencode(commit, NULL, get_commit_output_encoding());
|
||||
|
||||
ident_line = find_commit_header(buffer, "author", &ident_len);
|
||||
if (!ident_line)
|
||||
die(_("missing author line in commit %s"),
|
||||
oid_to_hex(&commit->object.oid));
|
||||
|
||||
if (split_ident_line(&id, ident_line, ident_len) < 0)
|
||||
die(_("invalid ident line: %.*s"), (int)ident_len, ident_line);
|
||||
|
||||
|
|
@ -1531,7 +1538,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
|
|||
o.branch1 = "HEAD";
|
||||
their_tree_name = xstrfmt("%.*s", linelen(state->msg), state->msg);
|
||||
o.branch2 = their_tree_name;
|
||||
o.detect_directory_renames = MERGE_DIRECTORY_RENAMES_NONE;
|
||||
o.detect_directory_renames = 0;
|
||||
|
||||
if (state->quiet)
|
||||
o.verbosity = 0;
|
||||
|
|
@ -1696,8 +1703,7 @@ static void am_run(struct am_state *state, int resume)
|
|||
|
||||
unlink(am_path(state, "dirtyindex"));
|
||||
|
||||
if (refresh_and_write_cache(REFRESH_QUIET, 0, 0) < 0)
|
||||
die(_("unable to write index file"));
|
||||
refresh_and_write_cache();
|
||||
|
||||
if (repo_index_has_changes(the_repository, NULL, &sb)) {
|
||||
write_state_bool(state, "dirtyindex", 1);
|
||||
|
|
@ -1768,7 +1774,7 @@ static void am_run(struct am_state *state, int resume)
|
|||
linelen(state->msg), state->msg);
|
||||
|
||||
if (advice_amworkdir)
|
||||
advise(_("Use 'git am --show-current-patch=diff' to see the failed patch"));
|
||||
advise(_("Use 'git am --show-current-patch' to see the failed patch"));
|
||||
|
||||
die_user_resolve(state);
|
||||
}
|
||||
|
|
@ -2066,7 +2072,7 @@ static void am_abort(struct am_state *state)
|
|||
am_destroy(state);
|
||||
}
|
||||
|
||||
static int show_patch(struct am_state *state, enum show_patch_type sub_mode)
|
||||
static int show_patch(struct am_state *state)
|
||||
{
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
const char *patch_path;
|
||||
|
|
@ -2083,17 +2089,7 @@ static int show_patch(struct am_state *state, enum show_patch_type sub_mode)
|
|||
return ret;
|
||||
}
|
||||
|
||||
switch (sub_mode) {
|
||||
case SHOW_PATCH_RAW:
|
||||
patch_path = am_path(state, msgnum(state));
|
||||
break;
|
||||
case SHOW_PATCH_DIFF:
|
||||
patch_path = am_path(state, "patch");
|
||||
break;
|
||||
default:
|
||||
BUG("invalid mode for --show-current-patch");
|
||||
}
|
||||
|
||||
patch_path = am_path(state, msgnum(state));
|
||||
len = strbuf_read_file(&sb, patch_path, 0);
|
||||
if (len < 0)
|
||||
die_errno(_("failed to read '%s'"), patch_path);
|
||||
|
|
@ -2133,7 +2129,7 @@ static int parse_opt_patchformat(const struct option *opt, const char *arg, int
|
|||
return 0;
|
||||
}
|
||||
|
||||
enum resume_type {
|
||||
enum resume_mode {
|
||||
RESUME_FALSE = 0,
|
||||
RESUME_APPLY,
|
||||
RESUME_RESOLVED,
|
||||
|
|
@ -2143,45 +2139,6 @@ enum resume_type {
|
|||
RESUME_SHOW_PATCH
|
||||
};
|
||||
|
||||
struct resume_mode {
|
||||
enum resume_type mode;
|
||||
enum show_patch_type sub_mode;
|
||||
};
|
||||
|
||||
static int parse_opt_show_current_patch(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
int *opt_value = opt->value;
|
||||
struct resume_mode *resume = container_of(opt_value, struct resume_mode, mode);
|
||||
|
||||
/*
|
||||
* Please update $__git_showcurrentpatch in git-completion.bash
|
||||
* when you add new options
|
||||
*/
|
||||
const char *valid_modes[] = {
|
||||
[SHOW_PATCH_DIFF] = "diff",
|
||||
[SHOW_PATCH_RAW] = "raw"
|
||||
};
|
||||
int new_value = SHOW_PATCH_RAW;
|
||||
|
||||
if (arg) {
|
||||
for (new_value = 0; new_value < ARRAY_SIZE(valid_modes); new_value++) {
|
||||
if (!strcmp(arg, valid_modes[new_value]))
|
||||
break;
|
||||
}
|
||||
if (new_value >= ARRAY_SIZE(valid_modes))
|
||||
return error(_("Invalid value for --show-current-patch: %s"), arg);
|
||||
}
|
||||
|
||||
if (resume->mode == RESUME_SHOW_PATCH && new_value != resume->sub_mode)
|
||||
return error(_("--show-current-patch=%s is incompatible with "
|
||||
"--show-current-patch=%s"),
|
||||
arg, valid_modes[resume->sub_mode]);
|
||||
|
||||
resume->mode = RESUME_SHOW_PATCH;
|
||||
resume->sub_mode = new_value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int git_am_config(const char *k, const char *v, void *cb)
|
||||
{
|
||||
int status;
|
||||
|
|
@ -2199,7 +2156,7 @@ int cmd_am(int argc, const char **argv, const char *prefix)
|
|||
int binary = -1;
|
||||
int keep_cr = -1;
|
||||
int patch_format = PATCH_FORMAT_UNKNOWN;
|
||||
struct resume_mode resume = { .mode = RESUME_FALSE };
|
||||
enum resume_mode resume = RESUME_FALSE;
|
||||
int in_progress;
|
||||
int ret = 0;
|
||||
|
||||
|
|
@ -2268,26 +2225,24 @@ int cmd_am(int argc, const char **argv, const char *prefix)
|
|||
PARSE_OPT_NOARG),
|
||||
OPT_STRING(0, "resolvemsg", &state.resolvemsg, NULL,
|
||||
N_("override error message when patch failure occurs")),
|
||||
OPT_CMDMODE(0, "continue", &resume.mode,
|
||||
OPT_CMDMODE(0, "continue", &resume,
|
||||
N_("continue applying patches after resolving a conflict"),
|
||||
RESUME_RESOLVED),
|
||||
OPT_CMDMODE('r', "resolved", &resume.mode,
|
||||
OPT_CMDMODE('r', "resolved", &resume,
|
||||
N_("synonyms for --continue"),
|
||||
RESUME_RESOLVED),
|
||||
OPT_CMDMODE(0, "skip", &resume.mode,
|
||||
OPT_CMDMODE(0, "skip", &resume,
|
||||
N_("skip the current patch"),
|
||||
RESUME_SKIP),
|
||||
OPT_CMDMODE(0, "abort", &resume.mode,
|
||||
OPT_CMDMODE(0, "abort", &resume,
|
||||
N_("restore the original branch and abort the patching operation."),
|
||||
RESUME_ABORT),
|
||||
OPT_CMDMODE(0, "quit", &resume.mode,
|
||||
OPT_CMDMODE(0, "quit", &resume,
|
||||
N_("abort the patching operation but keep HEAD where it is."),
|
||||
RESUME_QUIT),
|
||||
{ OPTION_CALLBACK, 0, "show-current-patch", &resume.mode,
|
||||
"(diff|raw)",
|
||||
N_("show the patch being applied"),
|
||||
PARSE_OPT_CMDMODE | PARSE_OPT_OPTARG | PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP,
|
||||
parse_opt_show_current_patch, RESUME_SHOW_PATCH },
|
||||
OPT_CMDMODE(0, "show-current-patch", &resume,
|
||||
N_("show the patch being applied."),
|
||||
RESUME_SHOW_PATCH),
|
||||
OPT_BOOL(0, "committer-date-is-author-date",
|
||||
&state.committer_date_is_author_date,
|
||||
N_("lie about committer date")),
|
||||
|
|
@ -2337,12 +2292,12 @@ int cmd_am(int argc, const char **argv, const char *prefix)
|
|||
* intend to feed us a patch but wanted to continue
|
||||
* unattended.
|
||||
*/
|
||||
if (argc || (resume.mode == RESUME_FALSE && !isatty(0)))
|
||||
if (argc || (resume == RESUME_FALSE && !isatty(0)))
|
||||
die(_("previous rebase directory %s still exists but mbox given."),
|
||||
state.dir);
|
||||
|
||||
if (resume.mode == RESUME_FALSE)
|
||||
resume.mode = RESUME_APPLY;
|
||||
if (resume == RESUME_FALSE)
|
||||
resume = RESUME_APPLY;
|
||||
|
||||
if (state.signoff == SIGNOFF_EXPLICIT)
|
||||
am_append_signoff(&state);
|
||||
|
|
@ -2356,7 +2311,7 @@ int cmd_am(int argc, const char **argv, const char *prefix)
|
|||
* stray directories.
|
||||
*/
|
||||
if (file_exists(state.dir) && !state.rebasing) {
|
||||
if (resume.mode == RESUME_ABORT || resume.mode == RESUME_QUIT) {
|
||||
if (resume == RESUME_ABORT || resume == RESUME_QUIT) {
|
||||
am_destroy(&state);
|
||||
am_state_release(&state);
|
||||
return 0;
|
||||
|
|
@ -2367,7 +2322,7 @@ int cmd_am(int argc, const char **argv, const char *prefix)
|
|||
state.dir);
|
||||
}
|
||||
|
||||
if (resume.mode)
|
||||
if (resume)
|
||||
die(_("Resolve operation not in progress, we are not resuming."));
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
|
|
@ -2385,7 +2340,7 @@ int cmd_am(int argc, const char **argv, const char *prefix)
|
|||
argv_array_clear(&paths);
|
||||
}
|
||||
|
||||
switch (resume.mode) {
|
||||
switch (resume) {
|
||||
case RESUME_FALSE:
|
||||
am_run(&state, 0);
|
||||
break;
|
||||
|
|
@ -2406,7 +2361,7 @@ int cmd_am(int argc, const char **argv, const char *prefix)
|
|||
am_destroy(&state);
|
||||
break;
|
||||
case RESUME_SHOW_PATCH:
|
||||
ret = show_patch(&state, resume.sub_mode);
|
||||
ret = show_patch(&state);
|
||||
break;
|
||||
default:
|
||||
BUG("invalid resume value");
|
||||
|
|
|
|||
134
third_party/git/builtin/bisect--helper.c
vendored
134
third_party/git/builtin/bisect--helper.c
vendored
|
|
@ -52,8 +52,8 @@ static void set_terms(struct bisect_terms *terms, const char *bad,
|
|||
terms->term_bad = xstrdup(bad);
|
||||
}
|
||||
|
||||
static const char vocab_bad[] = "bad|new";
|
||||
static const char vocab_good[] = "good|old";
|
||||
static const char *vocab_bad = "bad|new";
|
||||
static const char *vocab_good = "good|old";
|
||||
|
||||
/*
|
||||
* Check whether the string `term` belongs to the set of strings
|
||||
|
|
@ -169,12 +169,11 @@ static int bisect_reset(const char *commit)
|
|||
|
||||
argv_array_pushl(&argv, "checkout", branch.buf, "--", NULL);
|
||||
if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {
|
||||
error(_("could not check out original"
|
||||
" HEAD '%s'. Try 'git bisect"
|
||||
" reset <commit>'."), branch.buf);
|
||||
strbuf_release(&branch);
|
||||
argv_array_clear(&argv);
|
||||
return -1;
|
||||
return error(_("could not check out original"
|
||||
" HEAD '%s'. Try 'git bisect"
|
||||
" reset <commit>'."), branch.buf);
|
||||
}
|
||||
argv_array_clear(&argv);
|
||||
}
|
||||
|
|
@ -206,31 +205,31 @@ static int bisect_write(const char *state, const char *rev,
|
|||
struct object_id oid;
|
||||
struct commit *commit;
|
||||
FILE *fp = NULL;
|
||||
int res = 0;
|
||||
int retval = 0;
|
||||
|
||||
if (!strcmp(state, terms->term_bad)) {
|
||||
strbuf_addf(&tag, "refs/bisect/%s", state);
|
||||
} else if (one_of(state, terms->term_good, "skip", NULL)) {
|
||||
strbuf_addf(&tag, "refs/bisect/%s-%s", state, rev);
|
||||
} else {
|
||||
res = error(_("Bad bisect_write argument: %s"), state);
|
||||
retval = error(_("Bad bisect_write argument: %s"), state);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (get_oid(rev, &oid)) {
|
||||
res = error(_("couldn't get the oid of the rev '%s'"), rev);
|
||||
retval = error(_("couldn't get the oid of the rev '%s'"), rev);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (update_ref(NULL, tag.buf, &oid, NULL, 0,
|
||||
UPDATE_REFS_MSG_ON_ERR)) {
|
||||
res = -1;
|
||||
retval = -1;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
fp = fopen(git_path_bisect_log(), "a");
|
||||
if (!fp) {
|
||||
res = error_errno(_("couldn't open the file '%s'"), git_path_bisect_log());
|
||||
retval = error_errno(_("couldn't open the file '%s'"), git_path_bisect_log());
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
|
@ -244,7 +243,7 @@ finish:
|
|||
if (fp)
|
||||
fclose(fp);
|
||||
strbuf_release(&tag);
|
||||
return res;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int check_and_set_terms(struct bisect_terms *terms, const char *cmd)
|
||||
|
|
@ -282,23 +281,35 @@ static int mark_good(const char *refname, const struct object_id *oid,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static const char need_bad_and_good_revision_warning[] =
|
||||
static const char *need_bad_and_good_revision_warning =
|
||||
N_("You need to give me at least one %s and %s revision.\n"
|
||||
"You can use \"git bisect %s\" and \"git bisect %s\" for that.");
|
||||
|
||||
static const char need_bisect_start_warning[] =
|
||||
static const char *need_bisect_start_warning =
|
||||
N_("You need to start by \"git bisect start\".\n"
|
||||
"You then need to give me at least one %s and %s revision.\n"
|
||||
"You can use \"git bisect %s\" and \"git bisect %s\" for that.");
|
||||
|
||||
static int decide_next(const struct bisect_terms *terms,
|
||||
const char *current_term, int missing_good,
|
||||
int missing_bad)
|
||||
static int bisect_next_check(const struct bisect_terms *terms,
|
||||
const char *current_term)
|
||||
{
|
||||
int missing_good = 1, missing_bad = 1, retval = 0;
|
||||
const char *bad_ref = xstrfmt("refs/bisect/%s", terms->term_bad);
|
||||
const char *good_glob = xstrfmt("%s-*", terms->term_good);
|
||||
|
||||
if (ref_exists(bad_ref))
|
||||
missing_bad = 0;
|
||||
|
||||
for_each_glob_ref_in(mark_good, good_glob, "refs/bisect/",
|
||||
(void *) &missing_good);
|
||||
|
||||
if (!missing_good && !missing_bad)
|
||||
return 0;
|
||||
if (!current_term)
|
||||
return -1;
|
||||
goto finish;
|
||||
|
||||
if (!current_term) {
|
||||
retval = -1;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (missing_good && !missing_bad &&
|
||||
!strcmp(current_term, terms->term_good)) {
|
||||
|
|
@ -309,7 +320,7 @@ static int decide_next(const struct bisect_terms *terms,
|
|||
*/
|
||||
warning(_("bisecting only with a %s commit"), terms->term_bad);
|
||||
if (!isatty(0))
|
||||
return 0;
|
||||
goto finish;
|
||||
/*
|
||||
* TRANSLATORS: Make sure to include [Y] and [n] in your
|
||||
* translation. The program will only accept English input
|
||||
|
|
@ -317,35 +328,21 @@ static int decide_next(const struct bisect_terms *terms,
|
|||
*/
|
||||
yesno = git_prompt(_("Are you sure [Y/n]? "), PROMPT_ECHO);
|
||||
if (starts_with(yesno, "N") || starts_with(yesno, "n"))
|
||||
return -1;
|
||||
return 0;
|
||||
retval = -1;
|
||||
goto finish;
|
||||
}
|
||||
if (!is_empty_or_missing_file(git_path_bisect_start())) {
|
||||
retval = error(_(need_bad_and_good_revision_warning),
|
||||
vocab_bad, vocab_good, vocab_bad, vocab_good);
|
||||
} else {
|
||||
retval = error(_(need_bisect_start_warning),
|
||||
vocab_good, vocab_bad, vocab_good, vocab_bad);
|
||||
}
|
||||
|
||||
if (!is_empty_or_missing_file(git_path_bisect_start()))
|
||||
return error(_(need_bad_and_good_revision_warning),
|
||||
vocab_bad, vocab_good, vocab_bad, vocab_good);
|
||||
else
|
||||
return error(_(need_bisect_start_warning),
|
||||
vocab_good, vocab_bad, vocab_good, vocab_bad);
|
||||
}
|
||||
|
||||
static int bisect_next_check(const struct bisect_terms *terms,
|
||||
const char *current_term)
|
||||
{
|
||||
int missing_good = 1, missing_bad = 1;
|
||||
char *bad_ref = xstrfmt("refs/bisect/%s", terms->term_bad);
|
||||
char *good_glob = xstrfmt("%s-*", terms->term_good);
|
||||
|
||||
if (ref_exists(bad_ref))
|
||||
missing_bad = 0;
|
||||
|
||||
for_each_glob_ref_in(mark_good, good_glob, "refs/bisect/",
|
||||
(void *) &missing_good);
|
||||
|
||||
free(good_glob);
|
||||
free(bad_ref);
|
||||
|
||||
return decide_next(terms, current_term, missing_good, missing_bad);
|
||||
finish:
|
||||
free((void *) good_glob);
|
||||
free((void *) bad_ref);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int get_terms(struct bisect_terms *terms)
|
||||
|
|
@ -399,7 +396,7 @@ static int bisect_terms(struct bisect_terms *terms, const char *option)
|
|||
|
||||
static int bisect_append_log_quoted(const char **argv)
|
||||
{
|
||||
int res = 0;
|
||||
int retval = 0;
|
||||
FILE *fp = fopen(git_path_bisect_log(), "a");
|
||||
struct strbuf orig_args = STRBUF_INIT;
|
||||
|
||||
|
|
@ -407,25 +404,25 @@ static int bisect_append_log_quoted(const char **argv)
|
|||
return -1;
|
||||
|
||||
if (fprintf(fp, "git bisect start") < 1) {
|
||||
res = -1;
|
||||
retval = -1;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
sq_quote_argv(&orig_args, argv);
|
||||
if (fprintf(fp, "%s\n", orig_args.buf) < 1)
|
||||
res = -1;
|
||||
retval = -1;
|
||||
|
||||
finish:
|
||||
fclose(fp);
|
||||
strbuf_release(&orig_args);
|
||||
return res;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int bisect_start(struct bisect_terms *terms, int no_checkout,
|
||||
const char **argv, int argc)
|
||||
{
|
||||
int i, has_double_dash = 0, must_write_terms = 0, bad_seen = 0;
|
||||
int flags, pathspec_pos, res = 0;
|
||||
int flags, pathspec_pos, retval = 0;
|
||||
struct string_list revs = STRING_LIST_INIT_DUP;
|
||||
struct string_list states = STRING_LIST_INIT_DUP;
|
||||
struct strbuf start_head = STRBUF_INIT;
|
||||
|
|
@ -526,7 +523,7 @@ static int bisect_start(struct bisect_terms *terms, int no_checkout,
|
|||
argv_array_pushl(&argv, "checkout", start_head.buf,
|
||||
"--", NULL);
|
||||
if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {
|
||||
res = error(_("checking out '%s' failed."
|
||||
retval = error(_("checking out '%s' failed."
|
||||
" Try 'git bisect start "
|
||||
"<valid-branch>'."),
|
||||
start_head.buf);
|
||||
|
|
@ -574,12 +571,12 @@ static int bisect_start(struct bisect_terms *terms, int no_checkout,
|
|||
|
||||
if (no_checkout) {
|
||||
if (get_oid(start_head.buf, &oid) < 0) {
|
||||
res = error(_("invalid ref: '%s'"), start_head.buf);
|
||||
retval = error(_("invalid ref: '%s'"), start_head.buf);
|
||||
goto finish;
|
||||
}
|
||||
if (update_ref(NULL, "BISECT_HEAD", &oid, NULL, 0,
|
||||
UPDATE_REFS_MSG_ON_ERR)) {
|
||||
res = -1;
|
||||
retval = -1;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
|
@ -591,26 +588,26 @@ static int bisect_start(struct bisect_terms *terms, int no_checkout,
|
|||
for (i = 0; i < states.nr; i++)
|
||||
if (bisect_write(states.items[i].string,
|
||||
revs.items[i].string, terms, 1)) {
|
||||
res = -1;
|
||||
retval = -1;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (must_write_terms && write_terms(terms->term_bad,
|
||||
terms->term_good)) {
|
||||
res = -1;
|
||||
retval = -1;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
res = bisect_append_log_quoted(argv);
|
||||
if (res)
|
||||
res = -1;
|
||||
retval = bisect_append_log_quoted(argv);
|
||||
if (retval)
|
||||
retval = -1;
|
||||
|
||||
finish:
|
||||
string_list_clear(&revs, 0);
|
||||
string_list_clear(&states, 0);
|
||||
strbuf_release(&start_head);
|
||||
strbuf_release(&bisect_names);
|
||||
return res;
|
||||
return retval;
|
||||
}
|
||||
|
||||
int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
|
||||
|
|
@ -666,8 +663,7 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
|
|||
|
||||
switch (cmdmode) {
|
||||
case NEXT_ALL:
|
||||
res = bisect_next_all(the_repository, prefix, no_checkout);
|
||||
break;
|
||||
return bisect_next_all(the_repository, prefix, no_checkout);
|
||||
case WRITE_TERMS:
|
||||
if (argc != 2)
|
||||
return error(_("--write-terms requires two arguments"));
|
||||
|
|
@ -714,13 +710,5 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
|
|||
return error("BUG: unknown subcommand '%d'", cmdmode);
|
||||
}
|
||||
free_terms(&terms);
|
||||
|
||||
/*
|
||||
* Handle early success
|
||||
* From check_merge_bases > check_good_are_ancestors_of_bad > bisect_next_all
|
||||
*/
|
||||
if (res == BISECT_INTERNAL_SUCCESS_MERGE_BASE)
|
||||
res = BISECT_OK;
|
||||
|
||||
return abs(res);
|
||||
return !!res;
|
||||
}
|
||||
|
|
|
|||
40
third_party/git/builtin/blame.c
vendored
40
third_party/git/builtin/blame.c
vendored
|
|
@ -26,6 +26,7 @@
|
|||
#include "progress.h"
|
||||
#include "object-store.h"
|
||||
#include "blame.h"
|
||||
#include "string-list.h"
|
||||
#include "refs.h"
|
||||
|
||||
static char blame_usage[] = N_("git blame [<options>] [<rev-opts>] [<rev>] [--] <file>");
|
||||
|
|
@ -319,18 +320,18 @@ static const char *format_time(timestamp_t time, const char *tz_str,
|
|||
return time_buf.buf;
|
||||
}
|
||||
|
||||
#define OUTPUT_ANNOTATE_COMPAT (1U<<0)
|
||||
#define OUTPUT_LONG_OBJECT_NAME (1U<<1)
|
||||
#define OUTPUT_RAW_TIMESTAMP (1U<<2)
|
||||
#define OUTPUT_PORCELAIN (1U<<3)
|
||||
#define OUTPUT_SHOW_NAME (1U<<4)
|
||||
#define OUTPUT_SHOW_NUMBER (1U<<5)
|
||||
#define OUTPUT_SHOW_SCORE (1U<<6)
|
||||
#define OUTPUT_NO_AUTHOR (1U<<7)
|
||||
#define OUTPUT_SHOW_EMAIL (1U<<8)
|
||||
#define OUTPUT_LINE_PORCELAIN (1U<<9)
|
||||
#define OUTPUT_COLOR_LINE (1U<<10)
|
||||
#define OUTPUT_SHOW_AGE_WITH_COLOR (1U<<11)
|
||||
#define OUTPUT_ANNOTATE_COMPAT 001
|
||||
#define OUTPUT_LONG_OBJECT_NAME 002
|
||||
#define OUTPUT_RAW_TIMESTAMP 004
|
||||
#define OUTPUT_PORCELAIN 010
|
||||
#define OUTPUT_SHOW_NAME 020
|
||||
#define OUTPUT_SHOW_NUMBER 040
|
||||
#define OUTPUT_SHOW_SCORE 0100
|
||||
#define OUTPUT_NO_AUTHOR 0200
|
||||
#define OUTPUT_SHOW_EMAIL 0400
|
||||
#define OUTPUT_LINE_PORCELAIN 01000
|
||||
#define OUTPUT_COLOR_LINE 02000
|
||||
#define OUTPUT_SHOW_AGE_WITH_COLOR 04000
|
||||
|
||||
static void emit_porcelain_details(struct blame_origin *suspect, int repeat)
|
||||
{
|
||||
|
|
@ -459,7 +460,7 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int
|
|||
|
||||
for (cnt = 0; cnt < ent->num_lines; cnt++) {
|
||||
char ch;
|
||||
int length = (opt & OUTPUT_LONG_OBJECT_NAME) ? the_hash_algo->hexsz : abbrev;
|
||||
int length = (opt & OUTPUT_LONG_OBJECT_NAME) ? GIT_SHA1_HEXSZ : abbrev;
|
||||
|
||||
if (opt & OUTPUT_COLOR_LINE) {
|
||||
if (cnt > 0) {
|
||||
|
|
@ -861,6 +862,14 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
|
|||
OPT_STRING_LIST(0, "ignore-revs-file", &ignore_revs_file_list, N_("file"), N_("Ignore revisions from <file>")),
|
||||
OPT_BIT(0, "color-lines", &output_option, N_("color redundant metadata from previous line differently"), OUTPUT_COLOR_LINE),
|
||||
OPT_BIT(0, "color-by-age", &output_option, N_("color lines by age"), OUTPUT_SHOW_AGE_WITH_COLOR),
|
||||
|
||||
/*
|
||||
* The following two options are parsed by parse_revision_opt()
|
||||
* and are only included here to get included in the "-h"
|
||||
* output:
|
||||
*/
|
||||
{ OPTION_LOWLEVEL_CALLBACK, 0, "indent-heuristic", NULL, NULL, N_("Use an experimental heuristic to improve diffs"), PARSE_OPT_NOARG, NULL, 0, parse_opt_unknown_cb },
|
||||
|
||||
OPT_BIT(0, "minimal", &xdl_opts, N_("Spend extra cycles to find better match"), XDF_NEED_MINIMAL),
|
||||
OPT_STRING('S', NULL, &revs_file, N_("file"), N_("Use revisions from <file> instead of calling git-rev-list")),
|
||||
OPT_STRING(0, "contents", &contents_from, N_("file"), N_("Use <file>'s contents as the final image")),
|
||||
|
|
@ -876,7 +885,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
|
|||
struct range_set ranges;
|
||||
unsigned int range_i;
|
||||
long anchor;
|
||||
const int hexsz = the_hash_algo->hexsz;
|
||||
|
||||
setup_default_color_by_age();
|
||||
git_config(git_blame_config, &output_option);
|
||||
|
|
@ -923,11 +931,11 @@ parse_done:
|
|||
} else if (show_progress < 0)
|
||||
show_progress = isatty(2);
|
||||
|
||||
if (0 < abbrev && abbrev < hexsz)
|
||||
if (0 < abbrev && abbrev < GIT_SHA1_HEXSZ)
|
||||
/* one more abbrev length is needed for the boundary commit */
|
||||
abbrev++;
|
||||
else if (!abbrev)
|
||||
abbrev = hexsz;
|
||||
abbrev = GIT_SHA1_HEXSZ;
|
||||
|
||||
if (revs_file && read_ancestry(revs_file))
|
||||
die_errno("reading graft file '%s' failed", revs_file);
|
||||
|
|
|
|||
2
third_party/git/builtin/branch.c
vendored
2
third_party/git/builtin/branch.c
vendored
|
|
@ -624,7 +624,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
|
|||
OPT_SET_INT_F(0, "set-upstream", &track, N_("do not use"),
|
||||
BRANCH_TRACK_OVERRIDE, PARSE_OPT_HIDDEN),
|
||||
OPT_STRING('u', "set-upstream-to", &new_upstream, N_("upstream"), N_("change the upstream info")),
|
||||
OPT_BOOL(0, "unset-upstream", &unset_upstream, N_("unset the upstream info")),
|
||||
OPT_BOOL(0, "unset-upstream", &unset_upstream, N_("Unset the upstream info")),
|
||||
OPT__COLOR(&branch_use_color, N_("use colored output")),
|
||||
OPT_SET_INT('r', "remotes", &filter.kind, N_("act on remote-tracking branches"),
|
||||
FILTER_REFS_REMOTES),
|
||||
|
|
|
|||
221
third_party/git/builtin/bundle.c
vendored
221
third_party/git/builtin/bundle.c
vendored
|
|
@ -1,6 +1,4 @@
|
|||
#include "builtin.h"
|
||||
#include "argv-array.h"
|
||||
#include "parse-options.h"
|
||||
#include "cache.h"
|
||||
#include "bundle.h"
|
||||
|
||||
|
|
@ -11,184 +9,59 @@
|
|||
* bundle supporting "fetch", "pull", and "ls-remote".
|
||||
*/
|
||||
|
||||
static const char * const builtin_bundle_usage[] = {
|
||||
N_("git bundle create [<options>] <file> <git-rev-list args>"),
|
||||
N_("git bundle verify [<options>] <file>"),
|
||||
N_("git bundle list-heads <file> [<refname>...]"),
|
||||
N_("git bundle unbundle <file> [<refname>...]"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char * const builtin_bundle_create_usage[] = {
|
||||
N_("git bundle create [<options>] <file> <git-rev-list args>"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char * const builtin_bundle_verify_usage[] = {
|
||||
N_("git bundle verify [<options>] <file>"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char * const builtin_bundle_list_heads_usage[] = {
|
||||
N_("git bundle list-heads <file> [<refname>...]"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char * const builtin_bundle_unbundle_usage[] = {
|
||||
N_("git bundle unbundle <file> [<refname>...]"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static int verbose;
|
||||
|
||||
static int parse_options_cmd_bundle(int argc,
|
||||
const char **argv,
|
||||
const char* prefix,
|
||||
const char * const usagestr[],
|
||||
const struct option options[],
|
||||
const char **bundle_file) {
|
||||
int newargc;
|
||||
newargc = parse_options(argc, argv, NULL, options, usagestr,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
if (argc < 1)
|
||||
usage_with_options(usagestr, options);
|
||||
*bundle_file = prefix_filename(prefix, argv[0]);
|
||||
return newargc;
|
||||
}
|
||||
|
||||
static int cmd_bundle_create(int argc, const char **argv, const char *prefix) {
|
||||
int all_progress_implied = 0;
|
||||
int progress = isatty(STDERR_FILENO);
|
||||
struct argv_array pack_opts;
|
||||
|
||||
struct option options[] = {
|
||||
OPT_SET_INT('q', "quiet", &progress,
|
||||
N_("do not show progress meter"), 0),
|
||||
OPT_SET_INT(0, "progress", &progress,
|
||||
N_("show progress meter"), 1),
|
||||
OPT_SET_INT(0, "all-progress", &progress,
|
||||
N_("show progress meter during object writing phase"), 2),
|
||||
OPT_BOOL(0, "all-progress-implied",
|
||||
&all_progress_implied,
|
||||
N_("similar to --all-progress when progress meter is shown")),
|
||||
OPT_END()
|
||||
};
|
||||
const char* bundle_file;
|
||||
|
||||
argc = parse_options_cmd_bundle(argc, argv, prefix,
|
||||
builtin_bundle_create_usage, options, &bundle_file);
|
||||
/* bundle internals use argv[1] as further parameters */
|
||||
|
||||
argv_array_init(&pack_opts);
|
||||
if (progress == 0)
|
||||
argv_array_push(&pack_opts, "--quiet");
|
||||
else if (progress == 1)
|
||||
argv_array_push(&pack_opts, "--progress");
|
||||
else if (progress == 2)
|
||||
argv_array_push(&pack_opts, "--all-progress");
|
||||
if (progress && all_progress_implied)
|
||||
argv_array_push(&pack_opts, "--all-progress-implied");
|
||||
|
||||
if (!startup_info->have_repository)
|
||||
die(_("Need a repository to create a bundle."));
|
||||
return !!create_bundle(the_repository, bundle_file, argc, argv, &pack_opts);
|
||||
}
|
||||
|
||||
static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) {
|
||||
struct bundle_header header;
|
||||
int bundle_fd = -1;
|
||||
int quiet = 0;
|
||||
|
||||
struct option options[] = {
|
||||
OPT_BOOL('q', "quiet", &quiet,
|
||||
N_("do not show bundle details")),
|
||||
OPT_END()
|
||||
};
|
||||
const char* bundle_file;
|
||||
|
||||
argc = parse_options_cmd_bundle(argc, argv, prefix,
|
||||
builtin_bundle_verify_usage, options, &bundle_file);
|
||||
/* bundle internals use argv[1] as further parameters */
|
||||
|
||||
memset(&header, 0, sizeof(header));
|
||||
if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0)
|
||||
return 1;
|
||||
close(bundle_fd);
|
||||
if (verify_bundle(the_repository, &header, !quiet))
|
||||
return 1;
|
||||
fprintf(stderr, _("%s is okay\n"), bundle_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix) {
|
||||
struct bundle_header header;
|
||||
int bundle_fd = -1;
|
||||
|
||||
struct option options[] = {
|
||||
OPT_END()
|
||||
};
|
||||
const char* bundle_file;
|
||||
|
||||
argc = parse_options_cmd_bundle(argc, argv, prefix,
|
||||
builtin_bundle_list_heads_usage, options, &bundle_file);
|
||||
/* bundle internals use argv[1] as further parameters */
|
||||
|
||||
memset(&header, 0, sizeof(header));
|
||||
if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0)
|
||||
return 1;
|
||||
close(bundle_fd);
|
||||
return !!list_bundle_refs(&header, argc, argv);
|
||||
}
|
||||
|
||||
static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix) {
|
||||
struct bundle_header header;
|
||||
int bundle_fd = -1;
|
||||
|
||||
struct option options[] = {
|
||||
OPT_END()
|
||||
};
|
||||
const char* bundle_file;
|
||||
|
||||
argc = parse_options_cmd_bundle(argc, argv, prefix,
|
||||
builtin_bundle_unbundle_usage, options, &bundle_file);
|
||||
/* bundle internals use argv[1] as further parameters */
|
||||
|
||||
memset(&header, 0, sizeof(header));
|
||||
if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0)
|
||||
return 1;
|
||||
if (!startup_info->have_repository)
|
||||
die(_("Need a repository to unbundle."));
|
||||
return !!unbundle(the_repository, &header, bundle_fd, 0) ||
|
||||
list_bundle_refs(&header, argc, argv);
|
||||
}
|
||||
static const char builtin_bundle_usage[] =
|
||||
"git bundle create <file> <git-rev-list args>\n"
|
||||
" or: git bundle verify <file>\n"
|
||||
" or: git bundle list-heads <file> [<refname>...]\n"
|
||||
" or: git bundle unbundle <file> [<refname>...]";
|
||||
|
||||
int cmd_bundle(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct option options[] = {
|
||||
OPT__VERBOSE(&verbose, N_("be verbose; must be placed before a subcommand")),
|
||||
OPT_END()
|
||||
};
|
||||
int result;
|
||||
struct bundle_header header;
|
||||
const char *cmd, *bundle_file;
|
||||
int bundle_fd = -1;
|
||||
|
||||
argc = parse_options(argc, argv, prefix, options, builtin_bundle_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
if (argc < 3)
|
||||
usage(builtin_bundle_usage);
|
||||
|
||||
packet_trace_identity("bundle");
|
||||
cmd = argv[1];
|
||||
bundle_file = prefix_filename(prefix, argv[2]);
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
|
||||
if (argc < 2)
|
||||
usage_with_options(builtin_bundle_usage, options);
|
||||
memset(&header, 0, sizeof(header));
|
||||
if (strcmp(cmd, "create") && (bundle_fd =
|
||||
read_bundle_header(bundle_file, &header)) < 0)
|
||||
return 1;
|
||||
|
||||
else if (!strcmp(argv[0], "create"))
|
||||
result = cmd_bundle_create(argc, argv, prefix);
|
||||
else if (!strcmp(argv[0], "verify"))
|
||||
result = cmd_bundle_verify(argc, argv, prefix);
|
||||
else if (!strcmp(argv[0], "list-heads"))
|
||||
result = cmd_bundle_list_heads(argc, argv, prefix);
|
||||
else if (!strcmp(argv[0], "unbundle"))
|
||||
result = cmd_bundle_unbundle(argc, argv, prefix);
|
||||
else {
|
||||
error(_("Unknown subcommand: %s"), argv[0]);
|
||||
usage_with_options(builtin_bundle_usage, options);
|
||||
if (!strcmp(cmd, "verify")) {
|
||||
close(bundle_fd);
|
||||
if (argc != 1) {
|
||||
usage(builtin_bundle_usage);
|
||||
return 1;
|
||||
}
|
||||
if (verify_bundle(the_repository, &header, 1))
|
||||
return 1;
|
||||
fprintf(stderr, _("%s is okay\n"), bundle_file);
|
||||
return 0;
|
||||
}
|
||||
return result ? 1 : 0;
|
||||
if (!strcmp(cmd, "list-heads")) {
|
||||
close(bundle_fd);
|
||||
return !!list_bundle_refs(&header, argc, argv);
|
||||
}
|
||||
if (!strcmp(cmd, "create")) {
|
||||
if (argc < 2) {
|
||||
usage(builtin_bundle_usage);
|
||||
return 1;
|
||||
}
|
||||
if (!startup_info->have_repository)
|
||||
die(_("Need a repository to create a bundle."));
|
||||
return !!create_bundle(the_repository, bundle_file, argc, argv);
|
||||
} else if (!strcmp(cmd, "unbundle")) {
|
||||
if (!startup_info->have_repository)
|
||||
die(_("Need a repository to unbundle."));
|
||||
return !!unbundle(the_repository, &header, bundle_fd, 0) ||
|
||||
list_bundle_refs(&header, argc, argv);
|
||||
} else
|
||||
usage(builtin_bundle_usage);
|
||||
}
|
||||
|
|
|
|||
7
third_party/git/builtin/cat-file.c
vendored
7
third_party/git/builtin/cat-file.c
vendored
|
|
@ -15,7 +15,6 @@
|
|||
#include "sha1-array.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
#include "promisor-remote.h"
|
||||
|
||||
struct batch_options {
|
||||
int enabled;
|
||||
|
|
@ -262,7 +261,7 @@ static void expand_atom(struct strbuf *sb, const char *atom, int len,
|
|||
strbuf_addstr(sb, data->rest);
|
||||
} else if (is_atom("deltabase", atom, len)) {
|
||||
if (data->mark_query)
|
||||
data->info.delta_base_oid = &data->delta_base_oid;
|
||||
data->info.delta_base_sha1 = data->delta_base_oid.hash;
|
||||
else
|
||||
strbuf_addstr(sb,
|
||||
oid_to_hex(&data->delta_base_oid));
|
||||
|
|
@ -525,8 +524,8 @@ static int batch_objects(struct batch_options *opt)
|
|||
if (opt->all_objects) {
|
||||
struct object_cb_data cb;
|
||||
|
||||
if (has_promisor_remote())
|
||||
warning("This repository uses promisor remotes. Some objects may not be loaded.");
|
||||
if (repository_format_partial_clone)
|
||||
warning("This repository has extensions.partialClone set. Some objects may not be loaded.");
|
||||
|
||||
cb.opt = opt;
|
||||
cb.expand = &data;
|
||||
|
|
|
|||
37
third_party/git/builtin/check-ignore.c
vendored
37
third_party/git/builtin/check-ignore.c
vendored
|
|
@ -32,19 +32,19 @@ static const struct option check_ignore_options[] = {
|
|||
OPT_END()
|
||||
};
|
||||
|
||||
static void output_pattern(const char *path, struct path_pattern *pattern)
|
||||
static void output_exclude(const char *path, struct exclude *exclude)
|
||||
{
|
||||
char *bang = (pattern && pattern->flags & PATTERN_FLAG_NEGATIVE) ? "!" : "";
|
||||
char *slash = (pattern && pattern->flags & PATTERN_FLAG_MUSTBEDIR) ? "/" : "";
|
||||
char *bang = (exclude && exclude->flags & EXC_FLAG_NEGATIVE) ? "!" : "";
|
||||
char *slash = (exclude && exclude->flags & EXC_FLAG_MUSTBEDIR) ? "/" : "";
|
||||
if (!nul_term_line) {
|
||||
if (!verbose) {
|
||||
write_name_quoted(path, stdout, '\n');
|
||||
} else {
|
||||
if (pattern) {
|
||||
quote_c_style(pattern->pl->src, NULL, stdout, 0);
|
||||
if (exclude) {
|
||||
quote_c_style(exclude->el->src, NULL, stdout, 0);
|
||||
printf(":%d:%s%s%s\t",
|
||||
pattern->srcpos,
|
||||
bang, pattern->pattern, slash);
|
||||
exclude->srcpos,
|
||||
bang, exclude->pattern, slash);
|
||||
}
|
||||
else {
|
||||
printf("::\t");
|
||||
|
|
@ -56,11 +56,11 @@ static void output_pattern(const char *path, struct path_pattern *pattern)
|
|||
if (!verbose) {
|
||||
printf("%s%c", path, '\0');
|
||||
} else {
|
||||
if (pattern)
|
||||
if (exclude)
|
||||
printf("%s%c%d%c%s%s%s%c%s%c",
|
||||
pattern->pl->src, '\0',
|
||||
pattern->srcpos, '\0',
|
||||
bang, pattern->pattern, slash, '\0',
|
||||
exclude->el->src, '\0',
|
||||
exclude->srcpos, '\0',
|
||||
bang, exclude->pattern, slash, '\0',
|
||||
path, '\0');
|
||||
else
|
||||
printf("%c%c%c%s%c", '\0', '\0', '\0', path, '\0');
|
||||
|
|
@ -74,7 +74,7 @@ static int check_ignore(struct dir_struct *dir,
|
|||
const char *full_path;
|
||||
char *seen;
|
||||
int num_ignored = 0, i;
|
||||
struct path_pattern *pattern;
|
||||
struct exclude *exclude;
|
||||
struct pathspec pathspec;
|
||||
|
||||
if (!argc) {
|
||||
|
|
@ -103,18 +103,15 @@ static int check_ignore(struct dir_struct *dir,
|
|||
seen = find_pathspecs_matching_against_index(&pathspec, &the_index);
|
||||
for (i = 0; i < pathspec.nr; i++) {
|
||||
full_path = pathspec.items[i].match;
|
||||
pattern = NULL;
|
||||
exclude = NULL;
|
||||
if (!seen[i]) {
|
||||
int dtype = DT_UNKNOWN;
|
||||
pattern = last_matching_pattern(dir, &the_index,
|
||||
exclude = last_exclude_matching(dir, &the_index,
|
||||
full_path, &dtype);
|
||||
if (!verbose && pattern &&
|
||||
pattern->flags & PATTERN_FLAG_NEGATIVE)
|
||||
pattern = NULL;
|
||||
}
|
||||
if (!quiet && (pattern || show_non_matching))
|
||||
output_pattern(pathspec.items[i].original, pattern);
|
||||
if (pattern)
|
||||
if (!quiet && (exclude || show_non_matching))
|
||||
output_exclude(pathspec.items[i].original, exclude);
|
||||
if (exclude)
|
||||
num_ignored++;
|
||||
}
|
||||
free(seen);
|
||||
|
|
|
|||
137
third_party/git/builtin/checkout.c
vendored
137
third_party/git/builtin/checkout.c
vendored
|
|
@ -70,8 +70,6 @@ struct checkout_opts {
|
|||
int checkout_worktree;
|
||||
const char *ignore_unmerged_opt;
|
||||
int ignore_unmerged;
|
||||
int pathspec_file_nul;
|
||||
const char *pathspec_from_file;
|
||||
|
||||
const char *new_branch;
|
||||
const char *new_branch_force;
|
||||
|
|
@ -128,7 +126,6 @@ static int update_some(const struct object_id *oid, struct strbuf *base,
|
|||
if (pos >= 0) {
|
||||
struct cache_entry *old = active_cache[pos];
|
||||
if (ce->ce_mode == old->ce_mode &&
|
||||
!ce_intent_to_add(old) &&
|
||||
oideq(&ce->oid, &old->oid)) {
|
||||
old->ce_flags |= CE_UPDATE;
|
||||
discard_cache_entry(ce);
|
||||
|
|
@ -524,8 +521,6 @@ static int checkout_paths(const struct checkout_opts *opts,
|
|||
/* Now we are committed to check them out */
|
||||
if (opts->checkout_worktree)
|
||||
errs |= checkout_worktree(opts);
|
||||
else
|
||||
remove_marked_cache_entries(&the_index, 1);
|
||||
|
||||
/*
|
||||
* Allow updating the index when checking out from the index.
|
||||
|
|
@ -713,11 +708,11 @@ static int merge_working_tree(const struct checkout_opts *opts,
|
|||
* give up or do a real merge, depending on
|
||||
* whether the merge flag was used.
|
||||
*/
|
||||
struct tree *result;
|
||||
struct tree *work;
|
||||
struct tree *old_tree;
|
||||
struct merge_options o;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
struct strbuf old_commit_shortname = STRBUF_INIT;
|
||||
|
||||
if (!opts->merge)
|
||||
return 1;
|
||||
|
|
@ -735,6 +730,13 @@ static int merge_working_tree(const struct checkout_opts *opts,
|
|||
"the following files:\n%s"), sb.buf);
|
||||
strbuf_release(&sb);
|
||||
|
||||
if (repo_index_has_changes(the_repository,
|
||||
get_commit_tree(old_branch_info->commit),
|
||||
&sb))
|
||||
warning(_("staged changes in the following files may be lost: %s"),
|
||||
sb.buf);
|
||||
strbuf_release(&sb);
|
||||
|
||||
/* Do more real merge */
|
||||
|
||||
/*
|
||||
|
|
@ -758,7 +760,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
|
|||
*/
|
||||
init_merge_options(&o, the_repository);
|
||||
o.verbosity = 0;
|
||||
work = write_in_core_index_as_tree(the_repository);
|
||||
work = write_tree_from_memory(&o);
|
||||
|
||||
ret = reset_tree(new_tree,
|
||||
opts, 1,
|
||||
|
|
@ -766,25 +768,19 @@ static int merge_working_tree(const struct checkout_opts *opts,
|
|||
if (ret)
|
||||
return ret;
|
||||
o.ancestor = old_branch_info->name;
|
||||
if (old_branch_info->name == NULL) {
|
||||
strbuf_add_unique_abbrev(&old_commit_shortname,
|
||||
&old_branch_info->commit->object.oid,
|
||||
DEFAULT_ABBREV);
|
||||
o.ancestor = old_commit_shortname.buf;
|
||||
}
|
||||
o.branch1 = new_branch_info->name;
|
||||
o.branch2 = "local";
|
||||
ret = merge_trees(&o,
|
||||
new_tree,
|
||||
work,
|
||||
old_tree);
|
||||
old_tree,
|
||||
&result);
|
||||
if (ret < 0)
|
||||
exit(128);
|
||||
ret = reset_tree(new_tree,
|
||||
opts, 0,
|
||||
writeout_error);
|
||||
strbuf_release(&o.obuf);
|
||||
strbuf_release(&old_commit_shortname);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -865,7 +861,7 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
|
|||
strbuf_addf(&msg, "checkout: moving from %s to %s",
|
||||
old_desc ? old_desc : "(invalid)", new_branch_info->name);
|
||||
else
|
||||
strbuf_insertstr(&msg, 0, reflog_msg);
|
||||
strbuf_insert(&msg, 0, reflog_msg, strlen(reflog_msg));
|
||||
|
||||
if (!strcmp(new_branch_info->name, "HEAD") && !new_branch_info->path && !opts->force_detach) {
|
||||
/* Nothing to do. */
|
||||
|
|
@ -1117,43 +1113,12 @@ static void setup_new_branch_info_and_source_tree(
|
|||
}
|
||||
}
|
||||
|
||||
static const char *parse_remote_branch(const char *arg,
|
||||
struct object_id *rev,
|
||||
int could_be_checkout_paths)
|
||||
{
|
||||
int num_matches = 0;
|
||||
const char *remote = unique_tracking_name(arg, rev, &num_matches);
|
||||
|
||||
if (remote && could_be_checkout_paths) {
|
||||
die(_("'%s' could be both a local file and a tracking branch.\n"
|
||||
"Please use -- (and optionally --no-guess) to disambiguate"),
|
||||
arg);
|
||||
}
|
||||
|
||||
if (!remote && num_matches > 1) {
|
||||
if (advice_checkout_ambiguous_remote_branch_name) {
|
||||
advise(_("If you meant to check out a remote tracking branch on, e.g. 'origin',\n"
|
||||
"you can do so by fully qualifying the name with the --track option:\n"
|
||||
"\n"
|
||||
" git checkout --track origin/<name>\n"
|
||||
"\n"
|
||||
"If you'd like to always have checkouts of an ambiguous <name> prefer\n"
|
||||
"one remote, e.g. the 'origin' remote, consider setting\n"
|
||||
"checkout.defaultRemote=origin in your config."));
|
||||
}
|
||||
|
||||
die(_("'%s' matched multiple (%d) remote tracking branches"),
|
||||
arg, num_matches);
|
||||
}
|
||||
|
||||
return remote;
|
||||
}
|
||||
|
||||
static int parse_branchname_arg(int argc, const char **argv,
|
||||
int dwim_new_local_branch_ok,
|
||||
struct branch_info *new_branch_info,
|
||||
struct checkout_opts *opts,
|
||||
struct object_id *rev)
|
||||
struct object_id *rev,
|
||||
int *dwim_remotes_matched)
|
||||
{
|
||||
const char **new_branch = &opts->new_branch;
|
||||
int argcount = 0;
|
||||
|
|
@ -1258,9 +1223,13 @@ static int parse_branchname_arg(int argc, const char **argv,
|
|||
recover_with_dwim = 0;
|
||||
|
||||
if (recover_with_dwim) {
|
||||
const char *remote = parse_remote_branch(arg, rev,
|
||||
could_be_checkout_paths);
|
||||
const char *remote = unique_tracking_name(arg, rev,
|
||||
dwim_remotes_matched);
|
||||
if (remote) {
|
||||
if (could_be_checkout_paths)
|
||||
die(_("'%s' could be both a local file and a tracking branch.\n"
|
||||
"Please use -- (and optionally --no-guess) to disambiguate"),
|
||||
arg);
|
||||
*new_branch = arg;
|
||||
arg = remote;
|
||||
/* DWIMmed to create local branch, case (3).(b) */
|
||||
|
|
@ -1511,8 +1480,6 @@ static struct option *add_checkout_path_options(struct checkout_opts *opts,
|
|||
OPT_BOOL('p', "patch", &opts->patch_mode, N_("select hunks interactively")),
|
||||
OPT_BOOL(0, "ignore-skip-worktree-bits", &opts->ignore_skipworktree,
|
||||
N_("do not limit pathspecs to sparse entries only")),
|
||||
OPT_PATHSPEC_FROM_FILE(&opts->pathspec_from_file),
|
||||
OPT_PATHSPEC_FILE_NUL(&opts->pathspec_file_nul),
|
||||
OPT_END()
|
||||
};
|
||||
struct option *newopts = parse_options_concat(prevopts, options);
|
||||
|
|
@ -1525,6 +1492,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
|
|||
const char * const usagestr[])
|
||||
{
|
||||
struct branch_info new_branch_info;
|
||||
int dwim_remotes_matched = 0;
|
||||
int parseopt_flags = 0;
|
||||
|
||||
memset(&new_branch_info, 0, sizeof(new_branch_info));
|
||||
|
|
@ -1632,7 +1600,8 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
|
|||
opts->track == BRANCH_TRACK_UNSPECIFIED &&
|
||||
!opts->new_branch;
|
||||
int n = parse_branchname_arg(argc, argv, dwim_ok,
|
||||
&new_branch_info, opts, &rev);
|
||||
&new_branch_info, opts, &rev,
|
||||
&dwim_remotes_matched);
|
||||
argv += n;
|
||||
argc -= n;
|
||||
} else if (!opts->accept_ref && opts->from_treeish) {
|
||||
|
|
@ -1649,6 +1618,10 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
|
|||
die(_("reference is not a tree: %s"), opts->from_treeish);
|
||||
}
|
||||
|
||||
if (opts->accept_pathspec && !opts->empty_pathspec_ok && !argc &&
|
||||
!opts->patch_mode) /* patch mode is special */
|
||||
die(_("you must specify path(s) to restore"));
|
||||
|
||||
if (argc) {
|
||||
parse_pathspec(&opts->pathspec, 0,
|
||||
opts->patch_mode ? PATHSPEC_PREFIX_ORIGIN : 0,
|
||||
|
|
@ -1668,33 +1641,10 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
|
|||
if (opts->force_detach)
|
||||
die(_("git checkout: --detach does not take a path argument '%s'"),
|
||||
argv[0]);
|
||||
}
|
||||
|
||||
if (opts->pathspec_from_file) {
|
||||
if (opts->pathspec.nr)
|
||||
die(_("--pathspec-from-file is incompatible with pathspec arguments"));
|
||||
|
||||
if (opts->force_detach)
|
||||
die(_("--pathspec-from-file is incompatible with --detach"));
|
||||
|
||||
if (opts->patch_mode)
|
||||
die(_("--pathspec-from-file is incompatible with --patch"));
|
||||
|
||||
parse_pathspec_file(&opts->pathspec, 0,
|
||||
0,
|
||||
prefix, opts->pathspec_from_file, opts->pathspec_file_nul);
|
||||
} else if (opts->pathspec_file_nul) {
|
||||
die(_("--pathspec-file-nul requires --pathspec-from-file"));
|
||||
}
|
||||
|
||||
if (opts->pathspec.nr) {
|
||||
if (1 < !!opts->writeout_stage + !!opts->force + !!opts->merge)
|
||||
die(_("git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
|
||||
"checking out of the index."));
|
||||
} else {
|
||||
if (opts->accept_pathspec && !opts->empty_pathspec_ok &&
|
||||
!opts->patch_mode) /* patch mode is special */
|
||||
die(_("you must specify path(s) to restore"));
|
||||
}
|
||||
|
||||
if (opts->new_branch) {
|
||||
|
|
@ -1709,10 +1659,28 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
|
|||
}
|
||||
|
||||
UNLEAK(opts);
|
||||
if (opts->patch_mode || opts->pathspec.nr)
|
||||
return checkout_paths(opts, new_branch_info.name);
|
||||
else
|
||||
if (opts->patch_mode || opts->pathspec.nr) {
|
||||
int ret = checkout_paths(opts, new_branch_info.name);
|
||||
if (ret && dwim_remotes_matched > 1 &&
|
||||
advice_checkout_ambiguous_remote_branch_name)
|
||||
advise(_("'%s' matched more than one remote tracking branch.\n"
|
||||
"We found %d remotes with a reference that matched. So we fell back\n"
|
||||
"on trying to resolve the argument as a path, but failed there too!\n"
|
||||
"\n"
|
||||
"If you meant to check out a remote tracking branch on, e.g. 'origin',\n"
|
||||
"you can do so by fully qualifying the name with the --track option:\n"
|
||||
"\n"
|
||||
" git checkout --track origin/<name>\n"
|
||||
"\n"
|
||||
"If you'd like to always have checkouts of an ambiguous <name> prefer\n"
|
||||
"one remote, e.g. the 'origin' remote, consider setting\n"
|
||||
"checkout.defaultRemote=origin in your config."),
|
||||
argv[0],
|
||||
dwim_remotes_matched);
|
||||
return ret;
|
||||
} else {
|
||||
return checkout_branch(opts, &new_branch_info);
|
||||
}
|
||||
}
|
||||
|
||||
int cmd_checkout(int argc, const char **argv, const char *prefix)
|
||||
|
|
@ -1746,15 +1714,6 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
|
|||
opts.checkout_index = -2; /* default on */
|
||||
opts.checkout_worktree = -2; /* default on */
|
||||
|
||||
if (argc == 3 && !strcmp(argv[1], "-b")) {
|
||||
/*
|
||||
* User ran 'git checkout -b <branch>' and expects
|
||||
* the same behavior as 'git switch -c <branch>'.
|
||||
*/
|
||||
opts.switch_branch_doing_nothing_is_ok = 0;
|
||||
opts.only_merge_on_switching_branches = 1;
|
||||
}
|
||||
|
||||
options = parse_options_dup(checkout_options);
|
||||
options = add_common_options(&opts, options);
|
||||
options = add_common_switch_branch_options(&opts, options);
|
||||
|
|
|
|||
27
third_party/git/builtin/clean.c
vendored
27
third_party/git/builtin/clean.c
vendored
|
|
@ -158,8 +158,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
|
|||
|
||||
*dir_gone = 1;
|
||||
|
||||
if ((force_flag & REMOVE_DIR_KEEP_NESTED_GIT) &&
|
||||
is_nonbare_repository_dir(path)) {
|
||||
if ((force_flag & REMOVE_DIR_KEEP_NESTED_GIT) && is_nonbare_repository_dir(path)) {
|
||||
if (!quiet) {
|
||||
quote_path_relative(path->buf, prefix, "ed);
|
||||
printf(dry_run ? _(msg_would_skip_git_dir) : _(msg_skip_git_dir),
|
||||
|
|
@ -649,7 +648,7 @@ static int filter_by_patterns_cmd(void)
|
|||
struct strbuf confirm = STRBUF_INIT;
|
||||
struct strbuf **ignore_list;
|
||||
struct string_list_item *item;
|
||||
struct pattern_list *pl;
|
||||
struct exclude_list *el;
|
||||
int changed = -1, i;
|
||||
|
||||
for (;;) {
|
||||
|
|
@ -672,7 +671,7 @@ static int filter_by_patterns_cmd(void)
|
|||
break;
|
||||
|
||||
memset(&dir, 0, sizeof(dir));
|
||||
pl = add_pattern_list(&dir, EXC_CMDL, "manual exclude");
|
||||
el = add_exclude_list(&dir, EXC_CMDL, "manual exclude");
|
||||
ignore_list = strbuf_split_max(&confirm, ' ', 0);
|
||||
|
||||
for (i = 0; ignore_list[i]; i++) {
|
||||
|
|
@ -680,7 +679,7 @@ static int filter_by_patterns_cmd(void)
|
|||
if (!ignore_list[i]->len)
|
||||
continue;
|
||||
|
||||
add_pattern(ignore_list[i]->buf, "", 0, pl, -(i+1));
|
||||
add_exclude(ignore_list[i]->buf, "", 0, el, -(i+1));
|
||||
}
|
||||
|
||||
changed = 0;
|
||||
|
|
@ -902,7 +901,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
|||
struct pathspec pathspec;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
struct string_list exclude_list = STRING_LIST_INIT_NODUP;
|
||||
struct pattern_list *pl;
|
||||
struct exclude_list *el;
|
||||
struct string_list_item *item;
|
||||
const char *qname;
|
||||
struct option options[] = {
|
||||
|
|
@ -947,19 +946,9 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
|||
|
||||
if (force > 1)
|
||||
rm_flags = 0;
|
||||
else
|
||||
dir.flags |= DIR_SKIP_NESTED_GIT;
|
||||
|
||||
dir.flags |= DIR_SHOW_OTHER_DIRECTORIES;
|
||||
|
||||
if (argc) {
|
||||
/*
|
||||
* Remaining args implies pathspecs specified, and we should
|
||||
* recurse within those.
|
||||
*/
|
||||
remove_directories = 1;
|
||||
}
|
||||
|
||||
if (remove_directories)
|
||||
dir.flags |= DIR_SHOW_IGNORED_TOO | DIR_KEEP_UNTRACKED_CONTENTS;
|
||||
|
||||
|
|
@ -969,9 +958,9 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
|||
if (!ignored)
|
||||
setup_standard_excludes(&dir);
|
||||
|
||||
pl = add_pattern_list(&dir, EXC_CMDL, "--exclude option");
|
||||
el = add_exclude_list(&dir, EXC_CMDL, "--exclude option");
|
||||
for (i = 0; i < exclude_list.nr; i++)
|
||||
add_pattern(exclude_list.items[i].string, "", 0, pl, -(i+1));
|
||||
add_exclude(exclude_list.items[i].string, "", 0, el, -(i+1));
|
||||
|
||||
parse_pathspec(&pathspec, 0,
|
||||
PATHSPEC_PREFER_CWD,
|
||||
|
|
@ -1018,7 +1007,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
|||
for_each_string_list_item(item, &del_list) {
|
||||
struct stat st;
|
||||
|
||||
strbuf_reset(&abs_path);
|
||||
if (prefix)
|
||||
strbuf_addstr(&abs_path, prefix);
|
||||
|
||||
|
|
@ -1052,6 +1040,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
|
|||
printf(dry_run ? _(msg_would_remove) : _(msg_remove), qname);
|
||||
}
|
||||
}
|
||||
strbuf_reset(&abs_path);
|
||||
}
|
||||
|
||||
strbuf_release(&abs_path);
|
||||
|
|
|
|||
61
third_party/git/builtin/clone.c
vendored
61
third_party/git/builtin/clone.c
vendored
|
|
@ -32,6 +32,7 @@
|
|||
#include "connected.h"
|
||||
#include "packfile.h"
|
||||
#include "list-objects-filter-options.h"
|
||||
#include "object-store.h"
|
||||
|
||||
/*
|
||||
* Overall FIXMEs:
|
||||
|
|
@ -59,7 +60,6 @@ static const char *real_git_dir;
|
|||
static char *option_upload_pack = "git-upload-pack";
|
||||
static int option_verbosity;
|
||||
static int option_progress = -1;
|
||||
static int option_sparse_checkout;
|
||||
static enum transport_family family;
|
||||
static struct string_list option_config = STRING_LIST_INIT_NODUP;
|
||||
static struct string_list option_required_reference = STRING_LIST_INIT_NODUP;
|
||||
|
|
@ -147,8 +147,6 @@ static struct option builtin_clone_options[] = {
|
|||
OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options),
|
||||
OPT_BOOL(0, "remote-submodules", &option_remote_submodules,
|
||||
N_("any cloned submodules will use their remote-tracking branch")),
|
||||
OPT_BOOL(0, "sparse", &option_sparse_checkout,
|
||||
N_("initialize sparse-checkout file to include only files at root")),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
|
|
@ -673,7 +671,7 @@ static void update_remote_refs(const struct ref *refs,
|
|||
const char *msg,
|
||||
struct transport *transport,
|
||||
int check_connectivity,
|
||||
int check_refs_are_promisor_objects_only)
|
||||
int check_refs_only)
|
||||
{
|
||||
const struct ref *rm = mapped_refs;
|
||||
|
||||
|
|
@ -682,8 +680,7 @@ static void update_remote_refs(const struct ref *refs,
|
|||
|
||||
opt.transport = transport;
|
||||
opt.progress = transport->progress;
|
||||
opt.check_refs_are_promisor_objects_only =
|
||||
!!check_refs_are_promisor_objects_only;
|
||||
opt.check_refs_only = !!check_refs_only;
|
||||
|
||||
if (check_connected(iterate_ref_map, &rm, &opt))
|
||||
die(_("remote did not send all necessary objects"));
|
||||
|
|
@ -737,27 +734,6 @@ static void update_head(const struct ref *our, const struct ref *remote,
|
|||
}
|
||||
}
|
||||
|
||||
static int git_sparse_checkout_init(const char *repo)
|
||||
{
|
||||
struct argv_array argv = ARGV_ARRAY_INIT;
|
||||
int result = 0;
|
||||
argv_array_pushl(&argv, "-C", repo, "sparse-checkout", "init", NULL);
|
||||
|
||||
/*
|
||||
* We must apply the setting in the current process
|
||||
* for the later checkout to use the sparse-checkout file.
|
||||
*/
|
||||
core_apply_sparse_checkout = 1;
|
||||
|
||||
if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {
|
||||
error(_("failed to initialize sparse-checkout"));
|
||||
result = 1;
|
||||
}
|
||||
|
||||
argv_array_clear(&argv);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int checkout(int submodule_progress)
|
||||
{
|
||||
struct object_id oid;
|
||||
|
|
@ -809,12 +785,12 @@ static int checkout(int submodule_progress)
|
|||
if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
|
||||
die(_("unable to write new index file"));
|
||||
|
||||
err |= run_hook_le(NULL, "post-checkout", oid_to_hex(&null_oid),
|
||||
err |= run_hook_le(NULL, "post-checkout", sha1_to_hex(null_sha1),
|
||||
oid_to_hex(&oid), "1", NULL);
|
||||
|
||||
if (!err && (option_recurse_submodules.nr > 0)) {
|
||||
struct argv_array args = ARGV_ARRAY_INIT;
|
||||
argv_array_pushl(&args, "submodule", "update", "--require-init", "--recursive", NULL);
|
||||
argv_array_pushl(&args, "submodule", "update", "--init", "--recursive", NULL);
|
||||
|
||||
if (option_shallow_submodules == 1)
|
||||
argv_array_push(&args, "--depth=1");
|
||||
|
|
@ -833,11 +809,6 @@ static int checkout(int submodule_progress)
|
|||
argv_array_push(&args, "--no-fetch");
|
||||
}
|
||||
|
||||
if (option_single_branch >= 0)
|
||||
argv_array_push(&args, option_single_branch ?
|
||||
"--single-branch" :
|
||||
"--no-single-branch");
|
||||
|
||||
err = run_command_v_opt(args.argv, RUN_GIT_CMD);
|
||||
argv_array_clear(&args);
|
||||
}
|
||||
|
|
@ -929,7 +900,7 @@ static void dissociate_from_references(void)
|
|||
free(alternates);
|
||||
}
|
||||
|
||||
static int path_exists(const char *path)
|
||||
static int dir_exists(const char *path)
|
||||
{
|
||||
struct stat sb;
|
||||
return !stat(path, &sb);
|
||||
|
|
@ -957,6 +928,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||
|
||||
struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
|
||||
|
||||
fetch_if_missing = 0;
|
||||
|
||||
packet_trace_identity("clone");
|
||||
argc = parse_options(argc, argv, prefix, builtin_clone_options,
|
||||
builtin_clone_usage, 0);
|
||||
|
|
@ -1009,7 +982,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||
dir = guess_dir_name(repo_name, is_bundle, option_bare);
|
||||
strip_trailing_slashes(dir);
|
||||
|
||||
dest_exists = path_exists(dir);
|
||||
dest_exists = dir_exists(dir);
|
||||
if (dest_exists && !is_empty_dir(dir))
|
||||
die(_("destination path '%s' already exists and is not "
|
||||
"an empty directory."), dir);
|
||||
|
|
@ -1020,7 +993,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||
work_tree = NULL;
|
||||
else {
|
||||
work_tree = getenv("GIT_WORK_TREE");
|
||||
if (work_tree && path_exists(work_tree))
|
||||
if (work_tree && dir_exists(work_tree))
|
||||
die(_("working tree '%s' already exists."), work_tree);
|
||||
}
|
||||
|
||||
|
|
@ -1048,7 +1021,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
|
||||
if (real_git_dir) {
|
||||
if (path_exists(real_git_dir))
|
||||
if (dir_exists(real_git_dir))
|
||||
junk_git_dir_flags |= REMOVE_DIR_KEEP_TOPLEVEL;
|
||||
junk_git_dir = real_git_dir;
|
||||
} else {
|
||||
|
|
@ -1134,9 +1107,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||
if (option_required_reference.nr || option_optional_reference.nr)
|
||||
setup_reference();
|
||||
|
||||
if (option_sparse_checkout && git_sparse_checkout_init(dir))
|
||||
return 1;
|
||||
|
||||
remote = remote_get(option_origin);
|
||||
|
||||
strbuf_addf(&default_refspec, "+%s*:%s*", src_ref_prefix,
|
||||
|
|
@ -1190,11 +1160,13 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||
transport->server_options = &server_options;
|
||||
|
||||
if (filter_options.choice) {
|
||||
const char *spec =
|
||||
expand_list_objects_filter_spec(&filter_options);
|
||||
struct strbuf expanded_filter_spec = STRBUF_INIT;
|
||||
expand_list_objects_filter_spec(&filter_options,
|
||||
&expanded_filter_spec);
|
||||
transport_set_option(transport, TRANS_OPT_LIST_OBJECTS_FILTER,
|
||||
spec);
|
||||
expanded_filter_spec.buf);
|
||||
transport_set_option(transport, TRANS_OPT_FROM_PROMISOR, "1");
|
||||
strbuf_release(&expanded_filter_spec);
|
||||
}
|
||||
|
||||
if (transport->smart_options && !deepen && !filter_options.choice)
|
||||
|
|
@ -1296,6 +1268,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
|
||||
junk_mode = JUNK_LEAVE_REPO;
|
||||
fetch_if_missing = 1;
|
||||
err = checkout(submodule_progress);
|
||||
|
||||
strbuf_release(&reflog_msg);
|
||||
|
|
|
|||
135
third_party/git/builtin/commit-graph.c
vendored
135
third_party/git/builtin/commit-graph.c
vendored
|
|
@ -8,18 +8,25 @@
|
|||
#include "object-store.h"
|
||||
|
||||
static char const * const builtin_commit_graph_usage[] = {
|
||||
N_("git commit-graph verify [--object-dir <objdir>] [--shallow] [--[no-]progress]"),
|
||||
N_("git commit-graph write [--object-dir <objdir>] [--append|--split] [--reachable|--stdin-packs|--stdin-commits] [--[no-]progress] <split options>"),
|
||||
N_("git commit-graph [--object-dir <objdir>]"),
|
||||
N_("git commit-graph read [--object-dir <objdir>]"),
|
||||
N_("git commit-graph verify [--object-dir <objdir>] [--shallow]"),
|
||||
N_("git commit-graph write [--object-dir <objdir>] [--append|--split] [--reachable|--stdin-packs|--stdin-commits] <split options>"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char * const builtin_commit_graph_verify_usage[] = {
|
||||
N_("git commit-graph verify [--object-dir <objdir>] [--shallow] [--[no-]progress]"),
|
||||
N_("git commit-graph verify [--object-dir <objdir>] [--shallow]"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char * const builtin_commit_graph_read_usage[] = {
|
||||
N_("git commit-graph read [--object-dir <objdir>]"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char * const builtin_commit_graph_write_usage[] = {
|
||||
N_("git commit-graph write [--object-dir <objdir>] [--append|--split] [--reachable|--stdin-packs|--stdin-commits] [--[no-]progress] <split options>"),
|
||||
N_("git commit-graph write [--object-dir <objdir>] [--append|--split] [--reachable|--stdin-packs|--stdin-commits] <split options>"),
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -31,32 +38,11 @@ static struct opts_commit_graph {
|
|||
int append;
|
||||
int split;
|
||||
int shallow;
|
||||
int progress;
|
||||
} opts;
|
||||
|
||||
static struct object_directory *find_odb(struct repository *r,
|
||||
const char *obj_dir)
|
||||
{
|
||||
struct object_directory *odb;
|
||||
char *obj_dir_real = real_pathdup(obj_dir, 1);
|
||||
|
||||
prepare_alt_odb(r);
|
||||
for (odb = r->objects->odb; odb; odb = odb->next) {
|
||||
if (!strcmp(obj_dir_real, real_path(odb->path)))
|
||||
break;
|
||||
}
|
||||
|
||||
free(obj_dir_real);
|
||||
|
||||
if (!odb)
|
||||
die(_("could not find object directory matching %s"), obj_dir);
|
||||
return odb;
|
||||
}
|
||||
|
||||
static int graph_verify(int argc, const char **argv)
|
||||
{
|
||||
struct commit_graph *graph = NULL;
|
||||
struct object_directory *odb = NULL;
|
||||
char *graph_name;
|
||||
int open_ok;
|
||||
int fd;
|
||||
|
|
@ -69,13 +55,9 @@ static int graph_verify(int argc, const char **argv)
|
|||
N_("The object directory to store the graph")),
|
||||
OPT_BOOL(0, "shallow", &opts.shallow,
|
||||
N_("if the commit-graph is split, only verify the tip file")),
|
||||
OPT_BOOL(0, "progress", &opts.progress, N_("force progress reporting")),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
trace2_cmd_mode("verify");
|
||||
|
||||
opts.progress = isatty(2);
|
||||
argc = parse_options(argc, argv, NULL,
|
||||
builtin_commit_graph_verify_options,
|
||||
builtin_commit_graph_verify_usage, 0);
|
||||
|
|
@ -84,11 +66,8 @@ static int graph_verify(int argc, const char **argv)
|
|||
opts.obj_dir = get_object_directory();
|
||||
if (opts.shallow)
|
||||
flags |= COMMIT_GRAPH_VERIFY_SHALLOW;
|
||||
if (opts.progress)
|
||||
flags |= COMMIT_GRAPH_WRITE_PROGRESS;
|
||||
|
||||
odb = find_odb(the_repository, opts.obj_dir);
|
||||
graph_name = get_commit_graph_filename(odb);
|
||||
graph_name = get_commit_graph_filename(opts.obj_dir);
|
||||
open_ok = open_commit_graph(graph_name, &fd, &st);
|
||||
if (!open_ok && errno != ENOENT)
|
||||
die_errno(_("Could not open commit-graph '%s'"), graph_name);
|
||||
|
|
@ -96,9 +75,9 @@ static int graph_verify(int argc, const char **argv)
|
|||
FREE_AND_NULL(graph_name);
|
||||
|
||||
if (open_ok)
|
||||
graph = load_commit_graph_one_fd_st(fd, &st, odb);
|
||||
else
|
||||
graph = read_commit_graph_one(the_repository, odb);
|
||||
graph = load_commit_graph_one_fd_st(fd, &st);
|
||||
else
|
||||
graph = read_commit_graph_one(the_repository, opts.obj_dir);
|
||||
|
||||
/* Return failure if open_ok predicted success */
|
||||
if (!graph)
|
||||
|
|
@ -108,6 +87,64 @@ static int graph_verify(int argc, const char **argv)
|
|||
return verify_commit_graph(the_repository, graph, flags);
|
||||
}
|
||||
|
||||
static int graph_read(int argc, const char **argv)
|
||||
{
|
||||
struct commit_graph *graph = NULL;
|
||||
char *graph_name;
|
||||
int open_ok;
|
||||
int fd;
|
||||
struct stat st;
|
||||
|
||||
static struct option builtin_commit_graph_read_options[] = {
|
||||
OPT_STRING(0, "object-dir", &opts.obj_dir,
|
||||
N_("dir"),
|
||||
N_("The object directory to store the graph")),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
argc = parse_options(argc, argv, NULL,
|
||||
builtin_commit_graph_read_options,
|
||||
builtin_commit_graph_read_usage, 0);
|
||||
|
||||
if (!opts.obj_dir)
|
||||
opts.obj_dir = get_object_directory();
|
||||
|
||||
graph_name = get_commit_graph_filename(opts.obj_dir);
|
||||
|
||||
open_ok = open_commit_graph(graph_name, &fd, &st);
|
||||
if (!open_ok)
|
||||
die_errno(_("Could not open commit-graph '%s'"), graph_name);
|
||||
|
||||
graph = load_commit_graph_one_fd_st(fd, &st);
|
||||
if (!graph)
|
||||
return 1;
|
||||
|
||||
FREE_AND_NULL(graph_name);
|
||||
|
||||
printf("header: %08x %d %d %d %d\n",
|
||||
ntohl(*(uint32_t*)graph->data),
|
||||
*(unsigned char*)(graph->data + 4),
|
||||
*(unsigned char*)(graph->data + 5),
|
||||
*(unsigned char*)(graph->data + 6),
|
||||
*(unsigned char*)(graph->data + 7));
|
||||
printf("num_commits: %u\n", graph->num_commits);
|
||||
printf("chunks:");
|
||||
|
||||
if (graph->chunk_oid_fanout)
|
||||
printf(" oid_fanout");
|
||||
if (graph->chunk_oid_lookup)
|
||||
printf(" oid_lookup");
|
||||
if (graph->chunk_commit_data)
|
||||
printf(" commit_metadata");
|
||||
if (graph->chunk_extra_edges)
|
||||
printf(" extra_edges");
|
||||
printf("\n");
|
||||
|
||||
UNLEAK(graph);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int read_replace_refs;
|
||||
static struct split_commit_graph_opts split_opts;
|
||||
|
||||
|
|
@ -115,10 +152,9 @@ static int graph_write(int argc, const char **argv)
|
|||
{
|
||||
struct string_list *pack_indexes = NULL;
|
||||
struct string_list *commit_hex = NULL;
|
||||
struct object_directory *odb = NULL;
|
||||
struct string_list lines;
|
||||
int result = 0;
|
||||
enum commit_graph_write_flags flags = 0;
|
||||
unsigned int flags = COMMIT_GRAPH_PROGRESS;
|
||||
|
||||
static struct option builtin_commit_graph_write_options[] = {
|
||||
OPT_STRING(0, "object-dir", &opts.obj_dir,
|
||||
|
|
@ -132,7 +168,6 @@ static int graph_write(int argc, const char **argv)
|
|||
N_("start walk at commits listed by stdin")),
|
||||
OPT_BOOL(0, "append", &opts.append,
|
||||
N_("include all commits already in the commit-graph file")),
|
||||
OPT_BOOL(0, "progress", &opts.progress, N_("force progress reporting")),
|
||||
OPT_BOOL(0, "split", &opts.split,
|
||||
N_("allow writing an incremental commit-graph file")),
|
||||
OPT_INTEGER(0, "max-commits", &split_opts.max_commits,
|
||||
|
|
@ -144,13 +179,10 @@ static int graph_write(int argc, const char **argv)
|
|||
OPT_END(),
|
||||
};
|
||||
|
||||
opts.progress = isatty(2);
|
||||
split_opts.size_multiple = 2;
|
||||
split_opts.max_commits = 0;
|
||||
split_opts.expire_time = 0;
|
||||
|
||||
trace2_cmd_mode("write");
|
||||
|
||||
argc = parse_options(argc, argv, NULL,
|
||||
builtin_commit_graph_write_options,
|
||||
builtin_commit_graph_write_usage, 0);
|
||||
|
|
@ -160,17 +192,14 @@ static int graph_write(int argc, const char **argv)
|
|||
if (!opts.obj_dir)
|
||||
opts.obj_dir = get_object_directory();
|
||||
if (opts.append)
|
||||
flags |= COMMIT_GRAPH_WRITE_APPEND;
|
||||
flags |= COMMIT_GRAPH_APPEND;
|
||||
if (opts.split)
|
||||
flags |= COMMIT_GRAPH_WRITE_SPLIT;
|
||||
if (opts.progress)
|
||||
flags |= COMMIT_GRAPH_WRITE_PROGRESS;
|
||||
flags |= COMMIT_GRAPH_SPLIT;
|
||||
|
||||
read_replace_refs = 0;
|
||||
odb = find_odb(the_repository, opts.obj_dir);
|
||||
|
||||
if (opts.reachable) {
|
||||
if (write_commit_graph_reachable(odb, flags, &split_opts))
|
||||
if (write_commit_graph_reachable(opts.obj_dir, flags, &split_opts))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -184,15 +213,13 @@ static int graph_write(int argc, const char **argv)
|
|||
|
||||
if (opts.stdin_packs)
|
||||
pack_indexes = &lines;
|
||||
if (opts.stdin_commits) {
|
||||
if (opts.stdin_commits)
|
||||
commit_hex = &lines;
|
||||
flags |= COMMIT_GRAPH_WRITE_CHECK_OIDS;
|
||||
}
|
||||
|
||||
UNLEAK(buf);
|
||||
}
|
||||
|
||||
if (write_commit_graph(odb,
|
||||
if (write_commit_graph(opts.obj_dir,
|
||||
pack_indexes,
|
||||
commit_hex,
|
||||
flags,
|
||||
|
|
@ -222,9 +249,9 @@ int cmd_commit_graph(int argc, const char **argv, const char *prefix)
|
|||
builtin_commit_graph_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
|
||||
save_commit_buffer = 0;
|
||||
|
||||
if (argc > 0) {
|
||||
if (!strcmp(argv[0], "read"))
|
||||
return graph_read(argc, argv);
|
||||
if (!strcmp(argv[0], "verify"))
|
||||
return graph_verify(argc, argv);
|
||||
if (!strcmp(argv[0], "write"))
|
||||
|
|
|
|||
67
third_party/git/builtin/commit.c
vendored
67
third_party/git/builtin/commit.c
vendored
|
|
@ -107,9 +107,9 @@ static int all, also, interactive, patch_interactive, only, amend, signoff;
|
|||
static int edit_flag = -1; /* unspecified */
|
||||
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
|
||||
static int config_commit_verbose = -1; /* unspecified */
|
||||
static int no_post_rewrite, allow_empty_message, pathspec_file_nul;
|
||||
static int no_post_rewrite, allow_empty_message;
|
||||
static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;
|
||||
static char *sign_commit, *pathspec_from_file;
|
||||
static char *sign_commit;
|
||||
|
||||
/*
|
||||
* The default commit message cleanup mode will remove the lines
|
||||
|
|
@ -343,31 +343,11 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
|
|||
PATHSPEC_PREFER_FULL,
|
||||
prefix, argv);
|
||||
|
||||
if (pathspec_from_file) {
|
||||
if (interactive)
|
||||
die(_("--pathspec-from-file is incompatible with --interactive/--patch"));
|
||||
|
||||
if (all)
|
||||
die(_("--pathspec-from-file with -a does not make sense"));
|
||||
|
||||
if (pathspec.nr)
|
||||
die(_("--pathspec-from-file is incompatible with pathspec arguments"));
|
||||
|
||||
parse_pathspec_file(&pathspec, 0,
|
||||
PATHSPEC_PREFER_FULL,
|
||||
prefix, pathspec_from_file, pathspec_file_nul);
|
||||
} else if (pathspec_file_nul) {
|
||||
die(_("--pathspec-file-nul requires --pathspec-from-file"));
|
||||
}
|
||||
|
||||
if (!pathspec.nr && (also || (only && !amend && !allow_empty)))
|
||||
die(_("No paths with --include/--only does not make sense."));
|
||||
|
||||
if (read_cache_preload(&pathspec) < 0)
|
||||
die(_("index file corrupt"));
|
||||
|
||||
if (interactive) {
|
||||
char *old_index_env = NULL, *old_repo_index_file;
|
||||
char *old_index_env = NULL;
|
||||
hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
|
||||
|
||||
refresh_cache_or_die(refresh_flags);
|
||||
|
|
@ -375,16 +355,12 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
|
|||
if (write_locked_index(&the_index, &index_lock, 0))
|
||||
die(_("unable to create temporary index"));
|
||||
|
||||
old_repo_index_file = the_repository->index_file;
|
||||
the_repository->index_file =
|
||||
(char *)get_lock_file_path(&index_lock);
|
||||
old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT));
|
||||
setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1);
|
||||
setenv(INDEX_ENVIRONMENT, get_lock_file_path(&index_lock), 1);
|
||||
|
||||
if (interactive_add(argc, argv, prefix, patch_interactive) != 0)
|
||||
die(_("interactive add failed"));
|
||||
|
||||
the_repository->index_file = old_repo_index_file;
|
||||
if (old_index_env && *old_index_env)
|
||||
setenv(INDEX_ENVIRONMENT, old_index_env, 1);
|
||||
else
|
||||
|
|
@ -534,7 +510,7 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
|
|||
s->nowarn = nowarn;
|
||||
s->is_initial = get_oid(s->reference, &oid) ? 1 : 0;
|
||||
if (!s->is_initial)
|
||||
oidcpy(&s->oid_commit, &oid);
|
||||
hashcpy(s->sha1_commit, oid.hash);
|
||||
s->status_format = status_format;
|
||||
s->ignore_submodule_arg = ignore_submodule_arg;
|
||||
|
||||
|
|
@ -561,7 +537,7 @@ static void export_one(const char *var, const char *s, const char *e, int hack)
|
|||
struct strbuf buf = STRBUF_INIT;
|
||||
if (hack)
|
||||
strbuf_addch(&buf, hack);
|
||||
strbuf_add(&buf, s, e - s);
|
||||
strbuf_addf(&buf, "%.*s", (int)(e - s), s);
|
||||
setenv(var, buf.buf, 1);
|
||||
strbuf_release(&buf);
|
||||
}
|
||||
|
|
@ -968,7 +944,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
|
|||
*/
|
||||
if (!committable && whence != FROM_MERGE && !allow_empty &&
|
||||
!(amend && is_a_merge(current_head))) {
|
||||
s->hints = advice_status_hints;
|
||||
s->display_comment_prefix = old_display_comment_prefix;
|
||||
run_status(stdout, index_file, prefix, 0, s);
|
||||
if (amend)
|
||||
|
|
@ -1223,6 +1198,8 @@ static int parse_and_validate_options(int argc, const char *argv[],
|
|||
|
||||
if (also + only + all + interactive > 1)
|
||||
die(_("Only one of --include/--only/--all/--interactive/--patch can be used."));
|
||||
if (argc == 0 && (also || (only && !amend && !allow_empty)))
|
||||
die(_("No paths with --include/--only does not make sense."));
|
||||
cleanup_mode = get_cleanup_mode(cleanup_arg, use_editor);
|
||||
|
||||
handle_untracked_files_arg(s);
|
||||
|
|
@ -1429,7 +1406,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
|
|||
|
||||
s.is_initial = get_oid(s.reference, &oid) ? 1 : 0;
|
||||
if (!s.is_initial)
|
||||
oidcpy(&s.oid_commit, &oid);
|
||||
hashcpy(s.sha1_commit, oid.hash);
|
||||
|
||||
s.ignore_submodule_arg = ignore_submodule_arg;
|
||||
s.status_format = status_format;
|
||||
|
|
@ -1486,6 +1463,28 @@ static int git_commit_config(const char *k, const char *v, void *cb)
|
|||
return git_status_config(k, v, s);
|
||||
}
|
||||
|
||||
int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...)
|
||||
{
|
||||
struct argv_array hook_env = ARGV_ARRAY_INIT;
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
argv_array_pushf(&hook_env, "GIT_INDEX_FILE=%s", index_file);
|
||||
|
||||
/*
|
||||
* Let the hook know that no editor will be launched.
|
||||
*/
|
||||
if (!editor_is_used)
|
||||
argv_array_push(&hook_env, "GIT_EDITOR=:");
|
||||
|
||||
va_start(args, name);
|
||||
ret = run_hook_ve(hook_env.argv,name, args);
|
||||
va_end(args);
|
||||
argv_array_clear(&hook_env);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
const char *argv_gc_auto[] = {"gc", "--auto", NULL};
|
||||
|
|
@ -1536,8 +1535,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
|||
OPT_BOOL(0, "amend", &amend, N_("amend previous commit")),
|
||||
OPT_BOOL(0, "no-post-rewrite", &no_post_rewrite, N_("bypass post-rewrite hook")),
|
||||
{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, N_("mode"), N_("show untracked files, optional modes: all, normal, no. (Default: all)"), PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
|
||||
OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
|
||||
OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
|
||||
/* end commit contents options */
|
||||
|
||||
OPT_HIDDEN_BOOL(0, "allow-empty", &allow_empty,
|
||||
|
|
@ -1693,7 +1690,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
|||
"not exceeded, and then \"git restore --staged :/\" to recover."));
|
||||
|
||||
if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) &&
|
||||
write_commit_graph_reachable(the_repository->objects->odb, 0, NULL))
|
||||
write_commit_graph_reachable(get_object_directory(), 0, NULL))
|
||||
return 1;
|
||||
|
||||
repo_rerere(the_repository, 0);
|
||||
|
|
|
|||
46
third_party/git/builtin/config.c
vendored
46
third_party/git/builtin/config.c
vendored
|
|
@ -29,11 +29,10 @@ static int use_worktree_config;
|
|||
static struct git_config_source given_config_source;
|
||||
static int actions, type;
|
||||
static char *default_value;
|
||||
static int end_nul;
|
||||
static int end_null;
|
||||
static int respect_includes_opt = -1;
|
||||
static struct config_options config_options;
|
||||
static int show_origin;
|
||||
static int show_scope;
|
||||
|
||||
#define ACTION_GET (1<<0)
|
||||
#define ACTION_GET_ALL (1<<1)
|
||||
|
|
@ -152,11 +151,10 @@ static struct option builtin_config_options[] = {
|
|||
OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
|
||||
OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
|
||||
OPT_GROUP(N_("Other")),
|
||||
OPT_BOOL('z', "null", &end_nul, N_("terminate values with NUL byte")),
|
||||
OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")),
|
||||
OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")),
|
||||
OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")),
|
||||
OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")),
|
||||
OPT_BOOL(0, "show-scope", &show_scope, N_("show scope of config (worktree, local, global, system, command)")),
|
||||
OPT_STRING(0, "default", &default_value, N_("value"), N_("with --get, use default value when missing entry")),
|
||||
OPT_END(),
|
||||
};
|
||||
|
|
@ -180,34 +178,22 @@ static void check_argc(int argc, int min, int max)
|
|||
|
||||
static void show_config_origin(struct strbuf *buf)
|
||||
{
|
||||
const char term = end_nul ? '\0' : '\t';
|
||||
const char term = end_null ? '\0' : '\t';
|
||||
|
||||
strbuf_addstr(buf, current_config_origin_type());
|
||||
strbuf_addch(buf, ':');
|
||||
if (end_nul)
|
||||
if (end_null)
|
||||
strbuf_addstr(buf, current_config_name());
|
||||
else
|
||||
quote_c_style(current_config_name(), buf, NULL, 0);
|
||||
strbuf_addch(buf, term);
|
||||
}
|
||||
|
||||
static void show_config_scope(struct strbuf *buf)
|
||||
{
|
||||
const char term = end_nul ? '\0' : '\t';
|
||||
const char *scope = config_scope_name(current_config_scope());
|
||||
|
||||
strbuf_addstr(buf, N_(scope));
|
||||
strbuf_addch(buf, term);
|
||||
}
|
||||
|
||||
static int show_all_config(const char *key_, const char *value_, void *cb)
|
||||
{
|
||||
if (show_origin || show_scope) {
|
||||
if (show_origin) {
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
if (show_scope)
|
||||
show_config_scope(&buf);
|
||||
if (show_origin)
|
||||
show_config_origin(&buf);
|
||||
show_config_origin(&buf);
|
||||
/* Use fwrite as "buf" can contain \0's if "end_null" is set. */
|
||||
fwrite(buf.buf, 1, buf.len, stdout);
|
||||
strbuf_release(&buf);
|
||||
|
|
@ -227,8 +213,6 @@ struct strbuf_list {
|
|||
|
||||
static int format_config(struct strbuf *buf, const char *key_, const char *value_)
|
||||
{
|
||||
if (show_scope)
|
||||
show_config_scope(buf);
|
||||
if (show_origin)
|
||||
show_config_origin(buf);
|
||||
if (show_keys)
|
||||
|
|
@ -638,7 +622,6 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
|||
!strcmp(given_config_source.file, "-")) {
|
||||
given_config_source.file = NULL;
|
||||
given_config_source.use_stdin = 1;
|
||||
given_config_source.scope = CONFIG_SCOPE_COMMAND;
|
||||
}
|
||||
|
||||
if (use_global_config) {
|
||||
|
|
@ -654,8 +637,6 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
|||
*/
|
||||
die(_("$HOME not set"));
|
||||
|
||||
given_config_source.scope = CONFIG_SCOPE_GLOBAL;
|
||||
|
||||
if (access_or_warn(user_config, R_OK, 0) &&
|
||||
xdg_config && !access_or_warn(xdg_config, R_OK, 0)) {
|
||||
given_config_source.file = xdg_config;
|
||||
|
|
@ -665,13 +646,11 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
|||
free(xdg_config);
|
||||
}
|
||||
}
|
||||
else if (use_system_config) {
|
||||
else if (use_system_config)
|
||||
given_config_source.file = git_etc_gitconfig();
|
||||
given_config_source.scope = CONFIG_SCOPE_SYSTEM;
|
||||
} else if (use_local_config) {
|
||||
else if (use_local_config)
|
||||
given_config_source.file = git_pathdup("config");
|
||||
given_config_source.scope = CONFIG_SCOPE_LOCAL;
|
||||
} else if (use_worktree_config) {
|
||||
else if (use_worktree_config) {
|
||||
struct worktree **worktrees = get_worktrees(0);
|
||||
if (repository_format_worktree_config)
|
||||
given_config_source.file = git_pathdup("config.worktree");
|
||||
|
|
@ -683,18 +662,13 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
|||
"section in \"git help worktree\" for details"));
|
||||
else
|
||||
given_config_source.file = git_pathdup("config");
|
||||
given_config_source.scope = CONFIG_SCOPE_LOCAL;
|
||||
free_worktrees(worktrees);
|
||||
} else if (given_config_source.file) {
|
||||
if (!is_absolute_path(given_config_source.file) && prefix)
|
||||
given_config_source.file =
|
||||
prefix_filename(prefix, given_config_source.file);
|
||||
given_config_source.scope = CONFIG_SCOPE_COMMAND;
|
||||
} else if (given_config_source.blob) {
|
||||
given_config_source.scope = CONFIG_SCOPE_COMMAND;
|
||||
}
|
||||
|
||||
|
||||
if (respect_includes_opt == -1)
|
||||
config_options.respect_includes = !given_config_source.file;
|
||||
else
|
||||
|
|
@ -704,7 +678,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
|
|||
config_options.git_dir = get_git_dir();
|
||||
}
|
||||
|
||||
if (end_nul) {
|
||||
if (end_null) {
|
||||
term = '\0';
|
||||
delim = '\n';
|
||||
key_delim = '\n';
|
||||
|
|
|
|||
46
third_party/git/builtin/describe.c
vendored
46
third_party/git/builtin/describe.c
vendored
|
|
@ -15,6 +15,7 @@
|
|||
#include "argv-array.h"
|
||||
#include "run-command.h"
|
||||
#include "object-store.h"
|
||||
#include "revision.h"
|
||||
#include "list-objects.h"
|
||||
#include "commit-slab.h"
|
||||
|
||||
|
|
@ -63,22 +64,19 @@ static const char *prio_names[] = {
|
|||
};
|
||||
|
||||
static int commit_name_neq(const void *unused_cmp_data,
|
||||
const struct hashmap_entry *eptr,
|
||||
const struct hashmap_entry *entry_or_key,
|
||||
const void *entry,
|
||||
const void *entry_or_key,
|
||||
const void *peeled)
|
||||
{
|
||||
const struct commit_name *cn1, *cn2;
|
||||
|
||||
cn1 = container_of(eptr, const struct commit_name, entry);
|
||||
cn2 = container_of(entry_or_key, const struct commit_name, entry);
|
||||
const struct commit_name *cn1 = entry;
|
||||
const struct commit_name *cn2 = entry_or_key;
|
||||
|
||||
return !oideq(&cn1->peeled, peeled ? peeled : &cn2->peeled);
|
||||
}
|
||||
|
||||
static inline struct commit_name *find_commit_name(const struct object_id *peeled)
|
||||
{
|
||||
return hashmap_get_entry_from_hash(&names, oidhash(peeled), peeled,
|
||||
struct commit_name, entry);
|
||||
return hashmap_get_from_hash(&names, oidhash(peeled), peeled);
|
||||
}
|
||||
|
||||
static int replace_name(struct commit_name *e,
|
||||
|
|
@ -125,8 +123,8 @@ static void add_to_known_names(const char *path,
|
|||
if (!e) {
|
||||
e = xmalloc(sizeof(struct commit_name));
|
||||
oidcpy(&e->peeled, peeled);
|
||||
hashmap_entry_init(&e->entry, oidhash(peeled));
|
||||
hashmap_add(&names, &e->entry);
|
||||
hashmap_entry_init(e, oidhash(peeled));
|
||||
hashmap_add(&names, e);
|
||||
e->path = NULL;
|
||||
}
|
||||
e->tag = tag;
|
||||
|
|
@ -315,7 +313,7 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
|
|||
*/
|
||||
append_name(n, dst);
|
||||
if (longformat)
|
||||
append_suffix(0, n->tag ? get_tagged_oid(n->tag) : oid, dst);
|
||||
append_suffix(0, n->tag ? &n->tag->tagged->oid : oid, dst);
|
||||
if (suffix)
|
||||
strbuf_addstr(dst, suffix);
|
||||
return;
|
||||
|
|
@ -332,8 +330,8 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
|
|||
struct commit_name *n;
|
||||
|
||||
init_commit_names(&commit_names);
|
||||
hashmap_for_each_entry(&names, &iter, n,
|
||||
entry /* member name */) {
|
||||
n = hashmap_iter_first(&names, &iter);
|
||||
for (; n; n = hashmap_iter_next(&iter)) {
|
||||
c = lookup_commit_reference_gently(the_repository,
|
||||
&n->peeled, 1);
|
||||
if (c)
|
||||
|
|
@ -376,25 +374,11 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
|
|||
if (!(c->object.flags & t->flag_within))
|
||||
t->depth++;
|
||||
}
|
||||
/* Stop if last remaining path already covered by best candidate(s) */
|
||||
if (annotated_cnt && !list) {
|
||||
int best_depth = INT_MAX;
|
||||
unsigned best_within = 0;
|
||||
for (cur_match = 0; cur_match < match_cnt; cur_match++) {
|
||||
struct possible_tag *t = &all_matches[cur_match];
|
||||
if (t->depth < best_depth) {
|
||||
best_depth = t->depth;
|
||||
best_within = t->flag_within;
|
||||
} else if (t->depth == best_depth) {
|
||||
best_within |= t->flag_within;
|
||||
}
|
||||
}
|
||||
if ((c->object.flags & best_within) == best_within) {
|
||||
if (debug)
|
||||
fprintf(stderr, _("finished search at %s\n"),
|
||||
oid_to_hex(&c->object.oid));
|
||||
break;
|
||||
}
|
||||
if (debug)
|
||||
fprintf(stderr, _("finished search at %s\n"),
|
||||
oid_to_hex(&c->object.oid));
|
||||
break;
|
||||
}
|
||||
while (parents) {
|
||||
struct commit *p = parents->item;
|
||||
|
|
|
|||
56
third_party/git/builtin/difftool.c
vendored
56
third_party/git/builtin/difftool.c
vendored
|
|
@ -125,15 +125,12 @@ struct working_tree_entry {
|
|||
};
|
||||
|
||||
static int working_tree_entry_cmp(const void *unused_cmp_data,
|
||||
const struct hashmap_entry *eptr,
|
||||
const struct hashmap_entry *entry_or_key,
|
||||
const void *entry,
|
||||
const void *entry_or_key,
|
||||
const void *unused_keydata)
|
||||
{
|
||||
const struct working_tree_entry *a, *b;
|
||||
|
||||
a = container_of(eptr, const struct working_tree_entry, entry);
|
||||
b = container_of(entry_or_key, const struct working_tree_entry, entry);
|
||||
|
||||
const struct working_tree_entry *a = entry;
|
||||
const struct working_tree_entry *b = entry_or_key;
|
||||
return strcmp(a->path, b->path);
|
||||
}
|
||||
|
||||
|
|
@ -148,14 +145,12 @@ struct pair_entry {
|
|||
};
|
||||
|
||||
static int pair_cmp(const void *unused_cmp_data,
|
||||
const struct hashmap_entry *eptr,
|
||||
const struct hashmap_entry *entry_or_key,
|
||||
const void *entry,
|
||||
const void *entry_or_key,
|
||||
const void *unused_keydata)
|
||||
{
|
||||
const struct pair_entry *a, *b;
|
||||
|
||||
a = container_of(eptr, const struct pair_entry, entry);
|
||||
b = container_of(entry_or_key, const struct pair_entry, entry);
|
||||
const struct pair_entry *a = entry;
|
||||
const struct pair_entry *b = entry_or_key;
|
||||
|
||||
return strcmp(a->path, b->path);
|
||||
}
|
||||
|
|
@ -166,14 +161,14 @@ static void add_left_or_right(struct hashmap *map, const char *path,
|
|||
struct pair_entry *e, *existing;
|
||||
|
||||
FLEX_ALLOC_STR(e, path, path);
|
||||
hashmap_entry_init(&e->entry, strhash(path));
|
||||
existing = hashmap_get_entry(map, e, entry, NULL);
|
||||
hashmap_entry_init(e, strhash(path));
|
||||
existing = hashmap_get(map, e, NULL);
|
||||
if (existing) {
|
||||
free(e);
|
||||
e = existing;
|
||||
} else {
|
||||
e->left[0] = e->right[0] = '\0';
|
||||
hashmap_add(map, &e->entry);
|
||||
hashmap_add(map, e);
|
||||
}
|
||||
strlcpy(is_right ? e->right : e->left, content, PATH_MAX);
|
||||
}
|
||||
|
|
@ -184,14 +179,12 @@ struct path_entry {
|
|||
};
|
||||
|
||||
static int path_entry_cmp(const void *unused_cmp_data,
|
||||
const struct hashmap_entry *eptr,
|
||||
const struct hashmap_entry *entry_or_key,
|
||||
const void *entry,
|
||||
const void *entry_or_key,
|
||||
const void *key)
|
||||
{
|
||||
const struct path_entry *a, *b;
|
||||
|
||||
a = container_of(eptr, const struct path_entry, entry);
|
||||
b = container_of(entry_or_key, const struct path_entry, entry);
|
||||
const struct path_entry *a = entry;
|
||||
const struct path_entry *b = entry_or_key;
|
||||
|
||||
return strcmp(a->path, key ? key : b->path);
|
||||
}
|
||||
|
|
@ -241,8 +234,8 @@ static void changed_files(struct hashmap *result, const char *index_path,
|
|||
while (!strbuf_getline_nul(&buf, fp)) {
|
||||
struct path_entry *entry;
|
||||
FLEX_ALLOC_STR(entry, path, buf.buf);
|
||||
hashmap_entry_init(&entry->entry, strhash(buf.buf));
|
||||
hashmap_add(result, &entry->entry);
|
||||
hashmap_entry_init(entry, strhash(buf.buf));
|
||||
hashmap_add(result, entry);
|
||||
}
|
||||
fclose(fp);
|
||||
if (finish_command(&diff_files))
|
||||
|
|
@ -468,13 +461,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
|
|||
|
||||
/* Avoid duplicate working_tree entries */
|
||||
FLEX_ALLOC_STR(entry, path, dst_path);
|
||||
hashmap_entry_init(&entry->entry, strhash(dst_path));
|
||||
if (hashmap_get(&working_tree_dups, &entry->entry,
|
||||
NULL)) {
|
||||
hashmap_entry_init(entry, strhash(dst_path));
|
||||
if (hashmap_get(&working_tree_dups, entry, NULL)) {
|
||||
free(entry);
|
||||
continue;
|
||||
}
|
||||
hashmap_add(&working_tree_dups, &entry->entry);
|
||||
hashmap_add(&working_tree_dups, entry);
|
||||
|
||||
if (!use_wt_file(workdir, dst_path, &roid)) {
|
||||
if (checkout_path(rmode, &roid, dst_path,
|
||||
|
|
@ -538,8 +530,8 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
|
|||
* temporary file to both the left and right directories to show the
|
||||
* change in the recorded SHA1 for the submodule.
|
||||
*/
|
||||
hashmap_for_each_entry(&submodules, &iter, entry,
|
||||
entry /* member name */) {
|
||||
hashmap_iter_init(&submodules, &iter);
|
||||
while ((entry = hashmap_iter_next(&iter))) {
|
||||
if (*entry->left) {
|
||||
add_path(&ldir, ldir_len, entry->path);
|
||||
ensure_leading_directories(ldir.buf);
|
||||
|
|
@ -557,8 +549,8 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
|
|||
* shows only the link itself, not the contents of the link target.
|
||||
* This loop replicates that behavior.
|
||||
*/
|
||||
hashmap_for_each_entry(&symlinks2, &iter, entry,
|
||||
entry /* member name */) {
|
||||
hashmap_iter_init(&symlinks2, &iter);
|
||||
while ((entry = hashmap_iter_next(&iter))) {
|
||||
if (*entry->left) {
|
||||
add_path(&ldir, ldir_len, entry->path);
|
||||
ensure_leading_directories(ldir.buf);
|
||||
|
|
|
|||
88
third_party/git/builtin/fast-export.c
vendored
88
third_party/git/builtin/fast-export.c
vendored
|
|
@ -40,7 +40,6 @@ static int no_data;
|
|||
static int full_tree;
|
||||
static int reference_excluded_commits;
|
||||
static int show_original_ids;
|
||||
static int mark_tags;
|
||||
static struct string_list extra_refs = STRING_LIST_INIT_NODUP;
|
||||
static struct string_list tag_refs = STRING_LIST_INIT_NODUP;
|
||||
static struct refspec refspecs = REFSPEC_INIT_FETCH;
|
||||
|
|
@ -127,15 +126,10 @@ struct anonymized_entry {
|
|||
};
|
||||
|
||||
static int anonymized_entry_cmp(const void *unused_cmp_data,
|
||||
const struct hashmap_entry *eptr,
|
||||
const struct hashmap_entry *entry_or_key,
|
||||
const void *va, const void *vb,
|
||||
const void *unused_keydata)
|
||||
{
|
||||
const struct anonymized_entry *a, *b;
|
||||
|
||||
a = container_of(eptr, const struct anonymized_entry, hash);
|
||||
b = container_of(entry_or_key, const struct anonymized_entry, hash);
|
||||
|
||||
const struct anonymized_entry *a = va, *b = vb;
|
||||
return a->orig_len != b->orig_len ||
|
||||
memcmp(a->orig, b->orig, a->orig_len);
|
||||
}
|
||||
|
|
@ -154,10 +148,10 @@ static const void *anonymize_mem(struct hashmap *map,
|
|||
if (!map->cmpfn)
|
||||
hashmap_init(map, anonymized_entry_cmp, NULL, 0);
|
||||
|
||||
hashmap_entry_init(&key.hash, memhash(orig, *len));
|
||||
hashmap_entry_init(&key, memhash(orig, *len));
|
||||
key.orig = orig;
|
||||
key.orig_len = *len;
|
||||
ret = hashmap_get_entry(map, &key, hash, NULL);
|
||||
ret = hashmap_get(map, &key, NULL);
|
||||
|
||||
if (!ret) {
|
||||
ret = xmalloc(sizeof(*ret));
|
||||
|
|
@ -166,7 +160,7 @@ static const void *anonymize_mem(struct hashmap *map,
|
|||
ret->orig_len = *len;
|
||||
ret->anon = generate(orig, len);
|
||||
ret->anon_len = *len;
|
||||
hashmap_put(map, &ret->hash);
|
||||
hashmap_put(map, ret);
|
||||
}
|
||||
|
||||
*len = ret->anon_len;
|
||||
|
|
@ -293,8 +287,7 @@ static void export_blob(const struct object_id *oid)
|
|||
buf = read_object_file(oid, &type, &size);
|
||||
if (!buf)
|
||||
die("could not read blob %s", oid_to_hex(oid));
|
||||
if (check_object_signature(the_repository, oid, buf, size,
|
||||
type_name(type)) < 0)
|
||||
if (check_object_signature(oid, buf, size, type_name(type)) < 0)
|
||||
die("oid mismatch in blob %s", oid_to_hex(oid));
|
||||
object = parse_object_buffer(the_repository, oid, type,
|
||||
size, buf, &eaten);
|
||||
|
|
@ -849,39 +842,25 @@ static void handle_tag(const char *name, struct tag *tag)
|
|||
free(buf);
|
||||
return;
|
||||
case REWRITE:
|
||||
if (tagged->type == OBJ_TAG && !mark_tags) {
|
||||
die(_("Error: Cannot export nested tags unless --mark-tags is specified."));
|
||||
} else if (tagged->type == OBJ_COMMIT) {
|
||||
p = rewrite_commit((struct commit *)tagged);
|
||||
if (!p) {
|
||||
printf("reset %s\nfrom %s\n\n",
|
||||
name, oid_to_hex(&null_oid));
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
tagged_mark = get_object_mark(&p->object);
|
||||
} else {
|
||||
/* tagged->type is either OBJ_BLOB or OBJ_TAG */
|
||||
tagged_mark = get_object_mark(tagged);
|
||||
if (tagged->type != OBJ_COMMIT) {
|
||||
die("tag %s tags unexported %s!",
|
||||
oid_to_hex(&tag->object.oid),
|
||||
type_name(tagged->type));
|
||||
}
|
||||
p = rewrite_commit((struct commit *)tagged);
|
||||
if (!p) {
|
||||
printf("reset %s\nfrom %s\n\n",
|
||||
name, oid_to_hex(&null_oid));
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
tagged_mark = get_object_mark(&p->object);
|
||||
}
|
||||
}
|
||||
|
||||
if (tagged->type == OBJ_TAG) {
|
||||
printf("reset %s\nfrom %s\n\n",
|
||||
name, oid_to_hex(&null_oid));
|
||||
}
|
||||
skip_prefix(name, "refs/tags/", &name);
|
||||
printf("tag %s\n", name);
|
||||
if (mark_tags) {
|
||||
mark_next_object(&tag->object);
|
||||
printf("mark :%"PRIu32"\n", last_idnum);
|
||||
}
|
||||
if (tagged_mark)
|
||||
printf("from :%d\n", tagged_mark);
|
||||
else
|
||||
printf("from %s\n", oid_to_hex(&tagged->oid));
|
||||
|
||||
if (starts_with(name, "refs/tags/"))
|
||||
name += 10;
|
||||
printf("tag %s\nfrom :%d\n", name, tagged_mark);
|
||||
if (show_original_ids)
|
||||
printf("original-oid %s\n", oid_to_hex(&tag->object.oid));
|
||||
printf("%.*s%sdata %d\n%.*s\n",
|
||||
|
|
@ -1068,16 +1047,11 @@ static void export_marks(char *file)
|
|||
error("Unable to write marks file %s.", file);
|
||||
}
|
||||
|
||||
static void import_marks(char *input_file, int check_exists)
|
||||
static void import_marks(char *input_file)
|
||||
{
|
||||
char line[512];
|
||||
FILE *f;
|
||||
struct stat sb;
|
||||
FILE *f = xfopen(input_file, "r");
|
||||
|
||||
if (check_exists && stat(input_file, &sb))
|
||||
return;
|
||||
|
||||
f = xfopen(input_file, "r");
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
uint32_t mark;
|
||||
char *line_end, *mark_end;
|
||||
|
|
@ -1141,9 +1115,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
|
|||
struct rev_info revs;
|
||||
struct object_array commits = OBJECT_ARRAY_INIT;
|
||||
struct commit *commit;
|
||||
char *export_filename = NULL,
|
||||
*import_filename = NULL,
|
||||
*import_filename_if_exists = NULL;
|
||||
char *export_filename = NULL, *import_filename = NULL;
|
||||
uint32_t lastimportid;
|
||||
struct string_list refspecs_list = STRING_LIST_INIT_NODUP;
|
||||
struct string_list paths_of_changed_objects = STRING_LIST_INIT_DUP;
|
||||
|
|
@ -1163,10 +1135,6 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
|
|||
N_("Dump marks to this file")),
|
||||
OPT_STRING(0, "import-marks", &import_filename, N_("file"),
|
||||
N_("Import marks from this file")),
|
||||
OPT_STRING(0, "import-marks-if-exists",
|
||||
&import_filename_if_exists,
|
||||
N_("file"),
|
||||
N_("Import marks from this file if it exists")),
|
||||
OPT_BOOL(0, "fake-missing-tagger", &fake_missing_tagger,
|
||||
N_("Fake a tagger when tags lack one")),
|
||||
OPT_BOOL(0, "full-tree", &full_tree,
|
||||
|
|
@ -1181,8 +1149,6 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
|
|||
&reference_excluded_commits, N_("Reference parents which are not in fast-export stream by object id")),
|
||||
OPT_BOOL(0, "show-original-ids", &show_original_ids,
|
||||
N_("Show original object ids of blobs/commits")),
|
||||
OPT_BOOL(0, "mark-tags", &mark_tags,
|
||||
N_("Label tags with mark ids")),
|
||||
|
||||
OPT_END()
|
||||
};
|
||||
|
|
@ -1216,12 +1182,8 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
|
|||
if (use_done_feature)
|
||||
printf("feature done\n");
|
||||
|
||||
if (import_filename && import_filename_if_exists)
|
||||
die(_("Cannot pass both --import-marks and --import-marks-if-exists"));
|
||||
if (import_filename)
|
||||
import_marks(import_filename, 0);
|
||||
else if (import_filename_if_exists)
|
||||
import_marks(import_filename_if_exists, 1);
|
||||
import_marks(import_filename);
|
||||
lastimportid = last_idnum;
|
||||
|
||||
if (import_filename && revs.prune_data.nr)
|
||||
|
|
|
|||
344
third_party/git/builtin/fetch.c
vendored
344
third_party/git/builtin/fetch.c
vendored
|
|
@ -7,7 +7,6 @@
|
|||
#include "refs.h"
|
||||
#include "refspec.h"
|
||||
#include "object-store.h"
|
||||
#include "oidset.h"
|
||||
#include "commit.h"
|
||||
#include "builtin.h"
|
||||
#include "string-list.h"
|
||||
|
|
@ -24,9 +23,6 @@
|
|||
#include "packfile.h"
|
||||
#include "list-objects-filter-options.h"
|
||||
#include "commit-reach.h"
|
||||
#include "branch.h"
|
||||
#include "promisor-remote.h"
|
||||
#include "commit-graph.h"
|
||||
|
||||
#define FORCED_UPDATES_DELAY_WARNING_IN_MS (10 * 1000)
|
||||
|
||||
|
|
@ -54,13 +50,11 @@ static int fetch_prune_tags_config = -1; /* unspecified */
|
|||
static int prune_tags = -1; /* unspecified */
|
||||
#define PRUNE_TAGS_BY_DEFAULT 0 /* do we prune tags by default? */
|
||||
|
||||
static int all, append, dry_run, force, keep, multiple, update_head_ok;
|
||||
static int verbosity, deepen_relative, set_upstream;
|
||||
static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity, deepen_relative;
|
||||
static int progress = -1;
|
||||
static int enable_auto_gc = 1;
|
||||
static int tags = TAGS_DEFAULT, unshallow, update_shallow, deepen;
|
||||
static int max_jobs = -1, submodule_fetch_jobs_config = -1;
|
||||
static int fetch_parallel_config = 1;
|
||||
static int max_children = 1;
|
||||
static enum transport_family family;
|
||||
static const char *depth;
|
||||
static const char *deepen_since;
|
||||
|
|
@ -77,7 +71,6 @@ static struct refspec refmap = REFSPEC_INIT_FETCH;
|
|||
static struct list_objects_filter_options filter_options;
|
||||
static struct string_list server_options = STRING_LIST_INIT_DUP;
|
||||
static struct string_list negotiation_tip = STRING_LIST_INIT_NODUP;
|
||||
static int fetch_write_commit_graph = -1;
|
||||
|
||||
static int git_fetch_config(const char *k, const char *v, void *cb)
|
||||
{
|
||||
|
|
@ -103,20 +96,13 @@ static int git_fetch_config(const char *k, const char *v, void *cb)
|
|||
}
|
||||
|
||||
if (!strcmp(k, "submodule.fetchjobs")) {
|
||||
submodule_fetch_jobs_config = parse_submodule_fetchjobs(k, v);
|
||||
max_children = parse_submodule_fetchjobs(k, v);
|
||||
return 0;
|
||||
} else if (!strcmp(k, "fetch.recursesubmodules")) {
|
||||
recurse_submodules = parse_fetch_recurse_submodules_arg(k, v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(k, "fetch.parallel")) {
|
||||
fetch_parallel_config = git_config_int(k, v);
|
||||
if (fetch_parallel_config < 0)
|
||||
die(_("fetch.parallel cannot be negative"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return git_default_config(k, v, cb);
|
||||
}
|
||||
|
||||
|
|
@ -137,8 +123,6 @@ static struct option builtin_fetch_options[] = {
|
|||
OPT__VERBOSITY(&verbosity),
|
||||
OPT_BOOL(0, "all", &all,
|
||||
N_("fetch from all remotes")),
|
||||
OPT_BOOL(0, "set-upstream", &set_upstream,
|
||||
N_("set upstream for git pull/fetch")),
|
||||
OPT_BOOL('a', "append", &append,
|
||||
N_("append to .git/FETCH_HEAD instead of overwriting")),
|
||||
OPT_STRING(0, "upload-pack", &upload_pack, N_("path"),
|
||||
|
|
@ -150,7 +134,7 @@ static struct option builtin_fetch_options[] = {
|
|||
N_("fetch all tags and associated objects"), TAGS_SET),
|
||||
OPT_SET_INT('n', NULL, &tags,
|
||||
N_("do not fetch all tags (--no-tags)"), TAGS_UNSET),
|
||||
OPT_INTEGER('j', "jobs", &max_jobs,
|
||||
OPT_INTEGER('j', "jobs", &max_children,
|
||||
N_("number of submodules fetched in parallel")),
|
||||
OPT_BOOL('p', "prune", &prune,
|
||||
N_("prune remote-tracking branches no longer on remote")),
|
||||
|
|
@ -199,8 +183,6 @@ static struct option builtin_fetch_options[] = {
|
|||
N_("run 'gc --auto' after fetching")),
|
||||
OPT_BOOL(0, "show-forced-updates", &fetch_show_forced_updates,
|
||||
N_("check for forced-updates on all updated branches")),
|
||||
OPT_BOOL(0, "write-commit-graph", &fetch_write_commit_graph,
|
||||
N_("write the commit-graph after fetching")),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
|
|
@ -257,31 +239,32 @@ static void add_merge_config(struct ref **head,
|
|||
}
|
||||
}
|
||||
|
||||
static void create_fetch_oidset(struct ref **head, struct oidset *out)
|
||||
static int will_fetch(struct ref **head, const unsigned char *sha1)
|
||||
{
|
||||
struct ref *rm = *head;
|
||||
while (rm) {
|
||||
oidset_insert(out, &rm->old_oid);
|
||||
if (hasheq(rm->old_oid.hash, sha1))
|
||||
return 1;
|
||||
rm = rm->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct refname_hash_entry {
|
||||
struct hashmap_entry ent;
|
||||
struct hashmap_entry ent; /* must be the first member */
|
||||
struct object_id oid;
|
||||
int ignore;
|
||||
char refname[FLEX_ARRAY];
|
||||
};
|
||||
|
||||
static int refname_hash_entry_cmp(const void *hashmap_cmp_fn_data,
|
||||
const struct hashmap_entry *eptr,
|
||||
const struct hashmap_entry *entry_or_key,
|
||||
const void *e1_,
|
||||
const void *e2_,
|
||||
const void *keydata)
|
||||
{
|
||||
const struct refname_hash_entry *e1, *e2;
|
||||
const struct refname_hash_entry *e1 = e1_;
|
||||
const struct refname_hash_entry *e2 = e2_;
|
||||
|
||||
e1 = container_of(eptr, const struct refname_hash_entry, ent);
|
||||
e2 = container_of(entry_or_key, const struct refname_hash_entry, ent);
|
||||
return strcmp(e1->refname, keydata ? keydata : e2->refname);
|
||||
}
|
||||
|
||||
|
|
@ -293,9 +276,9 @@ static struct refname_hash_entry *refname_hash_add(struct hashmap *map,
|
|||
size_t len = strlen(refname);
|
||||
|
||||
FLEX_ALLOC_MEM(ent, refname, refname, len);
|
||||
hashmap_entry_init(&ent->ent, strhash(refname));
|
||||
hashmap_entry_init(ent, strhash(refname));
|
||||
oidcpy(&ent->oid, oid);
|
||||
hashmap_add(map, &ent->ent);
|
||||
hashmap_add(map, ent);
|
||||
return ent;
|
||||
}
|
||||
|
||||
|
|
@ -330,16 +313,13 @@ static void find_non_local_tags(const struct ref *refs,
|
|||
{
|
||||
struct hashmap existing_refs;
|
||||
struct hashmap remote_refs;
|
||||
struct oidset fetch_oids = OIDSET_INIT;
|
||||
struct string_list remote_refs_list = STRING_LIST_INIT_NODUP;
|
||||
struct string_list_item *remote_ref_item;
|
||||
const struct ref *ref;
|
||||
struct refname_hash_entry *item = NULL;
|
||||
const int quick_flags = OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT;
|
||||
|
||||
refname_hash_init(&existing_refs);
|
||||
refname_hash_init(&remote_refs);
|
||||
create_fetch_oidset(head, &fetch_oids);
|
||||
|
||||
for_each_ref(add_one_refname, &existing_refs);
|
||||
for (ref = refs; ref; ref = ref->next) {
|
||||
|
|
@ -354,10 +334,11 @@ static void find_non_local_tags(const struct ref *refs,
|
|||
*/
|
||||
if (ends_with(ref->name, "^{}")) {
|
||||
if (item &&
|
||||
!has_object_file_with_flags(&ref->old_oid, quick_flags) &&
|
||||
!oidset_contains(&fetch_oids, &ref->old_oid) &&
|
||||
!has_object_file_with_flags(&item->oid, quick_flags) &&
|
||||
!oidset_contains(&fetch_oids, &item->oid))
|
||||
!has_object_file_with_flags(&ref->old_oid,
|
||||
OBJECT_INFO_QUICK) &&
|
||||
!will_fetch(head, ref->old_oid.hash) &&
|
||||
!has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) &&
|
||||
!will_fetch(head, item->oid.hash))
|
||||
clear_item(item);
|
||||
item = NULL;
|
||||
continue;
|
||||
|
|
@ -370,8 +351,8 @@ static void find_non_local_tags(const struct ref *refs,
|
|||
* fetch.
|
||||
*/
|
||||
if (item &&
|
||||
!has_object_file_with_flags(&item->oid, quick_flags) &&
|
||||
!oidset_contains(&fetch_oids, &item->oid))
|
||||
!has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) &&
|
||||
!will_fetch(head, item->oid.hash))
|
||||
clear_item(item);
|
||||
|
||||
item = NULL;
|
||||
|
|
@ -384,15 +365,15 @@ static void find_non_local_tags(const struct ref *refs,
|
|||
item = refname_hash_add(&remote_refs, ref->name, &ref->old_oid);
|
||||
string_list_insert(&remote_refs_list, ref->name);
|
||||
}
|
||||
hashmap_free_entries(&existing_refs, struct refname_hash_entry, ent);
|
||||
hashmap_free(&existing_refs, 1);
|
||||
|
||||
/*
|
||||
* We may have a final lightweight tag that needs to be
|
||||
* checked to see if it needs fetching.
|
||||
*/
|
||||
if (item &&
|
||||
!has_object_file_with_flags(&item->oid, quick_flags) &&
|
||||
!oidset_contains(&fetch_oids, &item->oid))
|
||||
!has_object_file_with_flags(&item->oid, OBJECT_INFO_QUICK) &&
|
||||
!will_fetch(head, item->oid.hash))
|
||||
clear_item(item);
|
||||
|
||||
/*
|
||||
|
|
@ -402,10 +383,8 @@ static void find_non_local_tags(const struct ref *refs,
|
|||
for_each_string_list_item(remote_ref_item, &remote_refs_list) {
|
||||
const char *refname = remote_ref_item->string;
|
||||
struct ref *rm;
|
||||
unsigned int hash = strhash(refname);
|
||||
|
||||
item = hashmap_get_entry_from_hash(&remote_refs, hash, refname,
|
||||
struct refname_hash_entry, ent);
|
||||
item = hashmap_get_from_hash(&remote_refs, strhash(refname), refname);
|
||||
if (!item)
|
||||
BUG("unseen remote ref?");
|
||||
|
||||
|
|
@ -419,9 +398,8 @@ static void find_non_local_tags(const struct ref *refs,
|
|||
**tail = rm;
|
||||
*tail = &rm->next;
|
||||
}
|
||||
hashmap_free_entries(&remote_refs, struct refname_hash_entry, ent);
|
||||
hashmap_free(&remote_refs, 1);
|
||||
string_list_clear(&remote_refs_list, 0);
|
||||
oidset_clear(&fetch_oids);
|
||||
}
|
||||
|
||||
static struct ref *get_ref_map(struct remote *remote,
|
||||
|
|
@ -538,18 +516,17 @@ static struct ref *get_ref_map(struct remote *remote,
|
|||
if (rm->peer_ref) {
|
||||
const char *refname = rm->peer_ref->name;
|
||||
struct refname_hash_entry *peer_item;
|
||||
unsigned int hash = strhash(refname);
|
||||
|
||||
peer_item = hashmap_get_entry_from_hash(&existing_refs,
|
||||
hash, refname,
|
||||
struct refname_hash_entry, ent);
|
||||
peer_item = hashmap_get_from_hash(&existing_refs,
|
||||
strhash(refname),
|
||||
refname);
|
||||
if (peer_item) {
|
||||
struct object_id *old_oid = &peer_item->oid;
|
||||
oidcpy(&rm->peer_ref->old_oid, old_oid);
|
||||
}
|
||||
}
|
||||
}
|
||||
hashmap_free_entries(&existing_refs, struct refname_hash_entry, ent);
|
||||
hashmap_free(&existing_refs, 1);
|
||||
|
||||
return ref_map;
|
||||
}
|
||||
|
|
@ -906,17 +883,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
|
|||
url = xstrdup("foreign");
|
||||
|
||||
if (!connectivity_checked) {
|
||||
struct check_connected_options opt = CHECK_CONNECTED_INIT;
|
||||
|
||||
if (filter_options.choice)
|
||||
/*
|
||||
* Since a filter is specified, objects indirectly
|
||||
* referenced by refs are allowed to be absent.
|
||||
*/
|
||||
opt.check_refs_are_promisor_objects_only = 1;
|
||||
|
||||
rm = ref_map;
|
||||
if (check_connected(iterate_ref_map, &rm, &opt)) {
|
||||
if (check_connected(iterate_ref_map, &rm, NULL)) {
|
||||
rc = error(_("%s did not send all necessary objects\n"), url);
|
||||
goto abort;
|
||||
}
|
||||
|
|
@ -966,12 +934,18 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
|
|||
kind = "";
|
||||
what = "";
|
||||
}
|
||||
else if (skip_prefix(rm->name, "refs/heads/", &what))
|
||||
else if (starts_with(rm->name, "refs/heads/")) {
|
||||
kind = "branch";
|
||||
else if (skip_prefix(rm->name, "refs/tags/", &what))
|
||||
what = rm->name + 11;
|
||||
}
|
||||
else if (starts_with(rm->name, "refs/tags/")) {
|
||||
kind = "tag";
|
||||
else if (skip_prefix(rm->name, "refs/remotes/", &what))
|
||||
what = rm->name + 10;
|
||||
}
|
||||
else if (starts_with(rm->name, "refs/remotes/")) {
|
||||
kind = "remote-tracking branch";
|
||||
what = rm->name + 13;
|
||||
}
|
||||
else {
|
||||
kind = "";
|
||||
what = rm->name;
|
||||
|
|
@ -1080,8 +1054,7 @@ static int check_exist_and_connected(struct ref *ref_map)
|
|||
* we need all direct targets to exist.
|
||||
*/
|
||||
for (r = rm; r; r = r->next) {
|
||||
if (!has_object_file_with_flags(&r->old_oid,
|
||||
OBJECT_INFO_SKIP_FETCH_OBJECT))
|
||||
if (!has_object_file(&r->old_oid))
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -1092,11 +1065,8 @@ static int check_exist_and_connected(struct ref *ref_map)
|
|||
static int fetch_refs(struct transport *transport, struct ref *ref_map)
|
||||
{
|
||||
int ret = check_exist_and_connected(ref_map);
|
||||
if (ret) {
|
||||
trace2_region_enter("fetch", "fetch_refs", the_repository);
|
||||
if (ret)
|
||||
ret = transport_fetch_refs(transport, ref_map);
|
||||
trace2_region_leave("fetch", "fetch_refs", the_repository);
|
||||
}
|
||||
if (!ret)
|
||||
/*
|
||||
* Keep the new pack's ".keep" file around to allow the caller
|
||||
|
|
@ -1112,14 +1082,11 @@ static int consume_refs(struct transport *transport, struct ref *ref_map)
|
|||
{
|
||||
int connectivity_checked = transport->smart_options
|
||||
? transport->smart_options->connectivity_checked : 0;
|
||||
int ret;
|
||||
trace2_region_enter("fetch", "consume_refs", the_repository);
|
||||
ret = store_updated_refs(transport->url,
|
||||
transport->remote->name,
|
||||
connectivity_checked,
|
||||
ref_map);
|
||||
int ret = store_updated_refs(transport->url,
|
||||
transport->remote->name,
|
||||
connectivity_checked,
|
||||
ref_map);
|
||||
transport_unlock_pack(transport);
|
||||
trace2_region_leave("fetch", "consume_refs", the_repository);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1271,10 +1238,13 @@ static struct transport *prepare_transport(struct remote *remote, int deepen)
|
|||
if (update_shallow)
|
||||
set_option(transport, TRANS_OPT_UPDATE_SHALLOW, "yes");
|
||||
if (filter_options.choice) {
|
||||
const char *spec =
|
||||
expand_list_objects_filter_spec(&filter_options);
|
||||
set_option(transport, TRANS_OPT_LIST_OBJECTS_FILTER, spec);
|
||||
struct strbuf expanded_filter_spec = STRBUF_INIT;
|
||||
expand_list_objects_filter_spec(&filter_options,
|
||||
&expanded_filter_spec);
|
||||
set_option(transport, TRANS_OPT_LIST_OBJECTS_FILTER,
|
||||
expanded_filter_spec.buf);
|
||||
set_option(transport, TRANS_OPT_FROM_PROMISOR, "1");
|
||||
strbuf_release(&expanded_filter_spec);
|
||||
}
|
||||
if (negotiation_tip.nr) {
|
||||
if (transport->smart_options)
|
||||
|
|
@ -1364,11 +1334,9 @@ static int do_fetch(struct transport *transport,
|
|||
argv_array_push(&ref_prefixes, "refs/tags/");
|
||||
}
|
||||
|
||||
if (must_list_refs) {
|
||||
trace2_region_enter("fetch", "remote_refs", the_repository);
|
||||
if (must_list_refs)
|
||||
remote_refs = transport_get_remote_refs(transport, &ref_prefixes);
|
||||
trace2_region_leave("fetch", "remote_refs", the_repository);
|
||||
} else
|
||||
else
|
||||
remote_refs = NULL;
|
||||
|
||||
argv_array_clear(&ref_prefixes);
|
||||
|
|
@ -1399,51 +1367,6 @@ static int do_fetch(struct transport *transport,
|
|||
retcode = 1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (set_upstream) {
|
||||
struct branch *branch = branch_get("HEAD");
|
||||
struct ref *rm;
|
||||
struct ref *source_ref = NULL;
|
||||
|
||||
/*
|
||||
* We're setting the upstream configuration for the
|
||||
* current branch. The relevant upstream is the
|
||||
* fetched branch that is meant to be merged with the
|
||||
* current one, i.e. the one fetched to FETCH_HEAD.
|
||||
*
|
||||
* When there are several such branches, consider the
|
||||
* request ambiguous and err on the safe side by doing
|
||||
* nothing and just emit a warning.
|
||||
*/
|
||||
for (rm = ref_map; rm; rm = rm->next) {
|
||||
if (!rm->peer_ref) {
|
||||
if (source_ref) {
|
||||
warning(_("multiple branches detected, incompatible with --set-upstream"));
|
||||
goto skip;
|
||||
} else {
|
||||
source_ref = rm;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (source_ref) {
|
||||
if (!strcmp(source_ref->name, "HEAD") ||
|
||||
starts_with(source_ref->name, "refs/heads/"))
|
||||
install_branch_config(0,
|
||||
branch->name,
|
||||
transport->remote->name,
|
||||
source_ref->name);
|
||||
else if (starts_with(source_ref->name, "refs/remotes/"))
|
||||
warning(_("not setting upstream for a remote remote-tracking branch"));
|
||||
else if (starts_with(source_ref->name, "refs/tags/"))
|
||||
warning(_("not setting upstream for a remote tag"));
|
||||
else
|
||||
warning(_("unknown branch type"));
|
||||
} else {
|
||||
warning(_("no source branch found.\n"
|
||||
"you need to specify exactly one branch with the --set-upstream option."));
|
||||
}
|
||||
}
|
||||
skip:
|
||||
free_refs(ref_map);
|
||||
|
||||
/* if neither --no-tags nor --tags was specified, do automated tag
|
||||
|
|
@ -1540,62 +1463,7 @@ static void add_options_to_argv(struct argv_array *argv)
|
|||
|
||||
}
|
||||
|
||||
/* Fetch multiple remotes in parallel */
|
||||
|
||||
struct parallel_fetch_state {
|
||||
const char **argv;
|
||||
struct string_list *remotes;
|
||||
int next, result;
|
||||
};
|
||||
|
||||
static int fetch_next_remote(struct child_process *cp, struct strbuf *out,
|
||||
void *cb, void **task_cb)
|
||||
{
|
||||
struct parallel_fetch_state *state = cb;
|
||||
char *remote;
|
||||
|
||||
if (state->next < 0 || state->next >= state->remotes->nr)
|
||||
return 0;
|
||||
|
||||
remote = state->remotes->items[state->next++].string;
|
||||
*task_cb = remote;
|
||||
|
||||
argv_array_pushv(&cp->args, state->argv);
|
||||
argv_array_push(&cp->args, remote);
|
||||
cp->git_cmd = 1;
|
||||
|
||||
if (verbosity >= 0)
|
||||
printf(_("Fetching %s\n"), remote);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int fetch_failed_to_start(struct strbuf *out, void *cb, void *task_cb)
|
||||
{
|
||||
struct parallel_fetch_state *state = cb;
|
||||
const char *remote = task_cb;
|
||||
|
||||
state->result = error(_("Could not fetch %s"), remote);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fetch_finished(int result, struct strbuf *out,
|
||||
void *cb, void *task_cb)
|
||||
{
|
||||
struct parallel_fetch_state *state = cb;
|
||||
const char *remote = task_cb;
|
||||
|
||||
if (result) {
|
||||
strbuf_addf(out, _("could not fetch '%s' (exit code: %d)\n"),
|
||||
remote, result);
|
||||
state->result = -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fetch_multiple(struct string_list *list, int max_children)
|
||||
static int fetch_multiple(struct string_list *list)
|
||||
{
|
||||
int i, result = 0;
|
||||
struct argv_array argv = ARGV_ARRAY_INIT;
|
||||
|
|
@ -1606,38 +1474,23 @@ static int fetch_multiple(struct string_list *list, int max_children)
|
|||
return errcode;
|
||||
}
|
||||
|
||||
argv_array_pushl(&argv, "fetch", "--append", "--no-auto-gc",
|
||||
"--no-write-commit-graph", NULL);
|
||||
argv_array_pushl(&argv, "fetch", "--append", "--no-auto-gc", NULL);
|
||||
add_options_to_argv(&argv);
|
||||
|
||||
if (max_children != 1 && list->nr != 1) {
|
||||
struct parallel_fetch_state state = { argv.argv, list, 0, 0 };
|
||||
|
||||
argv_array_push(&argv, "--end-of-options");
|
||||
result = run_processes_parallel_tr2(max_children,
|
||||
&fetch_next_remote,
|
||||
&fetch_failed_to_start,
|
||||
&fetch_finished,
|
||||
&state,
|
||||
"fetch", "parallel/fetch");
|
||||
|
||||
if (!result)
|
||||
result = state.result;
|
||||
} else
|
||||
for (i = 0; i < list->nr; i++) {
|
||||
const char *name = list->items[i].string;
|
||||
argv_array_push(&argv, name);
|
||||
if (verbosity >= 0)
|
||||
printf(_("Fetching %s\n"), name);
|
||||
if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {
|
||||
error(_("Could not fetch %s"), name);
|
||||
result = 1;
|
||||
}
|
||||
argv_array_pop(&argv);
|
||||
for (i = 0; i < list->nr; i++) {
|
||||
const char *name = list->items[i].string;
|
||||
argv_array_push(&argv, name);
|
||||
if (verbosity >= 0)
|
||||
printf(_("Fetching %s\n"), name);
|
||||
if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {
|
||||
error(_("Could not fetch %s"), name);
|
||||
result = 1;
|
||||
}
|
||||
argv_array_pop(&argv);
|
||||
}
|
||||
|
||||
argv_array_clear(&argv);
|
||||
return !!result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1657,27 +1510,37 @@ static inline void fetch_one_setup_partial(struct remote *remote)
|
|||
* If no prior partial clone/fetch and the current fetch DID NOT
|
||||
* request a partial-fetch, do a normal fetch.
|
||||
*/
|
||||
if (!has_promisor_remote() && !filter_options.choice)
|
||||
if (!repository_format_partial_clone && !filter_options.choice)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If this is a partial-fetch request, we enable partial on
|
||||
* this repo if not already enabled and remember the given
|
||||
* filter-spec as the default for subsequent fetches to this
|
||||
* remote.
|
||||
* If this is the FIRST partial-fetch request, we enable partial
|
||||
* on this repo and remember the given filter-spec as the default
|
||||
* for subsequent fetches to this remote.
|
||||
*/
|
||||
if (filter_options.choice) {
|
||||
if (!repository_format_partial_clone && filter_options.choice) {
|
||||
partial_clone_register(remote->name, &filter_options);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are currently limited to only ONE promisor remote and only
|
||||
* allow partial-fetches from the promisor remote.
|
||||
*/
|
||||
if (strcmp(remote->name, repository_format_partial_clone)) {
|
||||
if (filter_options.choice)
|
||||
die(_("--filter can only be used with the remote "
|
||||
"configured in extensions.partialClone"));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do a partial-fetch from the promisor remote using either the
|
||||
* explicitly given filter-spec or inherit the filter-spec from
|
||||
* the config.
|
||||
*/
|
||||
if (!filter_options.choice)
|
||||
partial_clone_get_default_filter_spec(&filter_options, remote->name);
|
||||
partial_clone_get_default_filter_spec(&filter_options);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1763,13 +1626,14 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
|
|||
|
||||
packet_trace_identity("fetch");
|
||||
|
||||
fetch_if_missing = 0;
|
||||
|
||||
/* Record the command line for the reflog */
|
||||
strbuf_addstr(&default_rla, "fetch");
|
||||
for (i = 1; i < argc; i++)
|
||||
strbuf_addf(&default_rla, " %s", argv[i]);
|
||||
|
||||
fetch_config_from_gitmodules(&submodule_fetch_jobs_config,
|
||||
&recurse_submodules);
|
||||
fetch_config_from_gitmodules(&max_children, &recurse_submodules);
|
||||
git_config(git_fetch_config, NULL);
|
||||
|
||||
argc = parse_options(argc, argv, prefix,
|
||||
|
|
@ -1797,7 +1661,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
|
|||
if (depth || deepen_since || deepen_not.nr)
|
||||
deepen = 1;
|
||||
|
||||
if (filter_options.choice && !has_promisor_remote())
|
||||
if (filter_options.choice && !repository_format_partial_clone)
|
||||
die("--filter can only be used when extensions.partialClone is set");
|
||||
|
||||
if (all) {
|
||||
|
|
@ -1831,31 +1695,19 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
|
||||
if (remote) {
|
||||
if (filter_options.choice || has_promisor_remote())
|
||||
if (filter_options.choice || repository_format_partial_clone)
|
||||
fetch_one_setup_partial(remote);
|
||||
result = fetch_one(remote, argc, argv, prune_tags_ok);
|
||||
} else {
|
||||
int max_children = max_jobs;
|
||||
|
||||
if (filter_options.choice)
|
||||
die(_("--filter can only be used with the remote "
|
||||
"configured in extensions.partialclone"));
|
||||
|
||||
if (max_children < 0)
|
||||
max_children = fetch_parallel_config;
|
||||
|
||||
/* TODO should this also die if we have a previous partial-clone? */
|
||||
result = fetch_multiple(&list, max_children);
|
||||
result = fetch_multiple(&list);
|
||||
}
|
||||
|
||||
if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF)) {
|
||||
struct argv_array options = ARGV_ARRAY_INIT;
|
||||
int max_children = max_jobs;
|
||||
|
||||
if (max_children < 0)
|
||||
max_children = submodule_fetch_jobs_config;
|
||||
if (max_children < 0)
|
||||
max_children = fetch_parallel_config;
|
||||
|
||||
add_options_to_argv(&options);
|
||||
result = fetch_populated_submodules(the_repository,
|
||||
|
|
@ -1870,20 +1722,6 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
|
|||
|
||||
string_list_clear(&list, 0);
|
||||
|
||||
prepare_repo_settings(the_repository);
|
||||
if (fetch_write_commit_graph > 0 ||
|
||||
(fetch_write_commit_graph < 0 &&
|
||||
the_repository->settings.fetch_write_commit_graph)) {
|
||||
int commit_graph_flags = COMMIT_GRAPH_WRITE_SPLIT;
|
||||
|
||||
if (progress)
|
||||
commit_graph_flags |= COMMIT_GRAPH_WRITE_PROGRESS;
|
||||
|
||||
write_commit_graph_reachable(the_repository->objects->odb,
|
||||
commit_graph_flags,
|
||||
NULL);
|
||||
}
|
||||
|
||||
close_object_store(the_repository->objects);
|
||||
|
||||
if (enable_auto_gc) {
|
||||
|
|
|
|||
9
third_party/git/builtin/fmt-merge-msg.c
vendored
9
third_party/git/builtin/fmt-merge-msg.c
vendored
|
|
@ -106,7 +106,7 @@ static int handle_line(char *line, struct merge_parents *merge_parents)
|
|||
int i, len = strlen(line);
|
||||
struct origin_data *origin_data;
|
||||
char *src;
|
||||
const char *origin, *tag_name;
|
||||
const char *origin;
|
||||
struct src_data *src_data;
|
||||
struct string_list_item *item;
|
||||
int pulling_head = 0;
|
||||
|
|
@ -162,13 +162,14 @@ static int handle_line(char *line, struct merge_parents *merge_parents)
|
|||
if (pulling_head) {
|
||||
origin = src;
|
||||
src_data->head_status |= 1;
|
||||
} else if (skip_prefix(line, "branch ", &origin)) {
|
||||
} else if (starts_with(line, "branch ")) {
|
||||
origin_data->is_local_branch = 1;
|
||||
origin = line + 7;
|
||||
string_list_append(&src_data->branch, origin);
|
||||
src_data->head_status |= 2;
|
||||
} else if (skip_prefix(line, "tag ", &tag_name)) {
|
||||
} else if (starts_with(line, "tag ")) {
|
||||
origin = line;
|
||||
string_list_append(&src_data->tag, tag_name);
|
||||
string_list_append(&src_data->tag, origin + 4);
|
||||
src_data->head_status |= 2;
|
||||
} else if (skip_prefix(line, "remote-tracking branch ", &origin)) {
|
||||
string_list_append(&src_data->r_branch, origin);
|
||||
|
|
|
|||
126
third_party/git/builtin/fsck.c
vendored
126
third_party/git/builtin/fsck.c
vendored
|
|
@ -50,20 +50,40 @@ static int name_objects;
|
|||
#define ERROR_REFS 010
|
||||
#define ERROR_COMMIT_GRAPH 020
|
||||
|
||||
static const char *describe_object(const struct object_id *oid)
|
||||
static const char *describe_object(struct object *obj)
|
||||
{
|
||||
return fsck_describe_object(&fsck_walk_options, oid);
|
||||
static struct strbuf bufs[] = {
|
||||
STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT
|
||||
};
|
||||
static int b = 0;
|
||||
struct strbuf *buf;
|
||||
char *name = NULL;
|
||||
|
||||
if (name_objects)
|
||||
name = lookup_decoration(fsck_walk_options.object_names, obj);
|
||||
|
||||
buf = bufs + b;
|
||||
b = (b + 1) % ARRAY_SIZE(bufs);
|
||||
strbuf_reset(buf);
|
||||
strbuf_addstr(buf, oid_to_hex(&obj->oid));
|
||||
if (name)
|
||||
strbuf_addf(buf, " (%s)", name);
|
||||
|
||||
return buf->buf;
|
||||
}
|
||||
|
||||
static const char *printable_type(const struct object_id *oid,
|
||||
enum object_type type)
|
||||
static const char *printable_type(struct object *obj)
|
||||
{
|
||||
const char *ret;
|
||||
|
||||
if (type == OBJ_NONE)
|
||||
type = oid_object_info(the_repository, oid, NULL);
|
||||
if (obj->type == OBJ_NONE) {
|
||||
enum object_type type = oid_object_info(the_repository,
|
||||
&obj->oid, NULL);
|
||||
if (type > 0)
|
||||
object_as_type(the_repository, obj, type, 0);
|
||||
}
|
||||
|
||||
ret = type_name(type);
|
||||
ret = type_name(obj->type);
|
||||
if (!ret)
|
||||
ret = _("unknown");
|
||||
|
||||
|
|
@ -98,32 +118,26 @@ static int objerror(struct object *obj, const char *err)
|
|||
errors_found |= ERROR_OBJECT;
|
||||
/* TRANSLATORS: e.g. error in tree 01bfda: <more explanation> */
|
||||
fprintf_ln(stderr, _("error in %s %s: %s"),
|
||||
printable_type(&obj->oid, obj->type),
|
||||
describe_object(&obj->oid), err);
|
||||
printable_type(obj), describe_object(obj), err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int fsck_error_func(struct fsck_options *o,
|
||||
const struct object_id *oid,
|
||||
enum object_type object_type,
|
||||
int msg_type, const char *message)
|
||||
struct object *obj, int type, const char *message)
|
||||
{
|
||||
switch (msg_type) {
|
||||
switch (type) {
|
||||
case FSCK_WARN:
|
||||
/* TRANSLATORS: e.g. warning in tree 01bfda: <more explanation> */
|
||||
fprintf_ln(stderr, _("warning in %s %s: %s"),
|
||||
printable_type(oid, object_type),
|
||||
describe_object(oid), message);
|
||||
printable_type(obj), describe_object(obj), message);
|
||||
return 0;
|
||||
case FSCK_ERROR:
|
||||
/* TRANSLATORS: e.g. error in tree 01bfda: <more explanation> */
|
||||
fprintf_ln(stderr, _("error in %s %s: %s"),
|
||||
printable_type(oid, object_type),
|
||||
describe_object(oid), message);
|
||||
printable_type(obj), describe_object(obj), message);
|
||||
return 1;
|
||||
default:
|
||||
BUG("%d (FSCK_IGNORE?) should never trigger this callback",
|
||||
msg_type);
|
||||
BUG("%d (FSCK_IGNORE?) should never trigger this callback", type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -141,8 +155,7 @@ static int mark_object(struct object *obj, int type, void *data, struct fsck_opt
|
|||
if (!obj) {
|
||||
/* ... these references to parent->fld are safe here */
|
||||
printf_ln(_("broken link from %7s %s"),
|
||||
printable_type(&parent->oid, parent->type),
|
||||
describe_object(&parent->oid));
|
||||
printable_type(parent), describe_object(parent));
|
||||
printf_ln(_("broken link from %7s %s"),
|
||||
(type == OBJ_ANY ? _("unknown") : type_name(type)),
|
||||
_("unknown"));
|
||||
|
|
@ -170,10 +183,10 @@ static int mark_object(struct object *obj, int type, void *data, struct fsck_opt
|
|||
if (parent && !has_object_file(&obj->oid)) {
|
||||
printf_ln(_("broken link from %7s %s\n"
|
||||
" to %7s %s"),
|
||||
printable_type(&parent->oid, parent->type),
|
||||
describe_object(&parent->oid),
|
||||
printable_type(&obj->oid, obj->type),
|
||||
describe_object(&obj->oid));
|
||||
printable_type(parent),
|
||||
describe_object(parent),
|
||||
printable_type(obj),
|
||||
describe_object(obj));
|
||||
errors_found |= ERROR_REACHABLE;
|
||||
}
|
||||
return 1;
|
||||
|
|
@ -279,9 +292,8 @@ static void check_reachable_object(struct object *obj)
|
|||
return;
|
||||
if (has_object_pack(&obj->oid))
|
||||
return; /* it is in pack - forget about it */
|
||||
printf_ln(_("missing %s %s"),
|
||||
printable_type(&obj->oid, obj->type),
|
||||
describe_object(&obj->oid));
|
||||
printf_ln(_("missing %s %s"), printable_type(obj),
|
||||
describe_object(obj));
|
||||
errors_found |= ERROR_REACHABLE;
|
||||
return;
|
||||
}
|
||||
|
|
@ -306,9 +318,8 @@ static void check_unreachable_object(struct object *obj)
|
|||
* since this is something that is prunable.
|
||||
*/
|
||||
if (show_unreachable) {
|
||||
printf_ln(_("unreachable %s %s"),
|
||||
printable_type(&obj->oid, obj->type),
|
||||
describe_object(&obj->oid));
|
||||
printf_ln(_("unreachable %s %s"), printable_type(obj),
|
||||
describe_object(obj));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -326,13 +337,12 @@ static void check_unreachable_object(struct object *obj)
|
|||
*/
|
||||
if (!(obj->flags & USED)) {
|
||||
if (show_dangling)
|
||||
printf_ln(_("dangling %s %s"),
|
||||
printable_type(&obj->oid, obj->type),
|
||||
describe_object(&obj->oid));
|
||||
printf_ln(_("dangling %s %s"), printable_type(obj),
|
||||
describe_object(obj));
|
||||
if (write_lost_and_found) {
|
||||
char *filename = git_pathdup("lost-found/%s/%s",
|
||||
obj->type == OBJ_COMMIT ? "commit" : "other",
|
||||
describe_object(&obj->oid));
|
||||
describe_object(obj));
|
||||
FILE *f;
|
||||
|
||||
if (safe_create_leading_directories_const(filename)) {
|
||||
|
|
@ -345,7 +355,7 @@ static void check_unreachable_object(struct object *obj)
|
|||
if (stream_blob_to_fd(fileno(f), &obj->oid, NULL, 1))
|
||||
die_errno(_("could not write '%s'"), filename);
|
||||
} else
|
||||
fprintf(f, "%s\n", describe_object(&obj->oid));
|
||||
fprintf(f, "%s\n", describe_object(obj));
|
||||
if (fclose(f))
|
||||
die_errno(_("could not finish '%s'"),
|
||||
filename);
|
||||
|
|
@ -364,7 +374,7 @@ static void check_unreachable_object(struct object *obj)
|
|||
static void check_object(struct object *obj)
|
||||
{
|
||||
if (verbose)
|
||||
fprintf_ln(stderr, _("Checking %s"), describe_object(&obj->oid));
|
||||
fprintf_ln(stderr, _("Checking %s"), describe_object(obj));
|
||||
|
||||
if (obj->flags & REACHABLE)
|
||||
check_reachable_object(obj);
|
||||
|
|
@ -422,8 +432,7 @@ static int fsck_obj(struct object *obj, void *buffer, unsigned long size)
|
|||
|
||||
if (verbose)
|
||||
fprintf_ln(stderr, _("Checking %s %s"),
|
||||
printable_type(&obj->oid, obj->type),
|
||||
describe_object(&obj->oid));
|
||||
printable_type(obj), describe_object(obj));
|
||||
|
||||
if (fsck_walk(obj, NULL, &fsck_obj_options))
|
||||
objerror(obj, _("broken links"));
|
||||
|
|
@ -436,7 +445,7 @@ static int fsck_obj(struct object *obj, void *buffer, unsigned long size)
|
|||
|
||||
if (!commit->parents && show_root)
|
||||
printf_ln(_("root %s"),
|
||||
describe_object(&commit->object.oid));
|
||||
describe_object(&commit->object));
|
||||
}
|
||||
|
||||
if (obj->type == OBJ_TAG) {
|
||||
|
|
@ -444,10 +453,10 @@ static int fsck_obj(struct object *obj, void *buffer, unsigned long size)
|
|||
|
||||
if (show_tags && tag->tagged) {
|
||||
printf_ln(_("tagged %s %s (%s) in %s"),
|
||||
printable_type(&tag->tagged->oid, tag->tagged->type),
|
||||
describe_object(&tag->tagged->oid),
|
||||
printable_type(tag->tagged),
|
||||
describe_object(tag->tagged),
|
||||
tag->tag,
|
||||
describe_object(&tag->object.oid));
|
||||
describe_object(&tag->object));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -490,10 +499,10 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid,
|
|||
if (!is_null_oid(oid)) {
|
||||
obj = lookup_object(the_repository, oid);
|
||||
if (obj && (obj->flags & HAS_OBJ)) {
|
||||
if (timestamp)
|
||||
fsck_put_object_name(&fsck_walk_options, oid,
|
||||
"%s@{%"PRItime"}",
|
||||
refname, timestamp);
|
||||
if (timestamp && name_objects)
|
||||
add_decoration(fsck_walk_options.object_names,
|
||||
obj,
|
||||
xstrfmt("%s@{%"PRItime"}", refname, timestamp));
|
||||
obj->flags |= USED;
|
||||
mark_object_reachable(obj);
|
||||
} else if (!is_promisor_object(oid)) {
|
||||
|
|
@ -557,8 +566,9 @@ static int fsck_handle_ref(const char *refname, const struct object_id *oid,
|
|||
}
|
||||
default_refs++;
|
||||
obj->flags |= USED;
|
||||
fsck_put_object_name(&fsck_walk_options,
|
||||
oid, "%s", refname);
|
||||
if (name_objects)
|
||||
add_decoration(fsck_walk_options.object_names,
|
||||
obj, xstrdup(refname));
|
||||
mark_object_reachable(obj);
|
||||
|
||||
return 0;
|
||||
|
|
@ -732,7 +742,9 @@ static int fsck_cache_tree(struct cache_tree *it)
|
|||
return 1;
|
||||
}
|
||||
obj->flags |= USED;
|
||||
fsck_put_object_name(&fsck_walk_options, &it->oid, ":");
|
||||
if (name_objects)
|
||||
add_decoration(fsck_walk_options.object_names,
|
||||
obj, xstrdup(":"));
|
||||
mark_object_reachable(obj);
|
||||
if (obj->type != OBJ_TREE)
|
||||
err |= objerror(obj, _("non-tree in cache-tree"));
|
||||
|
|
@ -818,7 +830,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
|
||||
if (name_objects)
|
||||
fsck_enable_object_names(&fsck_walk_options);
|
||||
fsck_walk_options.object_names =
|
||||
xcalloc(1, sizeof(struct decoration));
|
||||
|
||||
git_config(fsck_config, NULL);
|
||||
|
||||
|
|
@ -877,8 +890,9 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
|
||||
obj->flags |= USED;
|
||||
fsck_put_object_name(&fsck_walk_options, &oid,
|
||||
"%s", arg);
|
||||
if (name_objects)
|
||||
add_decoration(fsck_walk_options.object_names,
|
||||
obj, xstrdup(arg));
|
||||
mark_object_reachable(obj);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -914,8 +928,10 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
|
|||
continue;
|
||||
obj = &blob->object;
|
||||
obj->flags |= USED;
|
||||
fsck_put_object_name(&fsck_walk_options, &obj->oid,
|
||||
":%s", active_cache[i]->name);
|
||||
if (name_objects)
|
||||
add_decoration(fsck_walk_options.object_names,
|
||||
obj,
|
||||
xstrfmt(":%s", active_cache[i]->name));
|
||||
mark_object_reachable(obj);
|
||||
}
|
||||
if (active_cache_tree)
|
||||
|
|
|
|||
19
third_party/git/builtin/gc.c
vendored
19
third_party/git/builtin/gc.c
vendored
|
|
@ -27,7 +27,6 @@
|
|||
#include "pack-objects.h"
|
||||
#include "blob.h"
|
||||
#include "tree.h"
|
||||
#include "promisor-remote.h"
|
||||
|
||||
#define FAILED_RUN "failed to run %s"
|
||||
|
||||
|
|
@ -42,6 +41,7 @@ static int aggressive_depth = 50;
|
|||
static int aggressive_window = 250;
|
||||
static int gc_auto_threshold = 6700;
|
||||
static int gc_auto_pack_limit = 50;
|
||||
static int gc_write_commit_graph;
|
||||
static int detach_auto = 1;
|
||||
static timestamp_t gc_log_expire_time;
|
||||
static const char *gc_log_expire = "1.day.ago";
|
||||
|
|
@ -148,6 +148,7 @@ static void gc_config(void)
|
|||
git_config_get_int("gc.aggressivedepth", &aggressive_depth);
|
||||
git_config_get_int("gc.auto", &gc_auto_threshold);
|
||||
git_config_get_int("gc.autopacklimit", &gc_auto_pack_limit);
|
||||
git_config_get_bool("gc.writecommitgraph", &gc_write_commit_graph);
|
||||
git_config_get_bool("gc.autodetach", &detach_auto);
|
||||
git_config_get_expiry("gc.pruneexpire", &prune_expire);
|
||||
git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire);
|
||||
|
|
@ -458,7 +459,7 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
|
|||
/*
|
||||
* Returns 0 if there was no previous error and gc can proceed, 1 if
|
||||
* gc should not proceed due to an error in the last run. Prints a
|
||||
* message and returns -1 if an error occurred while reading gc.log
|
||||
* message and returns -1 if an error occured while reading gc.log
|
||||
*/
|
||||
static int report_last_gc_error(void)
|
||||
{
|
||||
|
|
@ -601,7 +602,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
|
|||
if (detach_auto) {
|
||||
int ret = report_last_gc_error();
|
||||
if (ret < 0)
|
||||
/* an I/O error occurred, already reported */
|
||||
/* an I/O error occured, already reported */
|
||||
exit(128);
|
||||
if (ret == 1)
|
||||
/* Last gc --auto failed. Skip this one. */
|
||||
|
|
@ -660,7 +661,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
|
|||
argv_array_push(&prune, prune_expire);
|
||||
if (quiet)
|
||||
argv_array_push(&prune, "--no-progress");
|
||||
if (has_promisor_remote())
|
||||
if (repository_format_partial_clone)
|
||||
argv_array_push(&prune,
|
||||
"--exclude-promisor-objects");
|
||||
if (run_command_v_opt(prune.argv, RUN_GIT_CMD))
|
||||
|
|
@ -684,11 +685,11 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
|
|||
clean_pack_garbage();
|
||||
}
|
||||
|
||||
prepare_repo_settings(the_repository);
|
||||
if (the_repository->settings.gc_write_commit_graph == 1)
|
||||
write_commit_graph_reachable(the_repository->objects->odb,
|
||||
!quiet && !daemonized ? COMMIT_GRAPH_WRITE_PROGRESS : 0,
|
||||
NULL);
|
||||
if (gc_write_commit_graph &&
|
||||
write_commit_graph_reachable(get_object_directory(),
|
||||
!quiet && !daemonized ? COMMIT_GRAPH_PROGRESS : 0,
|
||||
NULL))
|
||||
return 1;
|
||||
|
||||
if (auto_gc && too_many_loose_objects())
|
||||
warning(_("There are too many unreachable loose objects; "
|
||||
|
|
|
|||
117
third_party/git/builtin/grep.c
vendored
117
third_party/git/builtin/grep.c
vendored
|
|
@ -24,7 +24,6 @@
|
|||
#include "submodule.h"
|
||||
#include "submodule-config.h"
|
||||
#include "object-store.h"
|
||||
#include "packfile.h"
|
||||
|
||||
static char const * const grep_usage[] = {
|
||||
N_("git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"),
|
||||
|
|
@ -33,6 +32,7 @@ static char const * const grep_usage[] = {
|
|||
|
||||
static int recurse_submodules;
|
||||
|
||||
#define GREP_NUM_THREADS_DEFAULT 8
|
||||
static int num_threads;
|
||||
|
||||
static pthread_t *threads;
|
||||
|
|
@ -91,11 +91,8 @@ static pthread_cond_t cond_result;
|
|||
|
||||
static int skip_first_line;
|
||||
|
||||
static void add_work(struct grep_opt *opt, struct grep_source *gs)
|
||||
static void add_work(struct grep_opt *opt, const struct grep_source *gs)
|
||||
{
|
||||
if (opt->binary != GREP_BINARY_TEXT)
|
||||
grep_source_load_driver(gs, opt->repo->index);
|
||||
|
||||
grep_lock();
|
||||
|
||||
while ((todo_end+1) % ARRAY_SIZE(todo) == todo_done) {
|
||||
|
|
@ -103,6 +100,9 @@ static void add_work(struct grep_opt *opt, struct grep_source *gs)
|
|||
}
|
||||
|
||||
todo[todo_end].source = *gs;
|
||||
if (opt->binary != GREP_BINARY_TEXT)
|
||||
grep_source_load_driver(&todo[todo_end].source,
|
||||
opt->repo->index);
|
||||
todo[todo_end].done = 0;
|
||||
strbuf_reset(&todo[todo_end].out);
|
||||
todo_end = (todo_end + 1) % ARRAY_SIZE(todo);
|
||||
|
|
@ -200,12 +200,12 @@ static void start_threads(struct grep_opt *opt)
|
|||
int i;
|
||||
|
||||
pthread_mutex_init(&grep_mutex, NULL);
|
||||
pthread_mutex_init(&grep_read_mutex, NULL);
|
||||
pthread_mutex_init(&grep_attr_mutex, NULL);
|
||||
pthread_cond_init(&cond_add, NULL);
|
||||
pthread_cond_init(&cond_write, NULL);
|
||||
pthread_cond_init(&cond_result, NULL);
|
||||
grep_use_locks = 1;
|
||||
enable_obj_read_lock();
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(todo); i++) {
|
||||
strbuf_init(&todo[i].out, 0);
|
||||
|
|
@ -257,12 +257,12 @@ static int wait_all(void)
|
|||
free(threads);
|
||||
|
||||
pthread_mutex_destroy(&grep_mutex);
|
||||
pthread_mutex_destroy(&grep_read_mutex);
|
||||
pthread_mutex_destroy(&grep_attr_mutex);
|
||||
pthread_cond_destroy(&cond_add);
|
||||
pthread_cond_destroy(&cond_write);
|
||||
pthread_cond_destroy(&cond_result);
|
||||
grep_use_locks = 0;
|
||||
disable_obj_read_lock();
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
|
@ -295,6 +295,16 @@ static int grep_cmd_config(const char *var, const char *value, void *cb)
|
|||
return st;
|
||||
}
|
||||
|
||||
static void *lock_and_read_oid_file(const struct object_id *oid, enum object_type *type, unsigned long *size)
|
||||
{
|
||||
void *data;
|
||||
|
||||
grep_read_lock();
|
||||
data = read_object_file(oid, type, size);
|
||||
grep_read_unlock();
|
||||
return data;
|
||||
}
|
||||
|
||||
static int grep_oid(struct grep_opt *opt, const struct object_id *oid,
|
||||
const char *filename, int tree_name_len,
|
||||
const char *path)
|
||||
|
|
@ -393,32 +403,34 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
|
|||
static int grep_submodule(struct grep_opt *opt,
|
||||
const struct pathspec *pathspec,
|
||||
const struct object_id *oid,
|
||||
const char *filename, const char *path, int cached)
|
||||
const char *filename, const char *path)
|
||||
{
|
||||
struct repository subrepo;
|
||||
struct repository *superproject = opt->repo;
|
||||
const struct submodule *sub;
|
||||
const struct submodule *sub = submodule_from_path(superproject,
|
||||
&null_oid, path);
|
||||
struct grep_opt subopt;
|
||||
int hit;
|
||||
|
||||
sub = submodule_from_path(superproject, &null_oid, path);
|
||||
|
||||
if (!is_submodule_active(superproject, path))
|
||||
return 0;
|
||||
|
||||
if (repo_submodule_init(&subrepo, superproject, sub))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* NEEDSWORK: repo_read_gitmodules() might call
|
||||
* add_to_alternates_memory() via config_from_gitmodules(). This
|
||||
* operation causes a race condition with concurrent object readings
|
||||
* performed by the worker threads. That's why we need obj_read_lock()
|
||||
* here. It should be removed once it's no longer necessary to add the
|
||||
* subrepo's odbs to the in-memory alternates list.
|
||||
* NEEDSWORK: submodules functions need to be protected because they
|
||||
* access the object store via config_from_gitmodules(): the latter
|
||||
* uses get_oid() which, for now, relies on the global the_repository
|
||||
* object.
|
||||
*/
|
||||
obj_read_lock();
|
||||
repo_read_gitmodules(&subrepo, 0);
|
||||
grep_read_lock();
|
||||
|
||||
if (!is_submodule_active(superproject, path)) {
|
||||
grep_read_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (repo_submodule_init(&subrepo, superproject, sub)) {
|
||||
grep_read_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
repo_read_gitmodules(&subrepo);
|
||||
|
||||
/*
|
||||
* NEEDSWORK: This adds the submodule's object directory to the list of
|
||||
|
|
@ -431,7 +443,7 @@ static int grep_submodule(struct grep_opt *opt,
|
|||
* object.
|
||||
*/
|
||||
add_to_alternates_memory(subrepo.objects->odb->path);
|
||||
obj_read_unlock();
|
||||
grep_read_unlock();
|
||||
|
||||
memcpy(&subopt, opt, sizeof(subopt));
|
||||
subopt.repo = &subrepo;
|
||||
|
|
@ -443,12 +455,14 @@ static int grep_submodule(struct grep_opt *opt,
|
|||
unsigned long size;
|
||||
struct strbuf base = STRBUF_INIT;
|
||||
|
||||
obj_read_lock();
|
||||
object = parse_object_or_die(oid, oid_to_hex(oid));
|
||||
obj_read_unlock();
|
||||
|
||||
grep_read_lock();
|
||||
data = read_object_with_reference(&subrepo,
|
||||
&object->oid, tree_type,
|
||||
&size, NULL);
|
||||
grep_read_unlock();
|
||||
|
||||
if (!data)
|
||||
die(_("unable to read tree (%s)"), oid_to_hex(&object->oid));
|
||||
|
||||
|
|
@ -461,7 +475,7 @@ static int grep_submodule(struct grep_opt *opt,
|
|||
strbuf_release(&base);
|
||||
free(data);
|
||||
} else {
|
||||
hit = grep_cache(&subopt, pathspec, cached);
|
||||
hit = grep_cache(&subopt, pathspec, 1);
|
||||
}
|
||||
|
||||
repo_clear(&subrepo);
|
||||
|
|
@ -509,8 +523,7 @@ static int grep_cache(struct grep_opt *opt,
|
|||
}
|
||||
} else if (recurse_submodules && S_ISGITLINK(ce->ce_mode) &&
|
||||
submodule_path_match(repo->index, pathspec, name.buf, NULL)) {
|
||||
hit |= grep_submodule(opt, pathspec, NULL, ce->name,
|
||||
ce->name, cached);
|
||||
hit |= grep_submodule(opt, pathspec, NULL, ce->name, ce->name);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -573,7 +586,7 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
|
|||
void *data;
|
||||
unsigned long size;
|
||||
|
||||
data = read_object_file(&entry.oid, &type, &size);
|
||||
data = lock_and_read_oid_file(&entry.oid, &type, &size);
|
||||
if (!data)
|
||||
die(_("unable to read tree (%s)"),
|
||||
oid_to_hex(&entry.oid));
|
||||
|
|
@ -585,8 +598,7 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
|
|||
free(data);
|
||||
} else if (recurse_submodules && S_ISGITLINK(entry.mode)) {
|
||||
hit |= grep_submodule(opt, pathspec, &entry.oid,
|
||||
base->buf, base->buf + tn_len,
|
||||
1); /* ignored */
|
||||
base->buf, base->buf + tn_len);
|
||||
}
|
||||
|
||||
strbuf_setlen(base, old_baselen);
|
||||
|
|
@ -611,9 +623,12 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
|
|||
struct strbuf base;
|
||||
int hit, len;
|
||||
|
||||
grep_read_lock();
|
||||
data = read_object_with_reference(opt->repo,
|
||||
&obj->oid, tree_type,
|
||||
&size, NULL);
|
||||
grep_read_unlock();
|
||||
|
||||
if (!data)
|
||||
die(_("unable to read tree (%s)"), oid_to_hex(&obj->oid));
|
||||
|
||||
|
|
@ -642,18 +657,13 @@ static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
|
|||
|
||||
for (i = 0; i < nr; i++) {
|
||||
struct object *real_obj;
|
||||
|
||||
obj_read_lock();
|
||||
real_obj = deref_tag(opt->repo, list->objects[i].item,
|
||||
NULL, 0);
|
||||
obj_read_unlock();
|
||||
|
||||
/* load the gitmodules file for this rev */
|
||||
if (recurse_submodules) {
|
||||
submodule_free(opt->repo);
|
||||
obj_read_lock();
|
||||
gitmodules_config_oid(&real_obj->oid);
|
||||
obj_read_unlock();
|
||||
}
|
||||
if (grep_object(opt, pathspec, real_obj, list->objects[i].name,
|
||||
list->objects[i].path)) {
|
||||
|
|
@ -946,9 +956,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||
/* die the same way as if we did it at the beginning */
|
||||
setup_git_directory();
|
||||
}
|
||||
/* Ignore --recurse-submodules if --no-index is given or implied */
|
||||
if (!use_index)
|
||||
recurse_submodules = 0;
|
||||
|
||||
/*
|
||||
* skip a -- separator; we know it cannot be
|
||||
|
|
@ -1053,10 +1060,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||
pathspec.recursive = 1;
|
||||
pathspec.recurse_submodules = !!recurse_submodules;
|
||||
|
||||
if (recurse_submodules && untracked)
|
||||
die(_("--untracked not supported with --recurse-submodules"));
|
||||
|
||||
if (show_in_pager) {
|
||||
if (list.nr || cached || show_in_pager) {
|
||||
if (num_threads > 1)
|
||||
warning(_("invalid option combination, ignoring --threads"));
|
||||
num_threads = 1;
|
||||
|
|
@ -1066,7 +1070,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||
} else if (num_threads < 0)
|
||||
die(_("invalid number of threads specified (%d)"), num_threads);
|
||||
else if (num_threads == 0)
|
||||
num_threads = HAVE_THREADS ? online_cpus() : 1;
|
||||
num_threads = HAVE_THREADS ? GREP_NUM_THREADS_DEFAULT : 1;
|
||||
|
||||
if (num_threads > 1) {
|
||||
if (!HAVE_THREADS)
|
||||
|
|
@ -1075,17 +1079,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||
&& (opt.pre_context || opt.post_context ||
|
||||
opt.file_break || opt.funcbody))
|
||||
skip_first_line = 1;
|
||||
|
||||
/*
|
||||
* Pre-read gitmodules (if not read already) and force eager
|
||||
* initialization of packed_git to prevent racy lazy
|
||||
* reading/initialization once worker threads are started.
|
||||
*/
|
||||
if (recurse_submodules)
|
||||
repo_read_gitmodules(the_repository, 1);
|
||||
if (startup_info->have_repository)
|
||||
(void)get_packed_git(the_repository);
|
||||
|
||||
start_threads(&opt);
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -1115,11 +1108,14 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||
strbuf_addf(&buf, "+/%s%s",
|
||||
strcmp("less", pager) ? "" : "*",
|
||||
opt.pattern_list->pattern);
|
||||
string_list_append(&path_list,
|
||||
strbuf_detach(&buf, NULL));
|
||||
string_list_append(&path_list, buf.buf);
|
||||
strbuf_detach(&buf, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (recurse_submodules && (!use_index || untracked))
|
||||
die(_("option not supported with --recurse-submodules"));
|
||||
|
||||
if (!show_in_pager && !opt.status_only)
|
||||
setup_pager();
|
||||
|
||||
|
|
@ -1149,6 +1145,5 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||
run_pager(&opt, prefix);
|
||||
clear_pathspec(&pathspec);
|
||||
free_grep_patterns(&opt);
|
||||
grep_destroy();
|
||||
return !hit;
|
||||
}
|
||||
|
|
|
|||
26
third_party/git/builtin/index-pack.c
vendored
26
third_party/git/builtin/index-pack.c
vendored
|
|
@ -14,7 +14,7 @@
|
|||
#include "thread-utils.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
#include "promisor-remote.h"
|
||||
#include "fetch-object.h"
|
||||
|
||||
static const char index_pack_usage[] =
|
||||
"git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--verify] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
|
||||
|
|
@ -757,8 +757,7 @@ static int check_collison(struct object_entry *entry)
|
|||
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.entry = entry;
|
||||
data.st = open_istream(the_repository, &entry->idx.oid, &type, &size,
|
||||
NULL);
|
||||
data.st = open_istream(&entry->idx.oid, &type, &size, NULL);
|
||||
if (!data.st)
|
||||
return -1;
|
||||
if (size != entry->size || type != entry->type)
|
||||
|
|
@ -949,7 +948,7 @@ static void resolve_delta(struct object_entry *delta_obj,
|
|||
free(delta_data);
|
||||
if (!result->data)
|
||||
bad_object(delta_obj->idx.offset, _("failed to apply delta"));
|
||||
hash_object_file(the_hash_algo, result->data, result->size,
|
||||
hash_object_file(result->data, result->size,
|
||||
type_name(delta_obj->real_type), &delta_obj->idx.oid);
|
||||
sha1_object(result->data, NULL, result->size, delta_obj->real_type,
|
||||
&delta_obj->idx.oid);
|
||||
|
|
@ -1004,9 +1003,7 @@ static struct base_data *find_unresolved_deltas_1(struct base_data *base,
|
|||
|
||||
if (!compare_and_swap_type(&child->real_type, OBJ_REF_DELTA,
|
||||
base->obj->real_type))
|
||||
die("REF_DELTA at offset %"PRIuMAX" already resolved (duplicate base %s?)",
|
||||
(uintmax_t)child->idx.offset,
|
||||
oid_to_hex(&base->obj->idx.oid));
|
||||
BUG("child->real_type != OBJ_REF_DELTA");
|
||||
|
||||
resolve_delta(child, base, result);
|
||||
if (base->ref_first == base->ref_last && base->ofs_last == -1)
|
||||
|
|
@ -1355,7 +1352,7 @@ static void fix_unresolved_deltas(struct hashfile *f)
|
|||
sorted_by_pos[i] = &ref_deltas[i];
|
||||
QSORT(sorted_by_pos, nr_ref_deltas, delta_pos_compare);
|
||||
|
||||
if (has_promisor_remote()) {
|
||||
if (repository_format_partial_clone) {
|
||||
/*
|
||||
* Prefetch the delta bases.
|
||||
*/
|
||||
|
|
@ -1369,8 +1366,8 @@ static void fix_unresolved_deltas(struct hashfile *f)
|
|||
oid_array_append(&to_fetch, &d->oid);
|
||||
}
|
||||
if (to_fetch.nr)
|
||||
promisor_remote_get_direct(the_repository,
|
||||
to_fetch.oid, to_fetch.nr);
|
||||
fetch_objects(repository_format_partial_clone,
|
||||
to_fetch.oid, to_fetch.nr);
|
||||
oid_array_clear(&to_fetch);
|
||||
}
|
||||
|
||||
|
|
@ -1386,9 +1383,8 @@ static void fix_unresolved_deltas(struct hashfile *f)
|
|||
if (!base_obj->data)
|
||||
continue;
|
||||
|
||||
if (check_object_signature(the_repository, &d->oid,
|
||||
base_obj->data, base_obj->size,
|
||||
type_name(type)))
|
||||
if (check_object_signature(&d->oid, base_obj->data,
|
||||
base_obj->size, type_name(type)))
|
||||
die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
|
||||
base_obj->obj = append_obj_to_pack(f, d->oid.hash,
|
||||
base_obj->data, base_obj->size, type);
|
||||
|
|
@ -1494,11 +1490,11 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
|
|||
}
|
||||
|
||||
if (!from_stdin) {
|
||||
printf("%s\n", hash_to_hex(hash));
|
||||
printf("%s\n", sha1_to_hex(hash));
|
||||
} else {
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
strbuf_addf(&buf, "%s\t%s\n", report, hash_to_hex(hash));
|
||||
strbuf_addf(&buf, "%s\t%s\n", report, sha1_to_hex(hash));
|
||||
write_or_die(1, buf.buf, buf.len);
|
||||
strbuf_release(&buf);
|
||||
|
||||
|
|
|
|||
214
third_party/git/builtin/log.c
vendored
214
third_party/git/builtin/log.c
vendored
|
|
@ -37,7 +37,6 @@
|
|||
#include "range-diff.h"
|
||||
|
||||
#define MAIL_DEFAULT_WRAP 72
|
||||
#define COVER_FROM_AUTO_MAX_SUBJECT_LEN 100
|
||||
|
||||
/* Set a default date-time format for git log ("log.date" config variable) */
|
||||
static const char *default_date_mode = NULL;
|
||||
|
|
@ -208,7 +207,7 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix,
|
|||
if (!rev->show_notes_given && (!rev->pretty_given || w.notes))
|
||||
rev->show_notes = 1;
|
||||
if (rev->show_notes)
|
||||
load_display_notes(&rev->notes_opt);
|
||||
init_display_notes(&rev->notes_opt);
|
||||
|
||||
if ((rev->diffopt.pickaxe_opts & DIFF_PICKAXE_KINDS_MASK) ||
|
||||
rev->diffopt.filter || rev->diffopt.flags.follow_renames)
|
||||
|
|
@ -628,7 +627,6 @@ int cmd_show(int argc, const char **argv, const char *prefix)
|
|||
break;
|
||||
case OBJ_TAG: {
|
||||
struct tag *t = (struct tag *)o;
|
||||
struct object_id *oid = get_tagged_oid(t);
|
||||
|
||||
if (rev.shown_one)
|
||||
putchar('\n');
|
||||
|
|
@ -640,10 +638,10 @@ int cmd_show(int argc, const char **argv, const char *prefix)
|
|||
rev.shown_one = 1;
|
||||
if (ret)
|
||||
break;
|
||||
o = parse_object(the_repository, oid);
|
||||
o = parse_object(the_repository, &t->tagged->oid);
|
||||
if (!o)
|
||||
ret = error(_("could not read object %s"),
|
||||
oid_to_hex(oid));
|
||||
oid_to_hex(&t->tagged->oid));
|
||||
objects[i].item = o;
|
||||
i--;
|
||||
break;
|
||||
|
|
@ -766,56 +764,28 @@ static void add_header(const char *value)
|
|||
item->string[len] = '\0';
|
||||
}
|
||||
|
||||
enum cover_setting {
|
||||
#define THREAD_SHALLOW 1
|
||||
#define THREAD_DEEP 2
|
||||
static int thread;
|
||||
static int do_signoff;
|
||||
static int base_auto;
|
||||
static char *from;
|
||||
static const char *signature = git_version_string;
|
||||
static const char *signature_file;
|
||||
static int config_cover_letter;
|
||||
static const char *config_output_directory;
|
||||
|
||||
enum {
|
||||
COVER_UNSET,
|
||||
COVER_OFF,
|
||||
COVER_ON,
|
||||
COVER_AUTO
|
||||
};
|
||||
|
||||
enum thread_level {
|
||||
THREAD_UNSET,
|
||||
THREAD_SHALLOW,
|
||||
THREAD_DEEP
|
||||
};
|
||||
|
||||
enum cover_from_description {
|
||||
COVER_FROM_NONE,
|
||||
COVER_FROM_MESSAGE,
|
||||
COVER_FROM_SUBJECT,
|
||||
COVER_FROM_AUTO
|
||||
};
|
||||
|
||||
static enum thread_level thread;
|
||||
static int do_signoff;
|
||||
static int base_auto;
|
||||
static char *from;
|
||||
static const char *signature = git_version_string;
|
||||
static const char *signature_file;
|
||||
static enum cover_setting config_cover_letter;
|
||||
static const char *config_output_directory;
|
||||
static enum cover_from_description cover_from_description_mode = COVER_FROM_MESSAGE;
|
||||
static int show_notes;
|
||||
static struct display_notes_opt notes_opt;
|
||||
|
||||
static enum cover_from_description parse_cover_from_description(const char *arg)
|
||||
{
|
||||
if (!arg || !strcmp(arg, "default"))
|
||||
return COVER_FROM_MESSAGE;
|
||||
else if (!strcmp(arg, "none"))
|
||||
return COVER_FROM_NONE;
|
||||
else if (!strcmp(arg, "message"))
|
||||
return COVER_FROM_MESSAGE;
|
||||
else if (!strcmp(arg, "subject"))
|
||||
return COVER_FROM_SUBJECT;
|
||||
else if (!strcmp(arg, "auto"))
|
||||
return COVER_FROM_AUTO;
|
||||
else
|
||||
die(_("%s: invalid cover from description mode"), arg);
|
||||
}
|
||||
|
||||
static int git_format_config(const char *var, const char *value, void *cb)
|
||||
{
|
||||
struct rev_info *rev = cb;
|
||||
|
||||
if (!strcmp(var, "format.headers")) {
|
||||
if (!value)
|
||||
die(_("format.headers without value"));
|
||||
|
|
@ -865,7 +835,7 @@ static int git_format_config(const char *var, const char *value, void *cb)
|
|||
thread = THREAD_SHALLOW;
|
||||
return 0;
|
||||
}
|
||||
thread = git_config_bool(var, value) ? THREAD_SHALLOW : THREAD_UNSET;
|
||||
thread = git_config_bool(var, value) && THREAD_SHALLOW;
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(var, "format.signoff")) {
|
||||
|
|
@ -902,17 +872,19 @@ static int git_format_config(const char *var, const char *value, void *cb)
|
|||
return 0;
|
||||
}
|
||||
if (!strcmp(var, "format.notes")) {
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
int b = git_parse_maybe_bool(value);
|
||||
if (b < 0)
|
||||
enable_ref_display_notes(¬es_opt, &show_notes, value);
|
||||
else if (b)
|
||||
enable_default_display_notes(¬es_opt, &show_notes);
|
||||
else
|
||||
disable_display_notes(¬es_opt, &show_notes);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(var, "format.coverfromdescription")) {
|
||||
cover_from_description_mode = parse_cover_from_description(value);
|
||||
if (!b)
|
||||
return 0;
|
||||
rev->show_notes = 1;
|
||||
if (b < 0) {
|
||||
strbuf_addstr(&buf, value);
|
||||
expand_notes_ref(&buf);
|
||||
string_list_append(&rev->notes_opt.extra_notes_refs,
|
||||
strbuf_detach(&buf, NULL));
|
||||
} else {
|
||||
rev->notes_opt.use_default_notes = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1021,6 +993,20 @@ static void print_signature(FILE *file)
|
|||
putc('\n', file);
|
||||
}
|
||||
|
||||
static void add_branch_description(struct strbuf *buf, const char *branch_name)
|
||||
{
|
||||
struct strbuf desc = STRBUF_INIT;
|
||||
if (!branch_name || !*branch_name)
|
||||
return;
|
||||
read_branch_desc(&desc, branch_name);
|
||||
if (desc.len) {
|
||||
strbuf_addch(buf, '\n');
|
||||
strbuf_addbuf(buf, &desc);
|
||||
strbuf_addch(buf, '\n');
|
||||
}
|
||||
strbuf_release(&desc);
|
||||
}
|
||||
|
||||
static char *find_branch_name(struct rev_info *rev)
|
||||
{
|
||||
int i, positive = -1;
|
||||
|
|
@ -1067,63 +1053,6 @@ static void show_diffstat(struct rev_info *rev,
|
|||
fprintf(rev->diffopt.file, "\n");
|
||||
}
|
||||
|
||||
static void prepare_cover_text(struct pretty_print_context *pp,
|
||||
const char *branch_name,
|
||||
struct strbuf *sb,
|
||||
const char *encoding,
|
||||
int need_8bit_cte)
|
||||
{
|
||||
const char *subject = "*** SUBJECT HERE ***";
|
||||
const char *body = "*** BLURB HERE ***";
|
||||
struct strbuf description_sb = STRBUF_INIT;
|
||||
struct strbuf subject_sb = STRBUF_INIT;
|
||||
|
||||
if (cover_from_description_mode == COVER_FROM_NONE)
|
||||
goto do_pp;
|
||||
|
||||
if (branch_name && *branch_name)
|
||||
read_branch_desc(&description_sb, branch_name);
|
||||
if (!description_sb.len)
|
||||
goto do_pp;
|
||||
|
||||
if (cover_from_description_mode == COVER_FROM_SUBJECT ||
|
||||
cover_from_description_mode == COVER_FROM_AUTO)
|
||||
body = format_subject(&subject_sb, description_sb.buf, " ");
|
||||
|
||||
if (cover_from_description_mode == COVER_FROM_MESSAGE ||
|
||||
(cover_from_description_mode == COVER_FROM_AUTO &&
|
||||
subject_sb.len > COVER_FROM_AUTO_MAX_SUBJECT_LEN))
|
||||
body = description_sb.buf;
|
||||
else
|
||||
subject = subject_sb.buf;
|
||||
|
||||
do_pp:
|
||||
pp_title_line(pp, &subject, sb, encoding, need_8bit_cte);
|
||||
pp_remainder(pp, &body, sb, 0);
|
||||
|
||||
strbuf_release(&description_sb);
|
||||
strbuf_release(&subject_sb);
|
||||
}
|
||||
|
||||
static int get_notes_refs(struct string_list_item *item, void *arg)
|
||||
{
|
||||
argv_array_pushf(arg, "--notes=%s", item->string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void get_notes_args(struct argv_array *arg, struct rev_info *rev)
|
||||
{
|
||||
if (!rev->show_notes) {
|
||||
argv_array_push(arg, "--no-notes");
|
||||
} else if (rev->notes_opt.use_default_notes > 0 ||
|
||||
(rev->notes_opt.use_default_notes == -1 &&
|
||||
!rev->notes_opt.extra_notes_refs.nr)) {
|
||||
argv_array_push(arg, "--notes");
|
||||
} else {
|
||||
for_each_string_list(&rev->notes_opt.extra_notes_refs, get_notes_refs, arg);
|
||||
}
|
||||
}
|
||||
|
||||
static void make_cover_letter(struct rev_info *rev, int use_stdout,
|
||||
struct commit *origin,
|
||||
int nr, struct commit **list,
|
||||
|
|
@ -1131,6 +1060,8 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
|
|||
int quiet)
|
||||
{
|
||||
const char *committer;
|
||||
const char *body = "*** SUBJECT HERE ***\n\n*** BLURB HERE ***\n";
|
||||
const char *msg;
|
||||
struct shortlog log;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
int i;
|
||||
|
|
@ -1160,12 +1091,15 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
|
|||
if (!branch_name)
|
||||
branch_name = find_branch_name(rev);
|
||||
|
||||
msg = body;
|
||||
pp.fmt = CMIT_FMT_EMAIL;
|
||||
pp.date_mode.type = DATE_RFC2822;
|
||||
pp.rev = rev;
|
||||
pp.print_email_subject = 1;
|
||||
pp_user_info(&pp, NULL, &sb, committer, encoding);
|
||||
prepare_cover_text(&pp, branch_name, &sb, encoding, need_8bit_cte);
|
||||
pp_title_line(&pp, &msg, &sb, encoding, need_8bit_cte);
|
||||
pp_remainder(&pp, &msg, &sb, 0);
|
||||
add_branch_description(&sb, branch_name);
|
||||
fprintf(rev->diffopt.file, "%s\n", sb.buf);
|
||||
|
||||
strbuf_release(&sb);
|
||||
|
|
@ -1196,16 +1130,13 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
|
|||
* can be added later if deemed desirable.
|
||||
*/
|
||||
struct diff_options opts;
|
||||
struct argv_array other_arg = ARGV_ARRAY_INIT;
|
||||
diff_setup(&opts);
|
||||
opts.file = rev->diffopt.file;
|
||||
opts.use_color = rev->diffopt.use_color;
|
||||
diff_setup_done(&opts);
|
||||
fprintf_ln(rev->diffopt.file, "%s", rev->rdiff_title);
|
||||
get_notes_args(&other_arg, rev);
|
||||
show_range_diff(rev->rdiff1, rev->rdiff2,
|
||||
rev->creation_factor, 1, &opts, &other_arg);
|
||||
argv_array_clear(&other_arg);
|
||||
rev->creation_factor, 1, &opts);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1317,9 +1248,9 @@ static int output_directory_callback(const struct option *opt, const char *arg,
|
|||
|
||||
static int thread_callback(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
enum thread_level *thread = (enum thread_level *)opt->value;
|
||||
int *thread = (int *)opt->value;
|
||||
if (unset)
|
||||
*thread = THREAD_UNSET;
|
||||
*thread = 0;
|
||||
else if (!arg || !strcmp(arg, "shallow"))
|
||||
*thread = THREAD_SHALLOW;
|
||||
else if (!strcmp(arg, "deep"))
|
||||
|
|
@ -1366,7 +1297,7 @@ static int header_callback(const struct option *opt, const char *arg, int unset)
|
|||
string_list_clear(&extra_to, 0);
|
||||
string_list_clear(&extra_cc, 0);
|
||||
} else {
|
||||
add_header(arg);
|
||||
add_header(arg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1422,7 +1353,7 @@ static struct commit *get_base_commit(const char *base_commit,
|
|||
base = lookup_commit_reference_by_name(base_commit);
|
||||
if (!base)
|
||||
die(_("unknown commit %s"), base_commit);
|
||||
} else if ((base_commit && !strcmp(base_commit, "auto"))) {
|
||||
} else if ((base_commit && !strcmp(base_commit, "auto")) || base_auto) {
|
||||
struct branch *curr_branch = branch_get(NULL);
|
||||
const char *upstream = branch_get_upstream(curr_branch, NULL);
|
||||
if (upstream) {
|
||||
|
|
@ -1610,7 +1541,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||
int use_patch_format = 0;
|
||||
int quiet = 0;
|
||||
int reroll_count = -1;
|
||||
char *cover_from_description_arg = NULL;
|
||||
char *branch_name = NULL;
|
||||
char *base_commit = NULL;
|
||||
struct base_tree_info bases;
|
||||
|
|
@ -1647,9 +1577,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||
{ OPTION_CALLBACK, 0, "rfc", &rev, NULL,
|
||||
N_("Use [RFC PATCH] instead of [PATCH]"),
|
||||
PARSE_OPT_NOARG | PARSE_OPT_NONEG, rfc_callback },
|
||||
OPT_STRING(0, "cover-from-description", &cover_from_description_arg,
|
||||
N_("cover-from-description-mode"),
|
||||
N_("generate parts of a cover letter based on a branch's description")),
|
||||
{ OPTION_CALLBACK, 0, "subject-prefix", &rev, N_("prefix"),
|
||||
N_("Use [<prefix>] instead of [PATCH]"),
|
||||
PARSE_OPT_NONEG, subject_prefix_callback },
|
||||
|
|
@ -1713,11 +1640,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||
extra_to.strdup_strings = 1;
|
||||
extra_cc.strdup_strings = 1;
|
||||
init_log_defaults();
|
||||
init_display_notes(¬es_opt);
|
||||
git_config(git_format_config, NULL);
|
||||
repo_init_revisions(the_repository, &rev, prefix);
|
||||
rev.show_notes = show_notes;
|
||||
memcpy(&rev.notes_opt, ¬es_opt, sizeof(notes_opt));
|
||||
git_config(git_format_config, &rev);
|
||||
rev.commit_format = CMIT_FMT_EMAIL;
|
||||
rev.expand_tabs_in_log_default = 0;
|
||||
rev.verbose_header = 1;
|
||||
|
|
@ -1729,9 +1653,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||
s_r_opt.def = "HEAD";
|
||||
s_r_opt.revarg_opt = REVARG_COMMITTISH;
|
||||
|
||||
if (base_auto)
|
||||
base_commit = "auto";
|
||||
|
||||
if (default_attach) {
|
||||
rev.mime_boundary = default_attach;
|
||||
rev.no_inline = 1;
|
||||
|
|
@ -1747,9 +1668,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||
PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
|
||||
PARSE_OPT_KEEP_DASHDASH);
|
||||
|
||||
if (cover_from_description_arg)
|
||||
cover_from_description_mode = parse_cover_from_description(cover_from_description_arg);
|
||||
|
||||
if (0 < reroll_count) {
|
||||
struct strbuf sprefix = STRBUF_INIT;
|
||||
strbuf_addf(&sprefix, "%s v%d",
|
||||
|
|
@ -1836,7 +1754,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||
rev.diffopt.flags.binary = 1;
|
||||
|
||||
if (rev.show_notes)
|
||||
load_display_notes(&rev.notes_opt);
|
||||
init_display_notes(&rev.notes_opt);
|
||||
|
||||
if (!output_directory && !use_stdout)
|
||||
output_directory = config_output_directory;
|
||||
|
|
@ -1847,26 +1765,10 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||
setup_pager();
|
||||
|
||||
if (output_directory) {
|
||||
int saved;
|
||||
if (rev.diffopt.use_color != GIT_COLOR_ALWAYS)
|
||||
rev.diffopt.use_color = GIT_COLOR_NEVER;
|
||||
if (use_stdout)
|
||||
die(_("standard output, or directory, which one?"));
|
||||
/*
|
||||
* We consider <outdir> as 'outside of gitdir', therefore avoid
|
||||
* applying adjust_shared_perm in s-c-l-d.
|
||||
*/
|
||||
saved = get_shared_repository();
|
||||
set_shared_repository(0);
|
||||
switch (safe_create_leading_directories_const(output_directory)) {
|
||||
case SCLD_OK:
|
||||
case SCLD_EXISTS:
|
||||
break;
|
||||
default:
|
||||
die(_("could not create leading directories "
|
||||
"of '%s'"), output_directory);
|
||||
}
|
||||
set_shared_repository(saved);
|
||||
if (mkdir(output_directory, 0777) < 0 && errno != EEXIST)
|
||||
die_errno(_("could not create directory '%s'"),
|
||||
output_directory);
|
||||
|
|
@ -1995,7 +1897,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
|
||||
memset(&bases, 0, sizeof(bases));
|
||||
if (base_commit) {
|
||||
if (base_commit || base_auto) {
|
||||
struct commit *base = get_base_commit(base_commit, list, nr);
|
||||
reset_revision_walk();
|
||||
clear_object_flags(UNINTERESTING);
|
||||
|
|
|
|||
8
third_party/git/builtin/ls-files.c
vendored
8
third_party/git/builtin/ls-files.c
vendored
|
|
@ -492,7 +492,7 @@ static int option_parse_exclude_from(const struct option *opt,
|
|||
BUG_ON_OPT_NEG(unset);
|
||||
|
||||
exc_given = 1;
|
||||
add_patterns_from_file(dir, arg);
|
||||
add_excludes_from_file(dir, arg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -516,7 +516,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
|
|||
int require_work_tree = 0, show_tag = 0, i;
|
||||
const char *max_prefix;
|
||||
struct dir_struct dir;
|
||||
struct pattern_list *pl;
|
||||
struct exclude_list *el;
|
||||
struct string_list exclude_list = STRING_LIST_INIT_NODUP;
|
||||
struct option builtin_ls_files_options[] = {
|
||||
/* Think twice before adding "--nul" synonym to this */
|
||||
|
|
@ -594,9 +594,9 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
|
|||
|
||||
argc = parse_options(argc, argv, prefix, builtin_ls_files_options,
|
||||
ls_files_usage, 0);
|
||||
pl = add_pattern_list(&dir, EXC_CMDL, "--exclude option");
|
||||
el = add_exclude_list(&dir, EXC_CMDL, "--exclude option");
|
||||
for (i = 0; i < exclude_list.nr; i++) {
|
||||
add_pattern(exclude_list.items[i].string, "", 0, pl, --exclude_args);
|
||||
add_exclude(exclude_list.items[i].string, "", 0, el, --exclude_args);
|
||||
}
|
||||
if (show_tag || show_valid_bit || show_fsmonitor_bit) {
|
||||
tag_cached = "H ";
|
||||
|
|
|
|||
4
third_party/git/builtin/merge-recursive.c
vendored
4
third_party/git/builtin/merge-recursive.c
vendored
|
|
@ -1,4 +1,3 @@
|
|||
#include "cache.h"
|
||||
#include "builtin.h"
|
||||
#include "commit.h"
|
||||
#include "tag.h"
|
||||
|
|
@ -64,9 +63,6 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix)
|
|||
if (argc - i != 3) /* "--" "<head>" "<remote>" */
|
||||
die(_("not handling anything other than two heads merge."));
|
||||
|
||||
if (repo_read_index_unmerged(the_repository))
|
||||
die_resolve_conflict("merge");
|
||||
|
||||
o.branch1 = argv[++i];
|
||||
o.branch2 = argv[++i];
|
||||
|
||||
|
|
|
|||
5
third_party/git/builtin/merge-tree.c
vendored
5
third_party/git/builtin/merge-tree.c
vendored
|
|
@ -180,9 +180,8 @@ static struct merge_list *create_entry(unsigned stage, unsigned mode, const stru
|
|||
|
||||
static char *traverse_path(const struct traverse_info *info, const struct name_entry *n)
|
||||
{
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
strbuf_make_traverse_path(&buf, info, n->path, n->pathlen);
|
||||
return strbuf_detach(&buf, NULL);
|
||||
char *path = xmallocz(traverse_path_len(info, n) + the_hash_algo->rawsz);
|
||||
return make_traverse_path(path, info, n);
|
||||
}
|
||||
|
||||
static void resolve(const struct traverse_info *info, struct name_entry *ours, struct name_entry *result)
|
||||
|
|
|
|||
40
third_party/git/builtin/merge.c
vendored
40
third_party/git/builtin/merge.c
vendored
|
|
@ -62,7 +62,6 @@ static int show_diffstat = 1, shortlog_len = -1, squash;
|
|||
static int option_commit = -1;
|
||||
static int option_edit = -1;
|
||||
static int allow_trivial = 1, have_message, verify_signatures;
|
||||
static int check_trust_level = 1;
|
||||
static int overwrite_ignore = 1;
|
||||
static struct strbuf merge_msg = STRBUF_INIT;
|
||||
static struct strategy **use_strategies;
|
||||
|
|
@ -82,7 +81,7 @@ static int show_progress = -1;
|
|||
static int default_to_upstream = 1;
|
||||
static int signoff;
|
||||
static const char *sign_commit;
|
||||
static int no_verify;
|
||||
static int verify_msg = 1;
|
||||
|
||||
static struct strategy all_strategy[] = {
|
||||
{ "recursive", DEFAULT_TWOHEAD | NO_TRIVIAL },
|
||||
|
|
@ -288,7 +287,7 @@ static struct option builtin_merge_options[] = {
|
|||
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
|
||||
OPT_BOOL(0, "overwrite-ignore", &overwrite_ignore, N_("update ignored files (default)")),
|
||||
OPT_BOOL(0, "signoff", &signoff, N_("add Signed-off-by:")),
|
||||
OPT_BOOL(0, "no-verify", &no_verify, N_("bypass pre-merge-commit and commit-msg hooks")),
|
||||
OPT_BOOL(0, "verify", &verify_msg, N_("verify commit-msg hook")),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
|
|
@ -632,8 +631,6 @@ static int git_merge_config(const char *k, const char *v, void *cb)
|
|||
} else if (!strcmp(k, "commit.gpgsign")) {
|
||||
sign_commit = git_config_bool(k, v) ? "" : NULL;
|
||||
return 0;
|
||||
} else if (!strcmp(k, "gpg.mintrustlevel")) {
|
||||
check_trust_level = 0;
|
||||
}
|
||||
|
||||
status = fmt_merge_msg_config(k, v, cb);
|
||||
|
|
@ -691,13 +688,16 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
|
|||
struct commit_list *remoteheads,
|
||||
struct commit *head)
|
||||
{
|
||||
struct lock_file lock = LOCK_INIT;
|
||||
const char *head_arg = "HEAD";
|
||||
|
||||
if (refresh_and_write_cache(REFRESH_QUIET, SKIP_IF_UNCHANGED, 0) < 0)
|
||||
hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
|
||||
refresh_cache(REFRESH_QUIET);
|
||||
if (write_locked_index(&the_index, &lock,
|
||||
COMMIT_LOCK | SKIP_IF_UNCHANGED))
|
||||
return error(_("Unable to write index."));
|
||||
|
||||
if (!strcmp(strategy, "recursive") || !strcmp(strategy, "subtree")) {
|
||||
struct lock_file lock = LOCK_INIT;
|
||||
int clean, x;
|
||||
struct commit *result;
|
||||
struct commit_list *reversed = NULL;
|
||||
|
|
@ -816,18 +816,6 @@ static void write_merge_heads(struct commit_list *);
|
|||
static void prepare_to_commit(struct commit_list *remoteheads)
|
||||
{
|
||||
struct strbuf msg = STRBUF_INIT;
|
||||
const char *index_file = get_index_file();
|
||||
|
||||
if (!no_verify && run_commit_hook(0 < option_edit, index_file, "pre-merge-commit", NULL))
|
||||
abort_commit(remoteheads, NULL);
|
||||
/*
|
||||
* Re-read the index as pre-merge-commit hook could have updated it,
|
||||
* and write it out as a tree. We must do this before we invoke
|
||||
* the editor and after we invoke run_status above.
|
||||
*/
|
||||
if (find_hook("pre-merge-commit"))
|
||||
discard_cache();
|
||||
read_cache_from(index_file);
|
||||
strbuf_addbuf(&msg, &merge_msg);
|
||||
if (squash)
|
||||
BUG("the control must not reach here under --squash");
|
||||
|
|
@ -854,7 +842,7 @@ static void prepare_to_commit(struct commit_list *remoteheads)
|
|||
abort_commit(remoteheads, NULL);
|
||||
}
|
||||
|
||||
if (!no_verify && run_commit_hook(0 < option_edit, get_index_file(),
|
||||
if (verify_msg && run_commit_hook(0 < option_edit, get_index_file(),
|
||||
"commit-msg",
|
||||
git_path_merge_msg(the_repository), NULL))
|
||||
abort_commit(remoteheads, NULL);
|
||||
|
|
@ -872,8 +860,12 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads)
|
|||
{
|
||||
struct object_id result_tree, result_commit;
|
||||
struct commit_list *parents, **pptr = &parents;
|
||||
struct lock_file lock = LOCK_INIT;
|
||||
|
||||
if (refresh_and_write_cache(REFRESH_QUIET, SKIP_IF_UNCHANGED, 0) < 0)
|
||||
hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
|
||||
refresh_cache(REFRESH_QUIET);
|
||||
if (write_locked_index(&the_index, &lock,
|
||||
COMMIT_LOCK | SKIP_IF_UNCHANGED))
|
||||
return error(_("Unable to write index."));
|
||||
|
||||
write_tree_trivial(&result_tree);
|
||||
|
|
@ -1400,8 +1392,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
|||
die(_("Can merge only exactly one commit into empty head"));
|
||||
|
||||
if (verify_signatures)
|
||||
verify_merge_signature(remoteheads->item, verbosity,
|
||||
check_trust_level);
|
||||
verify_merge_signature(remoteheads->item, verbosity);
|
||||
|
||||
remote_head_oid = &remoteheads->item->object.oid;
|
||||
read_empty(remote_head_oid, 0);
|
||||
|
|
@ -1424,8 +1415,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
|||
|
||||
if (verify_signatures) {
|
||||
for (p = remoteheads; p; p = p->next) {
|
||||
verify_merge_signature(p->item, verbosity,
|
||||
check_trust_level);
|
||||
verify_merge_signature(p->item, verbosity);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
7
third_party/git/builtin/mktag.c
vendored
7
third_party/git/builtin/mktag.c
vendored
|
|
@ -29,11 +29,8 @@ static int verify_object(const struct object_id *oid, const char *expected_type)
|
|||
const struct object_id *repl = lookup_replace_object(the_repository, oid);
|
||||
|
||||
if (buffer) {
|
||||
if (type == type_from_string(expected_type)) {
|
||||
ret = check_object_signature(the_repository, repl,
|
||||
buffer, size,
|
||||
expected_type);
|
||||
}
|
||||
if (type == type_from_string(expected_type))
|
||||
ret = check_object_signature(repl, buffer, size, expected_type);
|
||||
free(buffer);
|
||||
}
|
||||
return ret;
|
||||
|
|
|
|||
18
third_party/git/builtin/multi-pack-index.c
vendored
18
third_party/git/builtin/multi-pack-index.c
vendored
|
|
@ -6,25 +6,21 @@
|
|||
#include "trace2.h"
|
||||
|
||||
static char const * const builtin_multi_pack_index_usage[] = {
|
||||
N_("git multi-pack-index [<options>] (write|verify|expire|repack --batch-size=<size>)"),
|
||||
N_("git multi-pack-index [--object-dir=<dir>] (write|verify|expire|repack --batch-size=<size>)"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct opts_multi_pack_index {
|
||||
const char *object_dir;
|
||||
unsigned long batch_size;
|
||||
int progress;
|
||||
} opts;
|
||||
|
||||
int cmd_multi_pack_index(int argc, const char **argv,
|
||||
const char *prefix)
|
||||
{
|
||||
unsigned flags = 0;
|
||||
|
||||
static struct option builtin_multi_pack_index_options[] = {
|
||||
OPT_FILENAME(0, "object-dir", &opts.object_dir,
|
||||
N_("object directory containing set of packfile and pack-index pairs")),
|
||||
OPT_BOOL(0, "progress", &opts.progress, N_("force progress reporting")),
|
||||
OPT_MAGNITUDE(0, "batch-size", &opts.batch_size,
|
||||
N_("during repack, collect pack-files of smaller size into a batch that is larger than this size")),
|
||||
OPT_END(),
|
||||
|
|
@ -32,15 +28,12 @@ int cmd_multi_pack_index(int argc, const char **argv,
|
|||
|
||||
git_config(git_default_config, NULL);
|
||||
|
||||
opts.progress = isatty(2);
|
||||
argc = parse_options(argc, argv, prefix,
|
||||
builtin_multi_pack_index_options,
|
||||
builtin_multi_pack_index_usage, 0);
|
||||
|
||||
if (!opts.object_dir)
|
||||
opts.object_dir = get_object_directory();
|
||||
if (opts.progress)
|
||||
flags |= MIDX_PROGRESS;
|
||||
|
||||
if (argc == 0)
|
||||
usage_with_options(builtin_multi_pack_index_usage,
|
||||
|
|
@ -54,17 +47,16 @@ int cmd_multi_pack_index(int argc, const char **argv,
|
|||
trace2_cmd_mode(argv[0]);
|
||||
|
||||
if (!strcmp(argv[0], "repack"))
|
||||
return midx_repack(the_repository, opts.object_dir,
|
||||
(size_t)opts.batch_size, flags);
|
||||
return midx_repack(the_repository, opts.object_dir, (size_t)opts.batch_size);
|
||||
if (opts.batch_size)
|
||||
die(_("--batch-size option is only for 'repack' subcommand"));
|
||||
|
||||
if (!strcmp(argv[0], "write"))
|
||||
return write_midx_file(opts.object_dir, flags);
|
||||
return write_midx_file(opts.object_dir);
|
||||
if (!strcmp(argv[0], "verify"))
|
||||
return verify_midx_file(the_repository, opts.object_dir, flags);
|
||||
return verify_midx_file(the_repository, opts.object_dir);
|
||||
if (!strcmp(argv[0], "expire"))
|
||||
return expire_midx_packs(the_repository, opts.object_dir, flags);
|
||||
return expire_midx_packs(the_repository, opts.object_dir);
|
||||
|
||||
die(_("unrecognized subcommand: %s"), argv[0]);
|
||||
}
|
||||
|
|
|
|||
293
third_party/git/builtin/name-rev.c
vendored
293
third_party/git/builtin/name-rev.c
vendored
|
|
@ -6,25 +6,20 @@
|
|||
#include "tag.h"
|
||||
#include "refs.h"
|
||||
#include "parse-options.h"
|
||||
#include "prio-queue.h"
|
||||
#include "sha1-lookup.h"
|
||||
#include "commit-slab.h"
|
||||
|
||||
/*
|
||||
* One day. See the 'name a rev shortly after epoch' test in t6120 when
|
||||
* changing this value
|
||||
*/
|
||||
#define CUTOFF_DATE_SLOP 86400
|
||||
#define CUTOFF_DATE_SLOP 86400 /* one day */
|
||||
|
||||
struct rev_name {
|
||||
char *tip_name;
|
||||
typedef struct rev_name {
|
||||
const char *tip_name;
|
||||
timestamp_t taggerdate;
|
||||
int generation;
|
||||
int distance;
|
||||
int from_tag;
|
||||
};
|
||||
} rev_name;
|
||||
|
||||
define_commit_slab(commit_rev_name, struct rev_name);
|
||||
define_commit_slab(commit_rev_name, struct rev_name *);
|
||||
|
||||
static timestamp_t cutoff = TIME_MAX;
|
||||
static struct commit_rev_name rev_names;
|
||||
|
|
@ -32,16 +27,16 @@ static struct commit_rev_name rev_names;
|
|||
/* How many generations are maximally preferred over _one_ merge traversal? */
|
||||
#define MERGE_TRAVERSAL_WEIGHT 65535
|
||||
|
||||
static int is_valid_rev_name(const struct rev_name *name)
|
||||
static struct rev_name *get_commit_rev_name(struct commit *commit)
|
||||
{
|
||||
return name && (name->generation || name->tip_name);
|
||||
struct rev_name **slot = commit_rev_name_peek(&rev_names, commit);
|
||||
|
||||
return slot ? *slot : NULL;
|
||||
}
|
||||
|
||||
static struct rev_name *get_commit_rev_name(const struct commit *commit)
|
||||
static void set_commit_rev_name(struct commit *commit, struct rev_name *name)
|
||||
{
|
||||
struct rev_name *name = commit_rev_name_peek(&rev_names, commit);
|
||||
|
||||
return is_valid_rev_name(name) ? name : NULL;
|
||||
*commit_rev_name_at(&rev_names, commit) = name;
|
||||
}
|
||||
|
||||
static int is_better_name(struct rev_name *name,
|
||||
|
|
@ -80,135 +75,68 @@ static int is_better_name(struct rev_name *name,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct rev_name *create_or_update_name(struct commit *commit,
|
||||
timestamp_t taggerdate,
|
||||
int generation, int distance,
|
||||
int from_tag)
|
||||
{
|
||||
struct rev_name *name = commit_rev_name_at(&rev_names, commit);
|
||||
|
||||
if (is_valid_rev_name(name)) {
|
||||
if (!is_better_name(name, taggerdate, distance, from_tag))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* This string might still be shared with ancestors
|
||||
* (generation > 0). We can release it here regardless,
|
||||
* because the new name that has just won will be better
|
||||
* for them as well, so name_rev() will replace these
|
||||
* stale pointers when it processes the parents.
|
||||
*/
|
||||
if (!name->generation)
|
||||
free(name->tip_name);
|
||||
}
|
||||
|
||||
name->taggerdate = taggerdate;
|
||||
name->generation = generation;
|
||||
name->distance = distance;
|
||||
name->from_tag = from_tag;
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static char *get_parent_name(const struct rev_name *name, int parent_number)
|
||||
{
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
size_t len;
|
||||
|
||||
strip_suffix(name->tip_name, "^0", &len);
|
||||
if (name->generation > 0) {
|
||||
strbuf_grow(&sb, len +
|
||||
1 + decimal_width(name->generation) +
|
||||
1 + decimal_width(parent_number));
|
||||
strbuf_addf(&sb, "%.*s~%d^%d", (int)len, name->tip_name,
|
||||
name->generation, parent_number);
|
||||
} else {
|
||||
strbuf_grow(&sb, len +
|
||||
1 + decimal_width(parent_number));
|
||||
strbuf_addf(&sb, "%.*s^%d", (int)len, name->tip_name,
|
||||
parent_number);
|
||||
}
|
||||
return strbuf_detach(&sb, NULL);
|
||||
}
|
||||
|
||||
static void name_rev(struct commit *start_commit,
|
||||
static void name_rev(struct commit *commit,
|
||||
const char *tip_name, timestamp_t taggerdate,
|
||||
int from_tag, int deref)
|
||||
int generation, int distance, int from_tag,
|
||||
int deref)
|
||||
{
|
||||
struct prio_queue queue;
|
||||
struct commit *commit;
|
||||
struct commit **parents_to_queue = NULL;
|
||||
size_t parents_to_queue_nr, parents_to_queue_alloc = 0;
|
||||
struct rev_name *start_name;
|
||||
struct rev_name *name = get_commit_rev_name(commit);
|
||||
struct commit_list *parents;
|
||||
int parent_number = 1;
|
||||
char *to_free = NULL;
|
||||
|
||||
parse_commit(start_commit);
|
||||
if (start_commit->date < cutoff)
|
||||
parse_commit(commit);
|
||||
|
||||
if (commit->date < cutoff)
|
||||
return;
|
||||
|
||||
start_name = create_or_update_name(start_commit, taggerdate, 0, 0,
|
||||
from_tag);
|
||||
if (!start_name)
|
||||
return;
|
||||
if (deref)
|
||||
start_name->tip_name = xstrfmt("%s^0", tip_name);
|
||||
else
|
||||
start_name->tip_name = xstrdup(tip_name);
|
||||
if (deref) {
|
||||
tip_name = to_free = xstrfmt("%s^0", tip_name);
|
||||
|
||||
memset(&queue, 0, sizeof(queue)); /* Use the prio_queue as LIFO */
|
||||
prio_queue_put(&queue, start_commit);
|
||||
|
||||
while ((commit = prio_queue_get(&queue))) {
|
||||
struct rev_name *name = get_commit_rev_name(commit);
|
||||
struct commit_list *parents;
|
||||
int parent_number = 1;
|
||||
|
||||
parents_to_queue_nr = 0;
|
||||
|
||||
for (parents = commit->parents;
|
||||
parents;
|
||||
parents = parents->next, parent_number++) {
|
||||
struct commit *parent = parents->item;
|
||||
struct rev_name *parent_name;
|
||||
int generation, distance;
|
||||
|
||||
parse_commit(parent);
|
||||
if (parent->date < cutoff)
|
||||
continue;
|
||||
|
||||
if (parent_number > 1) {
|
||||
generation = 0;
|
||||
distance = name->distance + MERGE_TRAVERSAL_WEIGHT;
|
||||
} else {
|
||||
generation = name->generation + 1;
|
||||
distance = name->distance + 1;
|
||||
}
|
||||
|
||||
parent_name = create_or_update_name(parent, taggerdate,
|
||||
generation,
|
||||
distance, from_tag);
|
||||
if (parent_name) {
|
||||
if (parent_number > 1)
|
||||
parent_name->tip_name =
|
||||
get_parent_name(name,
|
||||
parent_number);
|
||||
else
|
||||
parent_name->tip_name = name->tip_name;
|
||||
ALLOC_GROW(parents_to_queue,
|
||||
parents_to_queue_nr + 1,
|
||||
parents_to_queue_alloc);
|
||||
parents_to_queue[parents_to_queue_nr] = parent;
|
||||
parents_to_queue_nr++;
|
||||
}
|
||||
}
|
||||
|
||||
/* The first parent must come out first from the prio_queue */
|
||||
while (parents_to_queue_nr)
|
||||
prio_queue_put(&queue,
|
||||
parents_to_queue[--parents_to_queue_nr]);
|
||||
if (generation)
|
||||
die("generation: %d, but deref?", generation);
|
||||
}
|
||||
|
||||
clear_prio_queue(&queue);
|
||||
free(parents_to_queue);
|
||||
if (name == NULL) {
|
||||
name = xmalloc(sizeof(rev_name));
|
||||
set_commit_rev_name(commit, name);
|
||||
goto copy_data;
|
||||
} else if (is_better_name(name, taggerdate, distance, from_tag)) {
|
||||
copy_data:
|
||||
name->tip_name = tip_name;
|
||||
name->taggerdate = taggerdate;
|
||||
name->generation = generation;
|
||||
name->distance = distance;
|
||||
name->from_tag = from_tag;
|
||||
} else {
|
||||
free(to_free);
|
||||
return;
|
||||
}
|
||||
|
||||
for (parents = commit->parents;
|
||||
parents;
|
||||
parents = parents->next, parent_number++) {
|
||||
if (parent_number > 1) {
|
||||
size_t len;
|
||||
char *new_name;
|
||||
|
||||
strip_suffix(tip_name, "^0", &len);
|
||||
if (generation > 0)
|
||||
new_name = xstrfmt("%.*s~%d^%d", (int)len, tip_name,
|
||||
generation, parent_number);
|
||||
else
|
||||
new_name = xstrfmt("%.*s^%d", (int)len, tip_name,
|
||||
parent_number);
|
||||
|
||||
name_rev(parents->item, new_name, taggerdate, 0,
|
||||
distance + MERGE_TRAVERSAL_WEIGHT,
|
||||
from_tag, 0);
|
||||
} else {
|
||||
name_rev(parents->item, tip_name, taggerdate,
|
||||
generation + 1, distance + 1,
|
||||
from_tag, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int subpath_matches(const char *path, const char *filter)
|
||||
|
|
@ -229,10 +157,10 @@ static const char *name_ref_abbrev(const char *refname, int shorten_unambiguous)
|
|||
{
|
||||
if (shorten_unambiguous)
|
||||
refname = shorten_unambiguous_ref(refname, 0);
|
||||
else if (skip_prefix(refname, "refs/heads/", &refname))
|
||||
; /* refname already advanced */
|
||||
else
|
||||
skip_prefix(refname, "refs/", &refname);
|
||||
else if (starts_with(refname, "refs/heads/"))
|
||||
refname = refname + 11;
|
||||
else if (starts_with(refname, "refs/"))
|
||||
refname = refname + 5;
|
||||
return refname;
|
||||
}
|
||||
|
||||
|
|
@ -247,10 +175,6 @@ static struct tip_table {
|
|||
struct tip_table_entry {
|
||||
struct object_id oid;
|
||||
const char *refname;
|
||||
struct commit *commit;
|
||||
timestamp_t taggerdate;
|
||||
unsigned int from_tag:1;
|
||||
unsigned int deref:1;
|
||||
} *table;
|
||||
int nr;
|
||||
int alloc;
|
||||
|
|
@ -258,18 +182,13 @@ static struct tip_table {
|
|||
} tip_table;
|
||||
|
||||
static void add_to_tip_table(const struct object_id *oid, const char *refname,
|
||||
int shorten_unambiguous, struct commit *commit,
|
||||
timestamp_t taggerdate, int from_tag, int deref)
|
||||
int shorten_unambiguous)
|
||||
{
|
||||
refname = name_ref_abbrev(refname, shorten_unambiguous);
|
||||
|
||||
ALLOC_GROW(tip_table.table, tip_table.nr + 1, tip_table.alloc);
|
||||
oidcpy(&tip_table.table[tip_table.nr].oid, oid);
|
||||
tip_table.table[tip_table.nr].refname = xstrdup(refname);
|
||||
tip_table.table[tip_table.nr].commit = commit;
|
||||
tip_table.table[tip_table.nr].taggerdate = taggerdate;
|
||||
tip_table.table[tip_table.nr].from_tag = from_tag;
|
||||
tip_table.table[tip_table.nr].deref = deref;
|
||||
tip_table.nr++;
|
||||
tip_table.sorted = 0;
|
||||
}
|
||||
|
|
@ -280,30 +199,12 @@ static int tipcmp(const void *a_, const void *b_)
|
|||
return oidcmp(&a->oid, &b->oid);
|
||||
}
|
||||
|
||||
static int cmp_by_tag_and_age(const void *a_, const void *b_)
|
||||
{
|
||||
const struct tip_table_entry *a = a_, *b = b_;
|
||||
int cmp;
|
||||
|
||||
/* Prefer tags. */
|
||||
cmp = b->from_tag - a->from_tag;
|
||||
if (cmp)
|
||||
return cmp;
|
||||
|
||||
/* Older is better. */
|
||||
if (a->taggerdate < b->taggerdate)
|
||||
return -1;
|
||||
return a->taggerdate != b->taggerdate;
|
||||
}
|
||||
|
||||
static int name_ref(const char *path, const struct object_id *oid, int flags, void *cb_data)
|
||||
{
|
||||
struct object *o = parse_object(the_repository, oid);
|
||||
struct name_ref_data *data = cb_data;
|
||||
int can_abbreviate_output = data->tags_only && data->name_only;
|
||||
int deref = 0;
|
||||
int from_tag = 0;
|
||||
struct commit *commit = NULL;
|
||||
timestamp_t taggerdate = TIME_MAX;
|
||||
|
||||
if (data->tags_only && !starts_with(path, "refs/tags/"))
|
||||
|
|
@ -352,6 +253,8 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo
|
|||
return 0;
|
||||
}
|
||||
|
||||
add_to_tip_table(oid, path, can_abbreviate_output);
|
||||
|
||||
while (o && o->type == OBJ_TAG) {
|
||||
struct tag *t = (struct tag *) o;
|
||||
if (!t->tagged)
|
||||
|
|
@ -361,33 +264,16 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo
|
|||
taggerdate = t->date;
|
||||
}
|
||||
if (o && o->type == OBJ_COMMIT) {
|
||||
commit = (struct commit *)o;
|
||||
from_tag = starts_with(path, "refs/tags/");
|
||||
struct commit *commit = (struct commit *)o;
|
||||
int from_tag = starts_with(path, "refs/tags/");
|
||||
|
||||
if (taggerdate == TIME_MAX)
|
||||
taggerdate = commit->date;
|
||||
}
|
||||
|
||||
add_to_tip_table(oid, path, can_abbreviate_output, commit, taggerdate,
|
||||
taggerdate = ((struct commit *)o)->date;
|
||||
path = name_ref_abbrev(path, can_abbreviate_output);
|
||||
name_rev(commit, xstrdup(path), taggerdate, 0, 0,
|
||||
from_tag, deref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void name_tips(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Try to set better names first, so that worse ones spread
|
||||
* less.
|
||||
*/
|
||||
QSORT(tip_table.table, tip_table.nr, cmp_by_tag_and_age);
|
||||
for (i = 0; i < tip_table.nr; i++) {
|
||||
struct tip_table_entry *e = &tip_table.table[i];
|
||||
if (e->commit) {
|
||||
name_rev(e->commit, e->refname, e->taggerdate,
|
||||
e->from_tag, e->deref);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const unsigned char *nth_tip_table_ent(size_t ix, void *table_)
|
||||
|
|
@ -419,11 +305,11 @@ static const char *get_exact_ref_match(const struct object *o)
|
|||
static const char *get_rev_name(const struct object *o, struct strbuf *buf)
|
||||
{
|
||||
struct rev_name *n;
|
||||
const struct commit *c;
|
||||
struct commit *c;
|
||||
|
||||
if (o->type != OBJ_COMMIT)
|
||||
return get_exact_ref_match(o);
|
||||
c = (const struct commit *) o;
|
||||
c = (struct commit *) o;
|
||||
n = get_commit_rev_name(c);
|
||||
if (!n)
|
||||
return NULL;
|
||||
|
|
@ -431,10 +317,11 @@ static const char *get_rev_name(const struct object *o, struct strbuf *buf)
|
|||
if (!n->generation)
|
||||
return n->tip_name;
|
||||
else {
|
||||
int len = strlen(n->tip_name);
|
||||
if (len > 2 && !strcmp(n->tip_name + len - 2, "^0"))
|
||||
len -= 2;
|
||||
strbuf_reset(buf);
|
||||
strbuf_addstr(buf, n->tip_name);
|
||||
strbuf_strip_suffix(buf, "^0");
|
||||
strbuf_addf(buf, "~%d", n->generation);
|
||||
strbuf_addf(buf, "%.*s~%d", len, n->tip_name, n->generation);
|
||||
return buf->buf;
|
||||
}
|
||||
}
|
||||
|
|
@ -594,15 +481,9 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)
|
|||
add_object_array(object, *argv, &revs);
|
||||
}
|
||||
|
||||
if (cutoff) {
|
||||
/* check for undeflow */
|
||||
if (cutoff > TIME_MIN + CUTOFF_DATE_SLOP)
|
||||
cutoff = cutoff - CUTOFF_DATE_SLOP;
|
||||
else
|
||||
cutoff = TIME_MIN;
|
||||
}
|
||||
if (cutoff)
|
||||
cutoff = cutoff - CUTOFF_DATE_SLOP;
|
||||
for_each_ref(name_ref, &data);
|
||||
name_tips();
|
||||
|
||||
if (transform_stdin) {
|
||||
char buffer[2048];
|
||||
|
|
|
|||
6
third_party/git/builtin/notes.c
vendored
6
third_party/git/builtin/notes.c
vendored
|
|
@ -513,7 +513,7 @@ static int copy(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
}
|
||||
|
||||
if (argc < 1) {
|
||||
if (argc < 2) {
|
||||
error(_("too few parameters"));
|
||||
usage_with_options(git_notes_copy_usage, options);
|
||||
}
|
||||
|
|
@ -622,7 +622,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)
|
|||
|
||||
strbuf_grow(&d.buf, size + 1);
|
||||
if (d.buf.len && prev_buf && size)
|
||||
strbuf_insertstr(&d.buf, 0, "\n");
|
||||
strbuf_insert(&d.buf, 0, "\n", 1);
|
||||
if (prev_buf && size)
|
||||
strbuf_insert(&d.buf, 0, prev_buf, size);
|
||||
free(prev_buf);
|
||||
|
|
@ -745,7 +745,7 @@ static int merge_commit(struct notes_merge_options *o)
|
|||
memset(&pretty_ctx, 0, sizeof(pretty_ctx));
|
||||
format_commit_message(partial, "%s", &msg, &pretty_ctx);
|
||||
strbuf_trim(&msg);
|
||||
strbuf_insertstr(&msg, 0, "notes: ");
|
||||
strbuf_insert(&msg, 0, "notes: ", 7);
|
||||
update_ref(msg.buf, o->local_ref, &oid,
|
||||
is_null_oid(&parent_oid) ? NULL : &parent_oid,
|
||||
0, UPDATE_REFS_DIE_ON_ERR);
|
||||
|
|
|
|||
336
third_party/git/builtin/pack-objects.c
vendored
336
third_party/git/builtin/pack-objects.c
vendored
|
|
@ -92,11 +92,10 @@ static struct progress *progress_state;
|
|||
|
||||
static struct packed_git *reuse_packfile;
|
||||
static uint32_t reuse_packfile_objects;
|
||||
static struct bitmap *reuse_packfile_bitmap;
|
||||
static off_t reuse_packfile_offset;
|
||||
|
||||
static int use_bitmap_index_default = 1;
|
||||
static int use_bitmap_index = -1;
|
||||
static int allow_pack_reuse = 1;
|
||||
static enum {
|
||||
WRITE_BITMAP_FALSE = 0,
|
||||
WRITE_BITMAP_QUIET,
|
||||
|
|
@ -164,7 +163,7 @@ static void *get_delta(struct object_entry *entry)
|
|||
delta_buf = diff_delta(base_buf, base_size,
|
||||
buf, size, &delta_size, 0);
|
||||
/*
|
||||
* We successfully computed this delta once but dropped it for
|
||||
* We succesfully computed this delta once but dropped it for
|
||||
* memory reasons. Something is very wrong if this time we
|
||||
* recompute and create a different delta.
|
||||
*/
|
||||
|
|
@ -304,8 +303,7 @@ static unsigned long write_no_reuse_object(struct hashfile *f, struct object_ent
|
|||
if (!usable_delta) {
|
||||
if (oe_type(entry) == OBJ_BLOB &&
|
||||
oe_size_greater_than(&to_pack, entry, big_file_threshold) &&
|
||||
(st = open_istream(the_repository, &entry->idx.oid, &type,
|
||||
&size, NULL)) != NULL)
|
||||
(st = open_istream(&entry->idx.oid, &type, &size, NULL)) != NULL)
|
||||
buf = NULL;
|
||||
else {
|
||||
buf = read_object_file(&entry->idx.oid, &type, &size);
|
||||
|
|
@ -612,12 +610,12 @@ static int mark_tagged(const char *path, const struct object_id *oid, int flag,
|
|||
void *cb_data)
|
||||
{
|
||||
struct object_id peeled;
|
||||
struct object_entry *entry = packlist_find(&to_pack, oid);
|
||||
struct object_entry *entry = packlist_find(&to_pack, oid, NULL);
|
||||
|
||||
if (entry)
|
||||
entry->tagged = 1;
|
||||
if (!peel_ref(path, &peeled)) {
|
||||
entry = packlist_find(&to_pack, &peeled);
|
||||
entry = packlist_find(&to_pack, &peeled, NULL);
|
||||
if (entry)
|
||||
entry->tagged = 1;
|
||||
}
|
||||
|
|
@ -786,186 +784,57 @@ static struct object_entry **compute_write_order(void)
|
|||
return wo;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* A reused set of objects. All objects in a chunk have the same
|
||||
* relative position in the original packfile and the generated
|
||||
* packfile.
|
||||
*/
|
||||
|
||||
static struct reused_chunk {
|
||||
/* The offset of the first object of this chunk in the original
|
||||
* packfile. */
|
||||
off_t original;
|
||||
/* The offset of the first object of this chunk in the generated
|
||||
* packfile minus "original". */
|
||||
off_t difference;
|
||||
} *reused_chunks;
|
||||
static int reused_chunks_nr;
|
||||
static int reused_chunks_alloc;
|
||||
|
||||
static void record_reused_object(off_t where, off_t offset)
|
||||
static off_t write_reused_pack(struct hashfile *f)
|
||||
{
|
||||
if (reused_chunks_nr && reused_chunks[reused_chunks_nr-1].difference == offset)
|
||||
return;
|
||||
unsigned char buffer[8192];
|
||||
off_t to_write, total;
|
||||
int fd;
|
||||
|
||||
ALLOC_GROW(reused_chunks, reused_chunks_nr + 1,
|
||||
reused_chunks_alloc);
|
||||
reused_chunks[reused_chunks_nr].original = where;
|
||||
reused_chunks[reused_chunks_nr].difference = offset;
|
||||
reused_chunks_nr++;
|
||||
}
|
||||
if (!is_pack_valid(reuse_packfile))
|
||||
die(_("packfile is invalid: %s"), reuse_packfile->pack_name);
|
||||
|
||||
/*
|
||||
* Binary search to find the chunk that "where" is in. Note
|
||||
* that we're not looking for an exact match, just the first
|
||||
* chunk that contains it (which implicitly ends at the start
|
||||
* of the next chunk.
|
||||
*/
|
||||
static off_t find_reused_offset(off_t where)
|
||||
{
|
||||
int lo = 0, hi = reused_chunks_nr;
|
||||
while (lo < hi) {
|
||||
int mi = lo + ((hi - lo) / 2);
|
||||
if (where == reused_chunks[mi].original)
|
||||
return reused_chunks[mi].difference;
|
||||
if (where < reused_chunks[mi].original)
|
||||
hi = mi;
|
||||
else
|
||||
lo = mi + 1;
|
||||
}
|
||||
fd = git_open(reuse_packfile->pack_name);
|
||||
if (fd < 0)
|
||||
die_errno(_("unable to open packfile for reuse: %s"),
|
||||
reuse_packfile->pack_name);
|
||||
|
||||
/*
|
||||
* The first chunk starts at zero, so we can't have gone below
|
||||
* there.
|
||||
*/
|
||||
assert(lo);
|
||||
return reused_chunks[lo-1].difference;
|
||||
}
|
||||
if (lseek(fd, sizeof(struct pack_header), SEEK_SET) == -1)
|
||||
die_errno(_("unable to seek in reused packfile"));
|
||||
|
||||
static void write_reused_pack_one(size_t pos, struct hashfile *out,
|
||||
struct pack_window **w_curs)
|
||||
{
|
||||
off_t offset, next, cur;
|
||||
enum object_type type;
|
||||
unsigned long size;
|
||||
if (reuse_packfile_offset < 0)
|
||||
reuse_packfile_offset = reuse_packfile->pack_size - the_hash_algo->rawsz;
|
||||
|
||||
offset = reuse_packfile->revindex[pos].offset;
|
||||
next = reuse_packfile->revindex[pos + 1].offset;
|
||||
total = to_write = reuse_packfile_offset - sizeof(struct pack_header);
|
||||
|
||||
record_reused_object(offset, offset - hashfile_total(out));
|
||||
while (to_write) {
|
||||
int read_pack = xread(fd, buffer, sizeof(buffer));
|
||||
|
||||
cur = offset;
|
||||
type = unpack_object_header(reuse_packfile, w_curs, &cur, &size);
|
||||
assert(type >= 0);
|
||||
if (read_pack <= 0)
|
||||
die_errno(_("unable to read from reused packfile"));
|
||||
|
||||
if (type == OBJ_OFS_DELTA) {
|
||||
off_t base_offset;
|
||||
off_t fixup;
|
||||
if (read_pack > to_write)
|
||||
read_pack = to_write;
|
||||
|
||||
unsigned char header[MAX_PACK_OBJECT_HEADER];
|
||||
unsigned len;
|
||||
|
||||
base_offset = get_delta_base(reuse_packfile, w_curs, &cur, type, offset);
|
||||
assert(base_offset != 0);
|
||||
|
||||
/* Convert to REF_DELTA if we must... */
|
||||
if (!allow_ofs_delta) {
|
||||
int base_pos = find_revindex_position(reuse_packfile, base_offset);
|
||||
struct object_id base_oid;
|
||||
|
||||
nth_packed_object_id(&base_oid, reuse_packfile,
|
||||
reuse_packfile->revindex[base_pos].nr);
|
||||
|
||||
len = encode_in_pack_object_header(header, sizeof(header),
|
||||
OBJ_REF_DELTA, size);
|
||||
hashwrite(out, header, len);
|
||||
hashwrite(out, base_oid.hash, 20);
|
||||
copy_pack_data(out, reuse_packfile, w_curs, cur, next - cur);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise see if we need to rewrite the offset... */
|
||||
fixup = find_reused_offset(offset) -
|
||||
find_reused_offset(base_offset);
|
||||
if (fixup) {
|
||||
unsigned char ofs_header[10];
|
||||
unsigned i, ofs_len;
|
||||
off_t ofs = offset - base_offset - fixup;
|
||||
|
||||
len = encode_in_pack_object_header(header, sizeof(header),
|
||||
OBJ_OFS_DELTA, size);
|
||||
|
||||
i = sizeof(ofs_header) - 1;
|
||||
ofs_header[i] = ofs & 127;
|
||||
while (ofs >>= 7)
|
||||
ofs_header[--i] = 128 | (--ofs & 127);
|
||||
|
||||
ofs_len = sizeof(ofs_header) - i;
|
||||
|
||||
hashwrite(out, header, len);
|
||||
hashwrite(out, ofs_header + sizeof(ofs_header) - ofs_len, ofs_len);
|
||||
copy_pack_data(out, reuse_packfile, w_curs, cur, next - cur);
|
||||
return;
|
||||
}
|
||||
|
||||
/* ...otherwise we have no fixup, and can write it verbatim */
|
||||
}
|
||||
|
||||
copy_pack_data(out, reuse_packfile, w_curs, offset, next - offset);
|
||||
}
|
||||
|
||||
static size_t write_reused_pack_verbatim(struct hashfile *out,
|
||||
struct pack_window **w_curs)
|
||||
{
|
||||
size_t pos = 0;
|
||||
|
||||
while (pos < reuse_packfile_bitmap->word_alloc &&
|
||||
reuse_packfile_bitmap->words[pos] == (eword_t)~0)
|
||||
pos++;
|
||||
|
||||
if (pos) {
|
||||
off_t to_write;
|
||||
|
||||
written = (pos * BITS_IN_EWORD);
|
||||
to_write = reuse_packfile->revindex[written].offset
|
||||
- sizeof(struct pack_header);
|
||||
|
||||
/* We're recording one chunk, not one object. */
|
||||
record_reused_object(sizeof(struct pack_header), 0);
|
||||
hashflush(out);
|
||||
copy_pack_data(out, reuse_packfile, w_curs,
|
||||
sizeof(struct pack_header), to_write);
|
||||
hashwrite(f, buffer, read_pack);
|
||||
to_write -= read_pack;
|
||||
|
||||
/*
|
||||
* We don't know the actual number of objects written,
|
||||
* only how many bytes written, how many bytes total, and
|
||||
* how many objects total. So we can fake it by pretending all
|
||||
* objects we are writing are the same size. This gives us a
|
||||
* smooth progress meter, and at the end it matches the true
|
||||
* answer.
|
||||
*/
|
||||
written = reuse_packfile_objects *
|
||||
(((double)(total - to_write)) / total);
|
||||
display_progress(progress_state, written);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
static void write_reused_pack(struct hashfile *f)
|
||||
{
|
||||
size_t i = 0;
|
||||
uint32_t offset;
|
||||
struct pack_window *w_curs = NULL;
|
||||
|
||||
if (allow_ofs_delta)
|
||||
i = write_reused_pack_verbatim(f, &w_curs);
|
||||
|
||||
for (; i < reuse_packfile_bitmap->word_alloc; ++i) {
|
||||
eword_t word = reuse_packfile_bitmap->words[i];
|
||||
size_t pos = (i * BITS_IN_EWORD);
|
||||
|
||||
for (offset = 0; offset < BITS_IN_EWORD; ++offset) {
|
||||
if ((word >> offset) == 0)
|
||||
break;
|
||||
|
||||
offset += ewah_bit_ctz64(word >> offset);
|
||||
write_reused_pack_one(pos + offset, f, &w_curs);
|
||||
display_progress(progress_state, ++written);
|
||||
}
|
||||
}
|
||||
|
||||
unuse_pack(&w_curs);
|
||||
close(fd);
|
||||
written = reuse_packfile_objects;
|
||||
display_progress(progress_state, written);
|
||||
return reuse_packfile_offset - sizeof(struct pack_header);
|
||||
}
|
||||
|
||||
static const char no_split_warning[] = N_(
|
||||
|
|
@ -998,9 +867,11 @@ static void write_pack_file(void)
|
|||
offset = write_pack_header(f, nr_remaining);
|
||||
|
||||
if (reuse_packfile) {
|
||||
off_t packfile_size;
|
||||
assert(pack_to_stdout);
|
||||
write_reused_pack(f);
|
||||
offset = hashfile_total(f);
|
||||
|
||||
packfile_size = write_reused_pack(f);
|
||||
offset += packfile_size;
|
||||
}
|
||||
|
||||
nr_written = 0;
|
||||
|
|
@ -1125,15 +996,12 @@ static int no_try_delta(const char *path)
|
|||
* few lines later when we want to add the new entry.
|
||||
*/
|
||||
static int have_duplicate_entry(const struct object_id *oid,
|
||||
int exclude)
|
||||
int exclude,
|
||||
uint32_t *index_pos)
|
||||
{
|
||||
struct object_entry *entry;
|
||||
|
||||
if (reuse_packfile_bitmap &&
|
||||
bitmap_walk_contains(bitmap_git, reuse_packfile_bitmap, oid))
|
||||
return 1;
|
||||
|
||||
entry = packlist_find(&to_pack, oid);
|
||||
entry = packlist_find(&to_pack, oid, index_pos);
|
||||
if (!entry)
|
||||
return 0;
|
||||
|
||||
|
|
@ -1273,12 +1141,13 @@ static void create_object_entry(const struct object_id *oid,
|
|||
uint32_t hash,
|
||||
int exclude,
|
||||
int no_try_delta,
|
||||
uint32_t index_pos,
|
||||
struct packed_git *found_pack,
|
||||
off_t found_offset)
|
||||
{
|
||||
struct object_entry *entry;
|
||||
|
||||
entry = packlist_alloc(&to_pack, oid);
|
||||
entry = packlist_alloc(&to_pack, oid->hash, index_pos);
|
||||
entry->hash = hash;
|
||||
oe_set_type(entry, type);
|
||||
if (exclude)
|
||||
|
|
@ -1302,10 +1171,11 @@ static int add_object_entry(const struct object_id *oid, enum object_type type,
|
|||
{
|
||||
struct packed_git *found_pack = NULL;
|
||||
off_t found_offset = 0;
|
||||
uint32_t index_pos;
|
||||
|
||||
display_progress(progress_state, ++nr_seen);
|
||||
|
||||
if (have_duplicate_entry(oid, exclude))
|
||||
if (have_duplicate_entry(oid, exclude, &index_pos))
|
||||
return 0;
|
||||
|
||||
if (!want_object_in_pack(oid, exclude, &found_pack, &found_offset)) {
|
||||
|
|
@ -1320,7 +1190,7 @@ static int add_object_entry(const struct object_id *oid, enum object_type type,
|
|||
|
||||
create_object_entry(oid, type, pack_name_hash(name),
|
||||
exclude, name && no_try_delta(name),
|
||||
found_pack, found_offset);
|
||||
index_pos, found_pack, found_offset);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -1329,15 +1199,17 @@ static int add_object_entry_from_bitmap(const struct object_id *oid,
|
|||
int flags, uint32_t name_hash,
|
||||
struct packed_git *pack, off_t offset)
|
||||
{
|
||||
uint32_t index_pos;
|
||||
|
||||
display_progress(progress_state, ++nr_seen);
|
||||
|
||||
if (have_duplicate_entry(oid, 0))
|
||||
if (have_duplicate_entry(oid, 0, &index_pos))
|
||||
return 0;
|
||||
|
||||
if (!want_object_in_pack(oid, 0, &pack, &offset))
|
||||
return 0;
|
||||
|
||||
create_object_entry(oid, type, name_hash, 0, 0, pack, offset);
|
||||
create_object_entry(oid, type, name_hash, 0, 0, index_pos, pack, offset);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -1619,17 +1491,23 @@ static void cleanup_preferred_base(void)
|
|||
* deltify other objects against, in order to avoid
|
||||
* circular deltas.
|
||||
*/
|
||||
static int can_reuse_delta(const struct object_id *base_oid,
|
||||
static int can_reuse_delta(const unsigned char *base_sha1,
|
||||
struct object_entry *delta,
|
||||
struct object_entry **base_out)
|
||||
{
|
||||
struct object_entry *base;
|
||||
struct object_id base_oid;
|
||||
|
||||
if (!base_sha1)
|
||||
return 0;
|
||||
|
||||
oidread(&base_oid, base_sha1);
|
||||
|
||||
/*
|
||||
* First see if we're already sending the base (or it's explicitly in
|
||||
* our "excluded" list).
|
||||
*/
|
||||
base = packlist_find(&to_pack, base_oid);
|
||||
base = packlist_find(&to_pack, &base_oid, NULL);
|
||||
if (base) {
|
||||
if (!in_same_island(&delta->idx.oid, &base->idx.oid))
|
||||
return 0;
|
||||
|
|
@ -1642,9 +1520,9 @@ static int can_reuse_delta(const struct object_id *base_oid,
|
|||
* even if it was buried too deep in history to make it into the
|
||||
* packing list.
|
||||
*/
|
||||
if (thin && bitmap_has_oid_in_uninteresting(bitmap_git, base_oid)) {
|
||||
if (thin && bitmap_has_oid_in_uninteresting(bitmap_git, &base_oid)) {
|
||||
if (use_delta_islands) {
|
||||
if (!in_same_island(&delta->idx.oid, base_oid))
|
||||
if (!in_same_island(&delta->idx.oid, &base_oid))
|
||||
return 0;
|
||||
}
|
||||
*base_out = NULL;
|
||||
|
|
@ -1661,8 +1539,7 @@ static void check_object(struct object_entry *entry)
|
|||
if (IN_PACK(entry)) {
|
||||
struct packed_git *p = IN_PACK(entry);
|
||||
struct pack_window *w_curs = NULL;
|
||||
int have_base = 0;
|
||||
struct object_id base_ref;
|
||||
const unsigned char *base_ref = NULL;
|
||||
struct object_entry *base_entry;
|
||||
unsigned long used, used_0;
|
||||
unsigned long avail;
|
||||
|
|
@ -1703,13 +1580,9 @@ static void check_object(struct object_entry *entry)
|
|||
unuse_pack(&w_curs);
|
||||
return;
|
||||
case OBJ_REF_DELTA:
|
||||
if (reuse_delta && !entry->preferred_base) {
|
||||
oidread(&base_ref,
|
||||
use_pack(p, &w_curs,
|
||||
entry->in_pack_offset + used,
|
||||
NULL));
|
||||
have_base = 1;
|
||||
}
|
||||
if (reuse_delta && !entry->preferred_base)
|
||||
base_ref = use_pack(p, &w_curs,
|
||||
entry->in_pack_offset + used, NULL);
|
||||
entry->in_pack_header_size = used + the_hash_algo->rawsz;
|
||||
break;
|
||||
case OBJ_OFS_DELTA:
|
||||
|
|
@ -1739,15 +1612,13 @@ static void check_object(struct object_entry *entry)
|
|||
revidx = find_pack_revindex(p, ofs);
|
||||
if (!revidx)
|
||||
goto give_up;
|
||||
if (!nth_packed_object_id(&base_ref, p, revidx->nr))
|
||||
have_base = 1;
|
||||
base_ref = nth_packed_object_sha1(p, revidx->nr);
|
||||
}
|
||||
entry->in_pack_header_size = used + used_0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (have_base &&
|
||||
can_reuse_delta(&base_ref, entry, &base_entry)) {
|
||||
if (can_reuse_delta(base_ref, entry, &base_entry)) {
|
||||
oe_set_type(entry, entry->in_pack_type);
|
||||
SET_SIZE(entry, in_pack_size); /* delta size */
|
||||
SET_DELTA_SIZE(entry, in_pack_size);
|
||||
|
|
@ -1757,7 +1628,7 @@ static void check_object(struct object_entry *entry)
|
|||
entry->delta_sibling_idx = base_entry->delta_child_idx;
|
||||
SET_DELTA_CHILD(base_entry, entry);
|
||||
} else {
|
||||
SET_DELTA_EXT(entry, &base_ref);
|
||||
SET_DELTA_EXT(entry, base_ref);
|
||||
}
|
||||
|
||||
unuse_pack(&w_curs);
|
||||
|
|
@ -2471,6 +2342,15 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
|
|||
free(array);
|
||||
}
|
||||
|
||||
static void try_to_free_from_threads(size_t size)
|
||||
{
|
||||
packing_data_lock(&to_pack);
|
||||
release_pack_memory(size);
|
||||
packing_data_unlock(&to_pack);
|
||||
}
|
||||
|
||||
static try_to_free_t old_try_to_free_routine;
|
||||
|
||||
/*
|
||||
* The main object list is split into smaller lists, each is handed to
|
||||
* one worker.
|
||||
|
|
@ -2511,10 +2391,12 @@ static void init_threaded_search(void)
|
|||
pthread_mutex_init(&cache_mutex, NULL);
|
||||
pthread_mutex_init(&progress_mutex, NULL);
|
||||
pthread_cond_init(&progress_cond, NULL);
|
||||
old_try_to_free_routine = set_try_to_free_routine(try_to_free_from_threads);
|
||||
}
|
||||
|
||||
static void cleanup_threaded_search(void)
|
||||
{
|
||||
set_try_to_free_routine(old_try_to_free_routine);
|
||||
pthread_cond_destroy(&progress_cond);
|
||||
pthread_mutex_destroy(&cache_mutex);
|
||||
pthread_mutex_destroy(&progress_mutex);
|
||||
|
|
@ -2686,13 +2568,6 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
|
|||
free(p);
|
||||
}
|
||||
|
||||
static int obj_is_packed(const struct object_id *oid)
|
||||
{
|
||||
return packlist_find(&to_pack, oid) ||
|
||||
(reuse_packfile_bitmap &&
|
||||
bitmap_walk_contains(bitmap_git, reuse_packfile_bitmap, oid));
|
||||
}
|
||||
|
||||
static void add_tag_chain(const struct object_id *oid)
|
||||
{
|
||||
struct tag *tag;
|
||||
|
|
@ -2704,7 +2579,7 @@ static void add_tag_chain(const struct object_id *oid)
|
|||
* it was included via bitmaps, we would not have parsed it
|
||||
* previously).
|
||||
*/
|
||||
if (obj_is_packed(oid))
|
||||
if (packlist_find(&to_pack, oid, NULL))
|
||||
return;
|
||||
|
||||
tag = lookup_tag(the_repository, oid);
|
||||
|
|
@ -2728,7 +2603,7 @@ static int add_ref_tag(const char *path, const struct object_id *oid, int flag,
|
|||
|
||||
if (starts_with(path, "refs/tags/") && /* is a tag? */
|
||||
!peel_ref(path, &peeled) && /* peelable? */
|
||||
obj_is_packed(&peeled)) /* object packed? */
|
||||
packlist_find(&to_pack, &peeled, NULL)) /* object packed? */
|
||||
add_tag_chain(oid);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2796,7 +2671,6 @@ static void prepare_pack(int window, int depth)
|
|||
|
||||
if (nr_deltas && n > 1) {
|
||||
unsigned nr_done = 0;
|
||||
|
||||
if (progress)
|
||||
progress_state = start_progress(_("Compressing objects"),
|
||||
nr_deltas);
|
||||
|
|
@ -2841,8 +2715,8 @@ static int git_pack_config(const char *k, const char *v, void *cb)
|
|||
use_bitmap_index_default = git_config_bool(k, v);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(k, "pack.allowpackreuse")) {
|
||||
allow_pack_reuse = git_config_bool(k, v);
|
||||
if (!strcmp(k, "pack.usesparse")) {
|
||||
sparse = git_config_bool(k, v);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp(k, "pack.threads")) {
|
||||
|
|
@ -2929,7 +2803,7 @@ static void show_object(struct object *obj, const char *name, void *data)
|
|||
for (p = strchr(name, '/'); p; p = strchr(p + 1, '/'))
|
||||
depth++;
|
||||
|
||||
ent = packlist_find(&to_pack, &obj->oid);
|
||||
ent = packlist_find(&to_pack, &obj->oid, NULL);
|
||||
if (ent && depth > oe_tree_depth(&to_pack, ent))
|
||||
oe_set_tree_depth(&to_pack, ent, depth);
|
||||
}
|
||||
|
|
@ -3055,7 +2929,7 @@ static void add_objects_in_unpacked_packs(void)
|
|||
in_pack.alloc);
|
||||
|
||||
for (i = 0; i < p->num_objects; i++) {
|
||||
nth_packed_object_id(&oid, p, i);
|
||||
nth_packed_object_oid(&oid, p, i);
|
||||
o = lookup_unknown_object(&oid);
|
||||
if (!(o->flags & OBJECT_ADDED))
|
||||
mark_in_pack_object(o, p, &in_pack);
|
||||
|
|
@ -3159,8 +3033,8 @@ static void loosen_unused_packed_objects(void)
|
|||
die(_("cannot open pack index"));
|
||||
|
||||
for (i = 0; i < p->num_objects; i++) {
|
||||
nth_packed_object_id(&oid, p, i);
|
||||
if (!packlist_find(&to_pack, &oid) &&
|
||||
nth_packed_object_oid(&oid, p, i);
|
||||
if (!packlist_find(&to_pack, &oid, NULL) &&
|
||||
!has_sha1_pack_kept_or_nonlocal(&oid) &&
|
||||
!loosened_object_can_be_discarded(&oid, p->mtime))
|
||||
if (force_object_loose(&oid, p->mtime))
|
||||
|
|
@ -3176,8 +3050,8 @@ static void loosen_unused_packed_objects(void)
|
|||
*/
|
||||
static int pack_options_allow_reuse(void)
|
||||
{
|
||||
return allow_pack_reuse &&
|
||||
pack_to_stdout &&
|
||||
return pack_to_stdout &&
|
||||
allow_ofs_delta &&
|
||||
!ignore_packed_keep_on_disk &&
|
||||
!ignore_packed_keep_in_core &&
|
||||
(!local || !have_non_local_packs) &&
|
||||
|
|
@ -3186,7 +3060,7 @@ static int pack_options_allow_reuse(void)
|
|||
|
||||
static int get_object_list_from_bitmap(struct rev_info *revs)
|
||||
{
|
||||
if (!(bitmap_git = prepare_bitmap_walk(revs, &filter_options)))
|
||||
if (!(bitmap_git = prepare_bitmap_walk(revs)))
|
||||
return -1;
|
||||
|
||||
if (pack_options_allow_reuse() &&
|
||||
|
|
@ -3194,14 +3068,13 @@ static int get_object_list_from_bitmap(struct rev_info *revs)
|
|||
bitmap_git,
|
||||
&reuse_packfile,
|
||||
&reuse_packfile_objects,
|
||||
&reuse_packfile_bitmap)) {
|
||||
&reuse_packfile_offset)) {
|
||||
assert(reuse_packfile_objects);
|
||||
nr_result += reuse_packfile_objects;
|
||||
display_progress(progress_state, nr_result);
|
||||
}
|
||||
|
||||
traverse_bitmap_commit_list(bitmap_git, revs,
|
||||
&add_object_entry_from_bitmap);
|
||||
traverse_bitmap_commit_list(bitmap_git, &add_object_entry_from_bitmap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3470,10 +3343,6 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
|||
read_replace_refs = 0;
|
||||
|
||||
sparse = git_env_bool("GIT_TEST_PACK_SPARSE", 0);
|
||||
prepare_repo_settings(the_repository);
|
||||
if (!sparse && the_repository->settings.pack_use_sparse != -1)
|
||||
sparse = the_repository->settings.pack_use_sparse;
|
||||
|
||||
reset_pack_idx_option(&pack_idx_opts);
|
||||
git_config(git_pack_config, NULL);
|
||||
|
||||
|
|
@ -3565,6 +3434,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
|||
if (filter_options.choice) {
|
||||
if (!pack_to_stdout)
|
||||
die(_("cannot use --filter without --stdout"));
|
||||
use_bitmap_index = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3655,9 +3525,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
|
|||
if (progress)
|
||||
fprintf_ln(stderr,
|
||||
_("Total %"PRIu32" (delta %"PRIu32"),"
|
||||
" reused %"PRIu32" (delta %"PRIu32"),"
|
||||
" pack-reused %"PRIu32),
|
||||
written, written_delta, reused, reused_delta,
|
||||
reuse_packfile_objects);
|
||||
" reused %"PRIu32" (delta %"PRIu32")"),
|
||||
written, written_delta, reused, reused_delta);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
16
third_party/git/builtin/patch-id.c
vendored
16
third_party/git/builtin/patch-id.c
vendored
|
|
@ -1,12 +1,16 @@
|
|||
#include "cache.h"
|
||||
#include "builtin.h"
|
||||
#include "config.h"
|
||||
#include "diff.h"
|
||||
|
||||
static void flush_current_id(int patchlen, struct object_id *id, struct object_id *result)
|
||||
{
|
||||
if (patchlen)
|
||||
printf("%s %s\n", oid_to_hex(result), oid_to_hex(id));
|
||||
char name[50];
|
||||
|
||||
if (!patchlen)
|
||||
return;
|
||||
|
||||
memcpy(name, oid_to_hex(id), GIT_SHA1_HEXSZ + 1);
|
||||
printf("%s %s\n", oid_to_hex(result), name);
|
||||
}
|
||||
|
||||
static int remove_space(char *line)
|
||||
|
|
@ -56,9 +60,9 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
|
|||
{
|
||||
int patchlen = 0, found_next = 0;
|
||||
int before = -1, after = -1;
|
||||
git_hash_ctx ctx;
|
||||
git_SHA_CTX ctx;
|
||||
|
||||
the_hash_algo->init_fn(&ctx);
|
||||
git_SHA1_Init(&ctx);
|
||||
oidclr(result);
|
||||
|
||||
while (strbuf_getwholeline(line_buf, stdin, '\n') != EOF) {
|
||||
|
|
@ -118,7 +122,7 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
|
|||
/* Compute the sha without whitespace */
|
||||
len = remove_space(line);
|
||||
patchlen += len;
|
||||
the_hash_algo->update_fn(&ctx, line, len);
|
||||
git_SHA1_Update(&ctx, line, len);
|
||||
}
|
||||
|
||||
if (!found_next)
|
||||
|
|
|
|||
48
third_party/git/builtin/pull.c
vendored
48
third_party/git/builtin/pull.c
vendored
|
|
@ -15,7 +15,6 @@
|
|||
#include "sha1-array.h"
|
||||
#include "remote.h"
|
||||
#include "dir.h"
|
||||
#include "rebase.h"
|
||||
#include "refs.h"
|
||||
#include "refspec.h"
|
||||
#include "revision.h"
|
||||
|
|
@ -27,6 +26,15 @@
|
|||
#include "commit-reach.h"
|
||||
#include "sequencer.h"
|
||||
|
||||
enum rebase_type {
|
||||
REBASE_INVALID = -1,
|
||||
REBASE_FALSE = 0,
|
||||
REBASE_TRUE,
|
||||
REBASE_PRESERVE,
|
||||
REBASE_MERGES,
|
||||
REBASE_INTERACTIVE
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses the value of --rebase. If value is a false value, returns
|
||||
* REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is
|
||||
|
|
@ -37,9 +45,22 @@
|
|||
static enum rebase_type parse_config_rebase(const char *key, const char *value,
|
||||
int fatal)
|
||||
{
|
||||
enum rebase_type v = rebase_parse_value(value);
|
||||
if (v != REBASE_INVALID)
|
||||
return v;
|
||||
int v = git_parse_maybe_bool(value);
|
||||
|
||||
if (!v)
|
||||
return REBASE_FALSE;
|
||||
else if (v > 0)
|
||||
return REBASE_TRUE;
|
||||
else if (!strcmp(value, "preserve") || !strcmp(value, "p"))
|
||||
return REBASE_PRESERVE;
|
||||
else if (!strcmp(value, "merges") || !strcmp(value, "m"))
|
||||
return REBASE_MERGES;
|
||||
else if (!strcmp(value, "interactive") || !strcmp(value, "i"))
|
||||
return REBASE_INTERACTIVE;
|
||||
/*
|
||||
* Please update _git_config() in git-completion.bash when you
|
||||
* add new rebase modes.
|
||||
*/
|
||||
|
||||
if (fatal)
|
||||
die(_("Invalid value for %s: %s"), key, value);
|
||||
|
|
@ -86,7 +107,6 @@ static char *opt_ff;
|
|||
static char *opt_verify_signatures;
|
||||
static int opt_autostash = -1;
|
||||
static int config_autostash;
|
||||
static int check_trust_level = 1;
|
||||
static struct argv_array opt_strategies = ARGV_ARRAY_INIT;
|
||||
static struct argv_array opt_strategy_opts = ARGV_ARRAY_INIT;
|
||||
static char *opt_gpg_sign;
|
||||
|
|
@ -109,7 +129,6 @@ static char *opt_refmap;
|
|||
static char *opt_ipv4;
|
||||
static char *opt_ipv6;
|
||||
static int opt_show_forced_updates = -1;
|
||||
static char *set_upstream;
|
||||
|
||||
static struct option pull_options[] = {
|
||||
/* Shared options */
|
||||
|
|
@ -224,9 +243,6 @@ static struct option pull_options[] = {
|
|||
PARSE_OPT_NOARG),
|
||||
OPT_BOOL(0, "show-forced-updates", &opt_show_forced_updates,
|
||||
N_("check for forced-updates on all updated branches")),
|
||||
OPT_PASSTHRU(0, "set-upstream", &set_upstream, NULL,
|
||||
N_("set upstream for git pull/fetch"),
|
||||
PARSE_OPT_NOARG),
|
||||
|
||||
OPT_END()
|
||||
};
|
||||
|
|
@ -335,8 +351,6 @@ static enum rebase_type config_get_rebase(void)
|
|||
*/
|
||||
static int git_pull_config(const char *var, const char *value, void *cb)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (!strcmp(var, "rebase.autostash")) {
|
||||
config_autostash = git_config_bool(var, value);
|
||||
return 0;
|
||||
|
|
@ -344,14 +358,7 @@ static int git_pull_config(const char *var, const char *value, void *cb)
|
|||
recurse_submodules = git_config_bool(var, value) ?
|
||||
RECURSE_SUBMODULES_ON : RECURSE_SUBMODULES_OFF;
|
||||
return 0;
|
||||
} else if (!strcmp(var, "gpg.mintrustlevel")) {
|
||||
check_trust_level = 0;
|
||||
}
|
||||
|
||||
status = git_gpg_config(var, value, cb);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return git_default_config(var, value, cb);
|
||||
}
|
||||
|
||||
|
|
@ -549,8 +556,6 @@ static int run_fetch(const char *repo, const char **refspecs)
|
|||
argv_array_push(&args, "--show-forced-updates");
|
||||
else if (opt_show_forced_updates == 0)
|
||||
argv_array_push(&args, "--no-show-forced-updates");
|
||||
if (set_upstream)
|
||||
argv_array_push(&args, set_upstream);
|
||||
|
||||
if (repo) {
|
||||
argv_array_push(&args, repo);
|
||||
|
|
@ -576,8 +581,7 @@ static int pull_into_void(const struct object_id *merge_head,
|
|||
die(_("unable to access commit %s"),
|
||||
oid_to_hex(merge_head));
|
||||
|
||||
verify_merge_signature(commit, opt_verbosity,
|
||||
check_trust_level);
|
||||
verify_merge_signature(commit, opt_verbosity);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
80
third_party/git/builtin/push.c
vendored
80
third_party/git/builtin/push.c
vendored
|
|
@ -64,7 +64,6 @@ static struct string_list push_options_config = STRING_LIST_INIT_DUP;
|
|||
static const char *map_refspec(const char *ref,
|
||||
struct remote *remote, struct ref *local_refs)
|
||||
{
|
||||
const char *branch_name;
|
||||
struct ref *matched = NULL;
|
||||
|
||||
/* Does "ref" uniquely name our ref? */
|
||||
|
|
@ -85,8 +84,8 @@ static const char *map_refspec(const char *ref,
|
|||
}
|
||||
|
||||
if (push_default == PUSH_DEFAULT_UPSTREAM &&
|
||||
skip_prefix(matched->name, "refs/heads/", &branch_name)) {
|
||||
struct branch *branch = branch_get(branch_name);
|
||||
starts_with(matched->name, "refs/heads/")) {
|
||||
struct branch *branch = branch_get(matched->name + 11);
|
||||
if (branch->merge_nr == 1 && branch->merge[0]->src) {
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
strbuf_addf(&buf, "%s:%s",
|
||||
|
|
@ -144,8 +143,8 @@ static int push_url_of_remote(struct remote *remote, const char ***url_p)
|
|||
return remote->url_nr;
|
||||
}
|
||||
|
||||
static NORETURN void die_push_simple(struct branch *branch,
|
||||
struct remote *remote)
|
||||
static NORETURN int die_push_simple(struct branch *branch,
|
||||
struct remote *remote)
|
||||
{
|
||||
/*
|
||||
* There's no point in using shorten_unambiguous_ref here,
|
||||
|
|
@ -358,10 +357,8 @@ static int push_with_options(struct transport *transport, struct refspec *rs,
|
|||
|
||||
if (verbosity > 0)
|
||||
fprintf(stderr, _("Pushing to %s\n"), transport->url);
|
||||
trace2_region_enter("push", "transport_push", the_repository);
|
||||
err = transport_push(the_repository, transport,
|
||||
rs, flags, &reject_reasons);
|
||||
trace2_region_leave("push", "transport_push", the_repository);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "%s", push_get_color(PUSH_COLOR_ERROR));
|
||||
error(_("failed to push some refs to '%s'"), transport->url);
|
||||
|
|
@ -388,14 +385,30 @@ static int push_with_options(struct transport *transport, struct refspec *rs,
|
|||
}
|
||||
|
||||
static int do_push(const char *repo, int flags,
|
||||
const struct string_list *push_options,
|
||||
struct remote *remote)
|
||||
const struct string_list *push_options)
|
||||
{
|
||||
int i, errs;
|
||||
struct remote *remote = pushremote_get(repo);
|
||||
const char **url;
|
||||
int url_nr;
|
||||
struct refspec *push_refspec = &rs;
|
||||
|
||||
if (!remote) {
|
||||
if (repo)
|
||||
die(_("bad repository '%s'"), repo);
|
||||
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"));
|
||||
}
|
||||
|
||||
if (remote->mirror)
|
||||
flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
|
||||
|
||||
if (push_options->nr)
|
||||
flags |= TRANSPORT_PUSH_OPTIONS;
|
||||
|
||||
|
|
@ -535,7 +548,6 @@ int cmd_push(int argc, const char **argv, const char *prefix)
|
|||
struct string_list push_options_cmdline = STRING_LIST_INIT_DUP;
|
||||
struct string_list *push_options;
|
||||
const struct string_list_item *item;
|
||||
struct remote *remote;
|
||||
|
||||
struct option options[] = {
|
||||
OPT__VERBOSITY(&verbosity),
|
||||
|
|
@ -590,6 +602,20 @@ int cmd_push(int argc, const char **argv, const char *prefix)
|
|||
die(_("--delete is incompatible with --all, --mirror and --tags"));
|
||||
if (deleterefs && argc < 2)
|
||||
die(_("--delete doesn't make sense without any refs"));
|
||||
if (flags & TRANSPORT_PUSH_ALL) {
|
||||
if (tags)
|
||||
die(_("--all and --tags are incompatible"));
|
||||
if (argc >= 2)
|
||||
die(_("--all can't be combined with refspecs"));
|
||||
}
|
||||
if (flags & TRANSPORT_PUSH_MIRROR) {
|
||||
if (tags)
|
||||
die(_("--mirror and --tags are incompatible"));
|
||||
if (argc >= 2)
|
||||
die(_("--mirror can't be combined with refspecs"));
|
||||
}
|
||||
if ((flags & TRANSPORT_PUSH_ALL) && (flags & TRANSPORT_PUSH_MIRROR))
|
||||
die(_("--all and --mirror are incompatible"));
|
||||
|
||||
if (recurse_submodules == RECURSE_SUBMODULES_CHECK)
|
||||
flags |= TRANSPORT_RECURSE_SUBMODULES_CHECK;
|
||||
|
|
@ -606,43 +632,11 @@ int cmd_push(int argc, const char **argv, const char *prefix)
|
|||
set_refspecs(argv + 1, argc - 1, repo);
|
||||
}
|
||||
|
||||
remote = pushremote_get(repo);
|
||||
if (!remote) {
|
||||
if (repo)
|
||||
die(_("bad repository '%s'"), repo);
|
||||
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"));
|
||||
}
|
||||
|
||||
if (remote->mirror)
|
||||
flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
|
||||
|
||||
if (flags & TRANSPORT_PUSH_ALL) {
|
||||
if (tags)
|
||||
die(_("--all and --tags are incompatible"));
|
||||
if (argc >= 2)
|
||||
die(_("--all can't be combined with refspecs"));
|
||||
}
|
||||
if (flags & TRANSPORT_PUSH_MIRROR) {
|
||||
if (tags)
|
||||
die(_("--mirror and --tags are incompatible"));
|
||||
if (argc >= 2)
|
||||
die(_("--mirror can't be combined with refspecs"));
|
||||
}
|
||||
if ((flags & TRANSPORT_PUSH_ALL) && (flags & TRANSPORT_PUSH_MIRROR))
|
||||
die(_("--all and --mirror are incompatible"));
|
||||
|
||||
for_each_string_list_item(item, push_options)
|
||||
if (strchr(item->string, '\n'))
|
||||
die(_("push options must not have new line characters"));
|
||||
|
||||
rc = do_push(repo, flags, push_options, remote);
|
||||
rc = do_push(repo, flags, push_options);
|
||||
string_list_clear(&push_options_cmdline, 0);
|
||||
string_list_clear(&push_options_config, 0);
|
||||
if (rc == -1)
|
||||
|
|
|
|||
7
third_party/git/builtin/range-diff.c
vendored
7
third_party/git/builtin/range-diff.c
vendored
|
|
@ -15,16 +15,12 @@ int cmd_range_diff(int argc, const char **argv, const char *prefix)
|
|||
{
|
||||
int creation_factor = RANGE_DIFF_CREATION_FACTOR_DEFAULT;
|
||||
struct diff_options diffopt = { NULL };
|
||||
struct argv_array other_arg = ARGV_ARRAY_INIT;
|
||||
int simple_color = -1;
|
||||
struct option range_diff_options[] = {
|
||||
OPT_INTEGER(0, "creation-factor", &creation_factor,
|
||||
N_("Percentage by which creation is weighted")),
|
||||
OPT_BOOL(0, "no-dual-color", &simple_color,
|
||||
N_("use simple diff colors")),
|
||||
OPT_PASSTHRU_ARGV(0, "notes", &other_arg,
|
||||
N_("notes"), N_("passed to 'git log'"),
|
||||
PARSE_OPT_OPTARG),
|
||||
OPT_END()
|
||||
};
|
||||
struct option *options;
|
||||
|
|
@ -82,9 +78,8 @@ int cmd_range_diff(int argc, const char **argv, const char *prefix)
|
|||
FREE_AND_NULL(options);
|
||||
|
||||
res = show_range_diff(range1.buf, range2.buf, creation_factor,
|
||||
simple_color < 1, &diffopt, &other_arg);
|
||||
simple_color < 1, &diffopt);
|
||||
|
||||
argv_array_clear(&other_arg);
|
||||
strbuf_release(&range1);
|
||||
strbuf_release(&range2);
|
||||
|
||||
|
|
|
|||
2
third_party/git/builtin/read-tree.c
vendored
2
third_party/git/builtin/read-tree.c
vendored
|
|
@ -185,7 +185,7 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)
|
|||
|
||||
if (opts.reset || opts.merge || opts.prefix) {
|
||||
if (read_cache_unmerged() && (opts.prefix || opts.merge))
|
||||
die(_("You need to resolve your current index first"));
|
||||
die("You need to resolve your current index first");
|
||||
stage = opts.merge = 1;
|
||||
}
|
||||
resolve_undo_clear();
|
||||
|
|
|
|||
414
third_party/git/builtin/rebase.c
vendored
414
third_party/git/builtin/rebase.c
vendored
|
|
@ -29,8 +29,8 @@
|
|||
#include "rebase-interactive.h"
|
||||
|
||||
static char const * const builtin_rebase_usage[] = {
|
||||
N_("git rebase [-i] [options] [--exec <cmd>] "
|
||||
"[--onto <newbase> | --keep-base] [<upstream> [<branch>]]"),
|
||||
N_("git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] "
|
||||
"[<upstream>] [<branch>]"),
|
||||
N_("git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] "
|
||||
"--root [<branch>]"),
|
||||
N_("git rebase --continue | --abort | --skip | --edit-todo"),
|
||||
|
|
@ -44,22 +44,14 @@ static GIT_PATH_FUNC(merge_dir, "rebase-merge")
|
|||
|
||||
enum rebase_type {
|
||||
REBASE_UNSPECIFIED = -1,
|
||||
REBASE_APPLY,
|
||||
REBASE_AM,
|
||||
REBASE_MERGE,
|
||||
REBASE_INTERACTIVE,
|
||||
REBASE_PRESERVE_MERGES
|
||||
};
|
||||
|
||||
enum empty_type {
|
||||
EMPTY_UNSPECIFIED = -1,
|
||||
EMPTY_DROP,
|
||||
EMPTY_KEEP,
|
||||
EMPTY_ASK
|
||||
};
|
||||
|
||||
struct rebase_options {
|
||||
enum rebase_type type;
|
||||
enum empty_type empty;
|
||||
const char *default_backend;
|
||||
const char *state_dir;
|
||||
struct commit *upstream;
|
||||
const char *upstream_name;
|
||||
|
|
@ -70,7 +62,7 @@ struct rebase_options {
|
|||
const char *onto_name;
|
||||
const char *revisions;
|
||||
const char *switch_to;
|
||||
int root, root_with_onto;
|
||||
int root;
|
||||
struct object_id *squash_onto;
|
||||
struct commit *restrict_revision;
|
||||
int dont_finish_rebase;
|
||||
|
|
@ -85,6 +77,7 @@ struct rebase_options {
|
|||
const char *action;
|
||||
int signoff;
|
||||
int allow_rerere_autoupdate;
|
||||
int keep_empty;
|
||||
int autosquash;
|
||||
char *gpg_sign_opt;
|
||||
int autostash;
|
||||
|
|
@ -99,8 +92,6 @@ struct rebase_options {
|
|||
|
||||
#define REBASE_OPTIONS_INIT { \
|
||||
.type = REBASE_UNSPECIFIED, \
|
||||
.empty = EMPTY_UNSPECIFIED, \
|
||||
.default_backend = "merge", \
|
||||
.flags = REBASE_NO_QUIET, \
|
||||
.git_am_opts = ARGV_ARRAY_INIT, \
|
||||
.git_format_patch_opt = STRBUF_INIT \
|
||||
|
|
@ -119,9 +110,6 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)
|
|||
replay.allow_rerere_auto = opts->allow_rerere_autoupdate;
|
||||
replay.allow_empty = 1;
|
||||
replay.allow_empty_message = opts->allow_empty_message;
|
||||
replay.drop_redundant_commits = (opts->empty == EMPTY_DROP);
|
||||
replay.keep_redundant_commits = (opts->empty == EMPTY_KEEP);
|
||||
replay.quiet = !(opts->flags & REBASE_NO_QUIET);
|
||||
replay.verbose = opts->flags & REBASE_VERBOSE;
|
||||
replay.reschedule_failed_exec = opts->reschedule_failed_exec;
|
||||
replay.gpg_sign = xstrdup_or_null(opts->gpg_sign_opt);
|
||||
|
|
@ -129,11 +117,6 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)
|
|||
if (opts->strategy_opts)
|
||||
parse_strategy_opts(&replay, opts->strategy_opts);
|
||||
|
||||
if (opts->squash_onto) {
|
||||
oidcpy(&replay.squash_onto, opts->squash_onto);
|
||||
replay.have_squash_onto = 1;
|
||||
}
|
||||
|
||||
return replay;
|
||||
}
|
||||
|
||||
|
|
@ -258,17 +241,21 @@ static int edit_todo_file(unsigned flags)
|
|||
}
|
||||
|
||||
static int get_revision_ranges(struct commit *upstream, struct commit *onto,
|
||||
struct object_id *orig_head, const char **head_hash,
|
||||
const char **head_hash,
|
||||
char **revisions, char **shortrevisions)
|
||||
{
|
||||
struct commit *base_rev = upstream ? upstream : onto;
|
||||
const char *shorthead;
|
||||
struct object_id orig_head;
|
||||
|
||||
*head_hash = find_unique_abbrev(orig_head, GIT_MAX_HEXSZ);
|
||||
if (get_oid("HEAD", &orig_head))
|
||||
return error(_("no HEAD?"));
|
||||
|
||||
*head_hash = find_unique_abbrev(&orig_head, GIT_MAX_HEXSZ);
|
||||
*revisions = xstrfmt("%s...%s", oid_to_hex(&base_rev->object.oid),
|
||||
*head_hash);
|
||||
|
||||
shorthead = find_unique_abbrev(orig_head, DEFAULT_ABBREV);
|
||||
shorthead = find_unique_abbrev(&orig_head, DEFAULT_ABBREV);
|
||||
|
||||
if (upstream) {
|
||||
const char *shortrev;
|
||||
|
|
@ -322,8 +309,12 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
|
|||
struct replay_opts replay = get_replay_opts(opts);
|
||||
struct string_list commands = STRING_LIST_INIT_DUP;
|
||||
|
||||
if (get_revision_ranges(opts->upstream, opts->onto, &opts->orig_head,
|
||||
&head_hash, &revisions, &shortrevisions))
|
||||
if (prepare_branch_to_be_rebased(the_repository, &replay,
|
||||
opts->switch_to))
|
||||
return -1;
|
||||
|
||||
if (get_revision_ranges(opts->upstream, opts->onto, &head_hash,
|
||||
&revisions, &shortrevisions))
|
||||
return -1;
|
||||
|
||||
if (init_basic_state(&replay,
|
||||
|
|
@ -341,8 +332,8 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
|
|||
|
||||
argv_array_pushl(&make_script_args, "", revisions, NULL);
|
||||
if (opts->restrict_revision)
|
||||
argv_array_pushf(&make_script_args, "^%s",
|
||||
oid_to_hex(&opts->restrict_revision->object.oid));
|
||||
argv_array_push(&make_script_args,
|
||||
oid_to_hex(&opts->restrict_revision->object.oid));
|
||||
|
||||
ret = sequencer_make_script(the_repository, &todo_list.buf,
|
||||
make_script_args.argc, make_script_args.argv,
|
||||
|
|
@ -371,7 +362,7 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int run_sequencer_rebase(struct rebase_options *opts,
|
||||
static int run_rebase_interactive(struct rebase_options *opts,
|
||||
enum action command)
|
||||
{
|
||||
unsigned flags = 0;
|
||||
|
|
@ -379,10 +370,10 @@ static int run_sequencer_rebase(struct rebase_options *opts,
|
|||
|
||||
git_config_get_bool("rebase.abbreviatecommands", &abbreviate_commands);
|
||||
|
||||
flags |= opts->keep_empty ? TODO_LIST_KEEP_EMPTY : 0;
|
||||
flags |= abbreviate_commands ? TODO_LIST_ABBREVIATE_CMDS : 0;
|
||||
flags |= opts->rebase_merges ? TODO_LIST_REBASE_MERGES : 0;
|
||||
flags |= opts->rebase_cousins > 0 ? TODO_LIST_REBASE_COUSINS : 0;
|
||||
flags |= opts->root_with_onto ? TODO_LIST_ROOT_WITH_ONTO : 0;
|
||||
flags |= command == ACTION_SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0;
|
||||
|
||||
switch (command) {
|
||||
|
|
@ -442,21 +433,6 @@ static int run_sequencer_rebase(struct rebase_options *opts,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int parse_opt_keep_empty(const struct option *opt, const char *arg,
|
||||
int unset)
|
||||
{
|
||||
struct rebase_options *opts = opt->value;
|
||||
|
||||
BUG_ON_OPT_ARG(arg);
|
||||
|
||||
/*
|
||||
* If we ever want to remap --keep-empty to --empty=keep, insert:
|
||||
* opts->empty = unset ? EMPTY_UNSPECIFIED : EMPTY_KEEP;
|
||||
*/
|
||||
opts->type = REBASE_MERGE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char * const builtin_rebase_interactive_usage[] = {
|
||||
N_("git rebase--interactive [<options>]"),
|
||||
NULL
|
||||
|
|
@ -470,13 +446,9 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
|
|||
struct option options[] = {
|
||||
OPT_NEGBIT(0, "ff", &opts.flags, N_("allow fast-forward"),
|
||||
REBASE_FORCE),
|
||||
{ OPTION_CALLBACK, 'k', "keep-empty", &options, NULL,
|
||||
N_("(DEPRECATED) keep empty commits"),
|
||||
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN,
|
||||
parse_opt_keep_empty },
|
||||
OPT_BOOL_F(0, "allow-empty-message", &opts.allow_empty_message,
|
||||
N_("allow commits with empty messages"),
|
||||
PARSE_OPT_HIDDEN),
|
||||
OPT_BOOL(0, "keep-empty", &opts.keep_empty, N_("keep empty commits")),
|
||||
OPT_BOOL(0, "allow-empty-message", &opts.allow_empty_message,
|
||||
N_("allow commits with empty messages")),
|
||||
OPT_BOOL(0, "rebase-merges", &opts.rebase_merges, N_("rebase merge commits")),
|
||||
OPT_BOOL(0, "rebase-cousins", &opts.rebase_cousins,
|
||||
N_("keep original branch points of cousins")),
|
||||
|
|
@ -546,26 +518,28 @@ int cmd_rebase__interactive(int argc, const char **argv, const char *prefix)
|
|||
warning(_("--[no-]rebase-cousins has no effect without "
|
||||
"--rebase-merges"));
|
||||
|
||||
return !!run_sequencer_rebase(&opts, command);
|
||||
return !!run_rebase_interactive(&opts, command);
|
||||
}
|
||||
|
||||
static int is_merge(struct rebase_options *opts)
|
||||
static int is_interactive(struct rebase_options *opts)
|
||||
{
|
||||
return opts->type == REBASE_MERGE ||
|
||||
return opts->type == REBASE_INTERACTIVE ||
|
||||
opts->type == REBASE_PRESERVE_MERGES;
|
||||
}
|
||||
|
||||
static void imply_merge(struct rebase_options *opts, const char *option)
|
||||
static void imply_interactive(struct rebase_options *opts, const char *option)
|
||||
{
|
||||
switch (opts->type) {
|
||||
case REBASE_APPLY:
|
||||
case REBASE_AM:
|
||||
die(_("%s requires an interactive rebase"), option);
|
||||
break;
|
||||
case REBASE_MERGE:
|
||||
case REBASE_INTERACTIVE:
|
||||
case REBASE_PRESERVE_MERGES:
|
||||
break;
|
||||
case REBASE_MERGE:
|
||||
/* we now implement --merge via --interactive */
|
||||
default:
|
||||
opts->type = REBASE_MERGE; /* implied */
|
||||
opts->type = REBASE_INTERACTIVE; /* implied */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -691,8 +665,8 @@ static int rebase_write_basic_state(struct rebase_options *opts)
|
|||
opts->onto ? oid_to_hex(&opts->onto->object.oid) : "");
|
||||
write_file(state_dir_path("orig-head", opts), "%s",
|
||||
oid_to_hex(&opts->orig_head));
|
||||
if (!(opts->flags & REBASE_NO_QUIET))
|
||||
write_file(state_dir_path("quiet", opts), "%s", "");
|
||||
write_file(state_dir_path("quiet", opts), "%s",
|
||||
opts->flags & REBASE_NO_QUIET ? "" : "t");
|
||||
if (opts->flags & REBASE_VERBOSE)
|
||||
write_file(state_dir_path("verbose", opts), "%s", "");
|
||||
if (opts->strategy)
|
||||
|
|
@ -710,7 +684,7 @@ static int rebase_write_basic_state(struct rebase_options *opts)
|
|||
write_file(state_dir_path("gpg_sign_opt", opts), "%s",
|
||||
opts->gpg_sign_opt);
|
||||
if (opts->signoff)
|
||||
write_file(state_dir_path("signoff", opts), "--signoff");
|
||||
write_file(state_dir_path("strategy", opts), "--signoff");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -774,7 +748,7 @@ static int finish_rebase(struct rebase_options *opts)
|
|||
* user should see them.
|
||||
*/
|
||||
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
|
||||
if (opts->type == REBASE_MERGE) {
|
||||
if (opts->type == REBASE_INTERACTIVE) {
|
||||
struct replay_opts replay = REPLAY_OPTS_INIT;
|
||||
|
||||
replay.action = REPLAY_INTERACTIVE_REBASE;
|
||||
|
|
@ -1037,8 +1011,7 @@ static int run_am(struct rebase_options *opts)
|
|||
argv_array_pushl(&format_patch.args, "format-patch", "-k", "--stdout",
|
||||
"--full-index", "--cherry-pick", "--right-only",
|
||||
"--src-prefix=a/", "--dst-prefix=b/", "--no-renames",
|
||||
"--no-cover-letter", "--pretty=mboxrd", "--topo-order",
|
||||
"--no-base", NULL);
|
||||
"--no-cover-letter", "--pretty=mboxrd", "--topo-order", NULL);
|
||||
if (opts->git_format_patch_opt.len)
|
||||
argv_array_split(&format_patch.args,
|
||||
opts->git_format_patch_opt.buf);
|
||||
|
|
@ -1107,8 +1080,8 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)
|
|||
int status;
|
||||
const char *backend, *backend_func;
|
||||
|
||||
if (opts->type == REBASE_MERGE) {
|
||||
/* Run sequencer-based rebase */
|
||||
if (opts->type == REBASE_INTERACTIVE) {
|
||||
/* Run builtin interactive rebase */
|
||||
setenv("GIT_CHERRY_PICK_HELP", resolvemsg, 1);
|
||||
if (!(opts->flags & REBASE_INTERACTIVE_EXPLICIT)) {
|
||||
setenv("GIT_SEQUENCE_EDITOR", ":", 1);
|
||||
|
|
@ -1121,11 +1094,11 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)
|
|||
opts->gpg_sign_opt = tmp;
|
||||
}
|
||||
|
||||
status = run_sequencer_rebase(opts, action);
|
||||
status = run_rebase_interactive(opts, action);
|
||||
goto finished_rebase;
|
||||
}
|
||||
|
||||
if (opts->type == REBASE_APPLY) {
|
||||
if (opts->type == REBASE_AM) {
|
||||
status = run_am(opts);
|
||||
goto finished_rebase;
|
||||
}
|
||||
|
|
@ -1145,6 +1118,8 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)
|
|||
add_var(&script_snippet, "revisions", opts->revisions);
|
||||
add_var(&script_snippet, "restrict_revision", opts->restrict_revision ?
|
||||
oid_to_hex(&opts->restrict_revision->object.oid) : NULL);
|
||||
add_var(&script_snippet, "GIT_QUIET",
|
||||
opts->flags & REBASE_NO_QUIET ? "" : "t");
|
||||
sq_quote_argv_pretty(&buf, opts->git_am_opts.argv);
|
||||
add_var(&script_snippet, "git_am_opt", buf.buf);
|
||||
strbuf_release(&buf);
|
||||
|
|
@ -1162,6 +1137,7 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)
|
|||
opts->allow_rerere_autoupdate ?
|
||||
opts->allow_rerere_autoupdate == RERERE_AUTOUPDATE ?
|
||||
"--rerere-autoupdate" : "--no-rerere-autoupdate" : "");
|
||||
add_var(&script_snippet, "keep_empty", opts->keep_empty ? "yes" : "");
|
||||
add_var(&script_snippet, "autosquash", opts->autosquash ? "t" : "");
|
||||
add_var(&script_snippet, "gpg_sign_opt", opts->gpg_sign_opt);
|
||||
add_var(&script_snippet, "cmd", opts->cmd);
|
||||
|
|
@ -1179,7 +1155,7 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)
|
|||
add_var(&script_snippet, "git_format_patch_opt",
|
||||
opts->git_format_patch_opt.buf);
|
||||
|
||||
if (is_merge(opts) &&
|
||||
if (is_interactive(opts) &&
|
||||
!(opts->flags & REBASE_INTERACTIVE_EXPLICIT)) {
|
||||
strbuf_addstr(&script_snippet,
|
||||
"GIT_SEQUENCE_EDITOR=:; export GIT_SEQUENCE_EDITOR; ");
|
||||
|
|
@ -1204,8 +1180,8 @@ static int run_specific_rebase(struct rebase_options *opts, enum action action)
|
|||
finished_rebase:
|
||||
if (opts->dont_finish_rebase)
|
||||
; /* do nothing */
|
||||
else if (opts->type == REBASE_MERGE)
|
||||
; /* merge backend cleans up after itself */
|
||||
else if (opts->type == REBASE_INTERACTIVE)
|
||||
; /* interactive rebase cleans up after itself */
|
||||
else if (status == 0) {
|
||||
if (!file_exists(state_dir_path("stopped-sha", opts)))
|
||||
finish_rebase(opts);
|
||||
|
|
@ -1263,10 +1239,6 @@ static int rebase_config(const char *var, const char *value, void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(var, "rebase.backend")) {
|
||||
return git_config_string(&opts->default_backend, var, value);
|
||||
}
|
||||
|
||||
return git_default_config(var, value, data);
|
||||
}
|
||||
|
||||
|
|
@ -1288,60 +1260,28 @@ static int is_linear_history(struct commit *from, struct commit *to)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int can_fast_forward(struct commit *onto, struct commit *upstream,
|
||||
struct commit *restrict_revision,
|
||||
struct object_id *head_oid, struct object_id *merge_base)
|
||||
static int can_fast_forward(struct commit *onto, struct object_id *head_oid,
|
||||
struct object_id *merge_base)
|
||||
{
|
||||
struct commit *head = lookup_commit(the_repository, head_oid);
|
||||
struct commit_list *merge_bases = NULL;
|
||||
int res = 0;
|
||||
struct commit_list *merge_bases;
|
||||
int res;
|
||||
|
||||
if (!head)
|
||||
goto done;
|
||||
return 0;
|
||||
|
||||
merge_bases = get_merge_bases(onto, head);
|
||||
if (!merge_bases || merge_bases->next) {
|
||||
if (merge_bases && !merge_bases->next) {
|
||||
oidcpy(merge_base, &merge_bases->item->object.oid);
|
||||
res = oideq(merge_base, &onto->object.oid);
|
||||
} else {
|
||||
oidcpy(merge_base, &null_oid);
|
||||
goto done;
|
||||
res = 0;
|
||||
}
|
||||
|
||||
oidcpy(merge_base, &merge_bases->item->object.oid);
|
||||
if (!oideq(merge_base, &onto->object.oid))
|
||||
goto done;
|
||||
|
||||
if (restrict_revision && !oideq(&restrict_revision->object.oid, merge_base))
|
||||
goto done;
|
||||
|
||||
if (!upstream)
|
||||
goto done;
|
||||
|
||||
free_commit_list(merge_bases);
|
||||
merge_bases = get_merge_bases(upstream, head);
|
||||
if (!merge_bases || merge_bases->next)
|
||||
goto done;
|
||||
|
||||
if (!oideq(&onto->object.oid, &merge_bases->item->object.oid))
|
||||
goto done;
|
||||
|
||||
res = 1;
|
||||
|
||||
done:
|
||||
free_commit_list(merge_bases);
|
||||
return res && is_linear_history(onto, head);
|
||||
}
|
||||
|
||||
static int parse_opt_am(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
struct rebase_options *opts = opt->value;
|
||||
|
||||
BUG_ON_OPT_NEG(unset);
|
||||
BUG_ON_OPT_ARG(arg);
|
||||
|
||||
opts->type = REBASE_APPLY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -i followed by -m is still -i */
|
||||
static int parse_opt_merge(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
|
|
@ -1350,7 +1290,7 @@ static int parse_opt_merge(const struct option *opt, const char *arg, int unset)
|
|||
BUG_ON_OPT_NEG(unset);
|
||||
BUG_ON_OPT_ARG(arg);
|
||||
|
||||
if (!is_merge(opts))
|
||||
if (!is_interactive(opts))
|
||||
opts->type = REBASE_MERGE;
|
||||
|
||||
return 0;
|
||||
|
|
@ -1365,35 +1305,12 @@ static int parse_opt_interactive(const struct option *opt, const char *arg,
|
|||
BUG_ON_OPT_NEG(unset);
|
||||
BUG_ON_OPT_ARG(arg);
|
||||
|
||||
opts->type = REBASE_MERGE;
|
||||
opts->type = REBASE_INTERACTIVE;
|
||||
opts->flags |= REBASE_INTERACTIVE_EXPLICIT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum empty_type parse_empty_value(const char *value)
|
||||
{
|
||||
if (!strcasecmp(value, "drop"))
|
||||
return EMPTY_DROP;
|
||||
else if (!strcasecmp(value, "keep"))
|
||||
return EMPTY_KEEP;
|
||||
else if (!strcasecmp(value, "ask"))
|
||||
return EMPTY_ASK;
|
||||
|
||||
die(_("unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and \"ask\"."), value);
|
||||
}
|
||||
|
||||
static int parse_opt_empty(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
struct rebase_options *options = opt->value;
|
||||
enum empty_type value = parse_empty_value(arg);
|
||||
|
||||
BUG_ON_OPT_NEG(unset);
|
||||
|
||||
options->empty = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void NORETURN error_on_missing_default_upstream(void)
|
||||
{
|
||||
struct branch *current_branch = branch_get(NULL);
|
||||
|
|
@ -1429,14 +1346,14 @@ static void set_reflog_action(struct rebase_options *options)
|
|||
const char *env;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
if (!is_merge(options))
|
||||
if (!is_interactive(options))
|
||||
return;
|
||||
|
||||
env = getenv(GIT_REFLOG_ACTION_ENVIRONMENT);
|
||||
if (env && strcmp("rebase", env))
|
||||
return; /* only override it if it is "rebase" */
|
||||
|
||||
strbuf_addf(&buf, "rebase (%s)", options->action);
|
||||
strbuf_addf(&buf, "rebase -i (%s)", options->action);
|
||||
setenv(GIT_REFLOG_ACTION_ENVIRONMENT, buf.buf, 1);
|
||||
strbuf_release(&buf);
|
||||
}
|
||||
|
|
@ -1459,7 +1376,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
struct rebase_options options = REBASE_OPTIONS_INIT;
|
||||
const char *branch_name;
|
||||
int ret, flags, total_argc, in_progress = 0;
|
||||
int keep_base = 0;
|
||||
int ok_to_skip_pre_rebase = 0;
|
||||
struct strbuf msg = STRBUF_INIT;
|
||||
struct strbuf revisions = STRBUF_INIT;
|
||||
|
|
@ -1474,18 +1390,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
struct object_id squash_onto;
|
||||
char *squash_onto_name = NULL;
|
||||
int reschedule_failed_exec = -1;
|
||||
int allow_preemptive_ff = 1;
|
||||
struct option builtin_rebase_options[] = {
|
||||
OPT_STRING(0, "onto", &options.onto_name,
|
||||
N_("revision"),
|
||||
N_("rebase onto given branch instead of upstream")),
|
||||
OPT_BOOL(0, "keep-base", &keep_base,
|
||||
N_("use the merge-base of upstream and branch as the current base")),
|
||||
OPT_BOOL(0, "no-verify", &ok_to_skip_pre_rebase,
|
||||
N_("allow pre-rebase hook to run")),
|
||||
OPT_NEGBIT('q', "quiet", &options.flags,
|
||||
N_("be quiet. implies --no-stat"),
|
||||
REBASE_NO_QUIET | REBASE_VERBOSE | REBASE_DIFFSTAT),
|
||||
REBASE_NO_QUIET| REBASE_VERBOSE | REBASE_DIFFSTAT),
|
||||
OPT_BIT('v', "verbose", &options.flags,
|
||||
N_("display a diffstat of what changed upstream"),
|
||||
REBASE_NO_QUIET | REBASE_VERBOSE | REBASE_DIFFSTAT),
|
||||
|
|
@ -1526,10 +1439,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
OPT_CMDMODE(0, "show-current-patch", &action,
|
||||
N_("show the patch file being applied or merged"),
|
||||
ACTION_SHOW_CURRENT_PATCH),
|
||||
{ OPTION_CALLBACK, 0, "apply", &options, NULL,
|
||||
N_("use apply strategies to rebase"),
|
||||
PARSE_OPT_NOARG | PARSE_OPT_NONEG,
|
||||
parse_opt_am },
|
||||
{ OPTION_CALLBACK, 'm', "merge", &options, NULL,
|
||||
N_("use merging strategies to rebase"),
|
||||
PARSE_OPT_NOARG | PARSE_OPT_NONEG,
|
||||
|
|
@ -1538,18 +1447,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
N_("let the user edit the list of commits to rebase"),
|
||||
PARSE_OPT_NOARG | PARSE_OPT_NONEG,
|
||||
parse_opt_interactive },
|
||||
OPT_SET_INT_F('p', "preserve-merges", &options.type,
|
||||
N_("(DEPRECATED) try to recreate merges instead of "
|
||||
"ignoring them"),
|
||||
REBASE_PRESERVE_MERGES, PARSE_OPT_HIDDEN),
|
||||
OPT_SET_INT('p', "preserve-merges", &options.type,
|
||||
N_("(DEPRECATED) try to recreate merges instead of "
|
||||
"ignoring them"), REBASE_PRESERVE_MERGES),
|
||||
OPT_RERERE_AUTOUPDATE(&options.allow_rerere_autoupdate),
|
||||
OPT_CALLBACK_F(0, "empty", &options, "{drop,keep,ask}",
|
||||
N_("how to handle commits that become empty"),
|
||||
PARSE_OPT_NONEG, parse_opt_empty),
|
||||
{ OPTION_CALLBACK, 'k', "keep-empty", &options, NULL,
|
||||
N_("(DEPRECATED) keep empty commits"),
|
||||
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN,
|
||||
parse_opt_keep_empty },
|
||||
OPT_BOOL('k', "keep-empty", &options.keep_empty,
|
||||
N_("preserve empty commits during rebase")),
|
||||
OPT_BOOL(0, "autosquash", &options.autosquash,
|
||||
N_("move commits that begin with "
|
||||
"squash!/fixup! under -i")),
|
||||
|
|
@ -1561,10 +1464,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
OPT_STRING_LIST('x', "exec", &exec, N_("exec"),
|
||||
N_("add exec lines after each commit of the "
|
||||
"editable list")),
|
||||
OPT_BOOL_F(0, "allow-empty-message",
|
||||
&options.allow_empty_message,
|
||||
N_("allow rebasing commits with empty messages"),
|
||||
PARSE_OPT_HIDDEN),
|
||||
OPT_BOOL(0, "allow-empty-message",
|
||||
&options.allow_empty_message,
|
||||
N_("allow rebasing commits with empty messages")),
|
||||
{OPTION_STRING, 'r', "rebase-merges", &rebase_merges,
|
||||
N_("mode"),
|
||||
N_("try to rebase merges instead of skipping them"),
|
||||
|
|
@ -1604,7 +1506,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
die(_("It looks like 'git am' is in progress. Cannot rebase."));
|
||||
|
||||
if (is_directory(apply_dir())) {
|
||||
options.type = REBASE_APPLY;
|
||||
options.type = REBASE_AM;
|
||||
options.state_dir = apply_dir();
|
||||
} else if (is_directory(merge_dir())) {
|
||||
strbuf_reset(&buf);
|
||||
|
|
@ -1616,7 +1518,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
strbuf_reset(&buf);
|
||||
strbuf_addf(&buf, "%s/interactive", merge_dir());
|
||||
if(file_exists(buf.buf)) {
|
||||
options.type = REBASE_MERGE;
|
||||
options.type = REBASE_INTERACTIVE;
|
||||
options.flags |= REBASE_INTERACTIVE_EXPLICIT;
|
||||
} else
|
||||
options.type = REBASE_MERGE;
|
||||
|
|
@ -1645,23 +1547,16 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
warning(_("git rebase --preserve-merges is deprecated. "
|
||||
"Use --rebase-merges instead."));
|
||||
|
||||
if (keep_base) {
|
||||
if (options.onto_name)
|
||||
die(_("cannot combine '--keep-base' with '--onto'"));
|
||||
if (options.root)
|
||||
die(_("cannot combine '--keep-base' with '--root'"));
|
||||
}
|
||||
|
||||
if (action != ACTION_NONE && !in_progress)
|
||||
die(_("No rebase in progress?"));
|
||||
setenv(GIT_REFLOG_ACTION_ENVIRONMENT, "rebase", 0);
|
||||
|
||||
if (action == ACTION_EDIT_TODO && !is_merge(&options))
|
||||
if (action == ACTION_EDIT_TODO && !is_interactive(&options))
|
||||
die(_("The --edit-todo action can only be used during "
|
||||
"interactive rebase."));
|
||||
|
||||
if (trace2_is_enabled()) {
|
||||
if (is_merge(&options))
|
||||
if (is_interactive(&options))
|
||||
trace2_cmd_mode("interactive");
|
||||
else if (exec.nr)
|
||||
trace2_cmd_mode("interactive-exec");
|
||||
|
|
@ -1737,7 +1632,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
goto cleanup;
|
||||
}
|
||||
case ACTION_QUIT: {
|
||||
if (options.type == REBASE_MERGE) {
|
||||
if (options.type == REBASE_INTERACTIVE) {
|
||||
struct replay_opts replay = REPLAY_OPTS_INIT;
|
||||
|
||||
replay.action = REPLAY_INTERACTIVE_REBASE;
|
||||
|
|
@ -1786,20 +1681,13 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
state_dir_base, cmd_live_rebase, buf.buf);
|
||||
}
|
||||
|
||||
if ((options.flags & REBASE_INTERACTIVE_EXPLICIT) ||
|
||||
(action != ACTION_NONE) ||
|
||||
(exec.nr > 0) ||
|
||||
options.autosquash) {
|
||||
allow_preemptive_ff = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < options.git_am_opts.argc; i++) {
|
||||
const char *option = options.git_am_opts.argv[i], *p;
|
||||
if (!strcmp(option, "--committer-date-is-author-date") ||
|
||||
!strcmp(option, "--ignore-date") ||
|
||||
!strcmp(option, "--whitespace=fix") ||
|
||||
!strcmp(option, "--whitespace=strip"))
|
||||
allow_preemptive_ff = 0;
|
||||
options.flags |= REBASE_FORCE;
|
||||
else if (skip_prefix(option, "-C", &p)) {
|
||||
while (*p)
|
||||
if (!isdigit(*(p++)))
|
||||
|
|
@ -1819,8 +1707,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
if (!(options.flags & REBASE_NO_QUIET))
|
||||
argv_array_push(&options.git_am_opts, "-q");
|
||||
|
||||
if (options.empty != EMPTY_UNSPECIFIED)
|
||||
imply_merge(&options, "--empty");
|
||||
if (options.keep_empty)
|
||||
imply_interactive(&options, "--keep-empty");
|
||||
|
||||
if (gpg_sign) {
|
||||
free(options.gpg_sign_opt);
|
||||
|
|
@ -1830,7 +1718,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
if (exec.nr) {
|
||||
int i;
|
||||
|
||||
imply_merge(&options, "--exec");
|
||||
imply_interactive(&options, "--exec");
|
||||
|
||||
strbuf_reset(&buf);
|
||||
for (i = 0; i < exec.nr; i++)
|
||||
|
|
@ -1846,7 +1734,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
else if (strcmp("no-rebase-cousins", rebase_merges))
|
||||
die(_("Unknown mode: %s"), rebase_merges);
|
||||
options.rebase_merges = 1;
|
||||
imply_merge(&options, "--rebase-merges");
|
||||
imply_interactive(&options, "--rebase-merges");
|
||||
}
|
||||
|
||||
if (strategy_options.nr) {
|
||||
|
|
@ -1865,9 +1753,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
if (options.strategy) {
|
||||
options.strategy = xstrdup(options.strategy);
|
||||
switch (options.type) {
|
||||
case REBASE_APPLY:
|
||||
case REBASE_AM:
|
||||
die(_("--strategy requires --merge or --interactive"));
|
||||
case REBASE_MERGE:
|
||||
case REBASE_INTERACTIVE:
|
||||
case REBASE_PRESERVE_MERGES:
|
||||
/* compatible */
|
||||
break;
|
||||
|
|
@ -1880,65 +1769,47 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
|
||||
if (options.type == REBASE_MERGE)
|
||||
imply_merge(&options, "--merge");
|
||||
imply_interactive(&options, "--merge");
|
||||
|
||||
if (options.root && !options.onto_name)
|
||||
imply_merge(&options, "--root without --onto");
|
||||
imply_interactive(&options, "--root without --onto");
|
||||
|
||||
if (isatty(2) && options.flags & REBASE_NO_QUIET)
|
||||
strbuf_addstr(&options.git_format_patch_opt, " --progress");
|
||||
|
||||
if (options.git_am_opts.argc || options.type == REBASE_APPLY) {
|
||||
/* all am options except -q are compatible only with --apply */
|
||||
for (i = options.git_am_opts.argc - 1; i >= 0; i--)
|
||||
if (strcmp(options.git_am_opts.argv[i], "-q"))
|
||||
break;
|
||||
|
||||
if (i >= 0) {
|
||||
if (is_merge(&options))
|
||||
die(_("cannot combine apply options with "
|
||||
"merge options"));
|
||||
else
|
||||
options.type = REBASE_APPLY;
|
||||
}
|
||||
}
|
||||
|
||||
if (options.type == REBASE_UNSPECIFIED) {
|
||||
if (!strcmp(options.default_backend, "merge"))
|
||||
imply_merge(&options, "--merge");
|
||||
else if (!strcmp(options.default_backend, "apply"))
|
||||
options.type = REBASE_APPLY;
|
||||
else
|
||||
die(_("Unknown rebase backend: %s"),
|
||||
options.default_backend);
|
||||
}
|
||||
|
||||
switch (options.type) {
|
||||
case REBASE_MERGE:
|
||||
case REBASE_INTERACTIVE:
|
||||
case REBASE_PRESERVE_MERGES:
|
||||
options.state_dir = merge_dir();
|
||||
break;
|
||||
case REBASE_APPLY:
|
||||
case REBASE_AM:
|
||||
options.state_dir = apply_dir();
|
||||
break;
|
||||
default:
|
||||
BUG("options.type was just set above; should be unreachable.");
|
||||
/* the default rebase backend is `--am` */
|
||||
options.type = REBASE_AM;
|
||||
options.state_dir = apply_dir();
|
||||
break;
|
||||
}
|
||||
|
||||
if (options.empty == EMPTY_UNSPECIFIED) {
|
||||
if (options.flags & REBASE_INTERACTIVE_EXPLICIT)
|
||||
options.empty = EMPTY_ASK;
|
||||
else if (exec.nr > 0)
|
||||
options.empty = EMPTY_KEEP;
|
||||
else
|
||||
options.empty = EMPTY_DROP;
|
||||
}
|
||||
if (reschedule_failed_exec > 0 && !is_merge(&options))
|
||||
if (reschedule_failed_exec > 0 && !is_interactive(&options))
|
||||
die(_("--reschedule-failed-exec requires "
|
||||
"--exec or --interactive"));
|
||||
if (reschedule_failed_exec >= 0)
|
||||
options.reschedule_failed_exec = reschedule_failed_exec;
|
||||
|
||||
if (options.git_am_opts.argc) {
|
||||
/* all am options except -q are compatible only with --am */
|
||||
for (i = options.git_am_opts.argc - 1; i >= 0; i--)
|
||||
if (strcmp(options.git_am_opts.argv[i], "-q"))
|
||||
break;
|
||||
|
||||
if (is_interactive(&options) && i >= 0)
|
||||
die(_("cannot combine am options with either "
|
||||
"interactive or merge options"));
|
||||
}
|
||||
|
||||
if (options.signoff) {
|
||||
if (options.type == REBASE_PRESERVE_MERGES)
|
||||
die("cannot combine '--signoff' with "
|
||||
|
|
@ -1962,6 +1833,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
"'--reschedule-failed-exec'"));
|
||||
}
|
||||
|
||||
if (options.rebase_merges) {
|
||||
if (strategy_options.nr)
|
||||
die(_("cannot combine '--rebase-merges' with "
|
||||
"'--strategy-option'"));
|
||||
if (options.strategy)
|
||||
die(_("cannot combine '--rebase-merges' with "
|
||||
"'--strategy'"));
|
||||
}
|
||||
|
||||
if (!options.root) {
|
||||
if (argc < 1) {
|
||||
struct branch *branch;
|
||||
|
|
@ -1992,9 +1872,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
options.squash_onto = &squash_onto;
|
||||
options.onto_name = squash_onto_name =
|
||||
xstrdup(oid_to_hex(&squash_onto));
|
||||
} else
|
||||
options.root_with_onto = 1;
|
||||
|
||||
}
|
||||
options.upstream_name = NULL;
|
||||
options.upstream = NULL;
|
||||
if (argc > 1)
|
||||
|
|
@ -2004,22 +1882,12 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
|
||||
/* Make sure the branch to rebase onto is valid. */
|
||||
if (keep_base) {
|
||||
strbuf_reset(&buf);
|
||||
strbuf_addstr(&buf, options.upstream_name);
|
||||
strbuf_addstr(&buf, "...");
|
||||
options.onto_name = xstrdup(buf.buf);
|
||||
} else if (!options.onto_name)
|
||||
if (!options.onto_name)
|
||||
options.onto_name = options.upstream_name;
|
||||
if (strstr(options.onto_name, "...")) {
|
||||
if (get_oid_mb(options.onto_name, &merge_base) < 0) {
|
||||
if (keep_base)
|
||||
die(_("'%s': need exactly one merge base with branch"),
|
||||
options.upstream_name);
|
||||
else
|
||||
die(_("'%s': need exactly one merge base"),
|
||||
options.onto_name);
|
||||
}
|
||||
if (get_oid_mb(options.onto_name, &merge_base) < 0)
|
||||
die(_("'%s': need exactly one merge base"),
|
||||
options.onto_name);
|
||||
options.onto = lookup_commit_or_die(&merge_base,
|
||||
options.onto_name);
|
||||
} else {
|
||||
|
|
@ -2044,11 +1912,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
/* Is it a local branch? */
|
||||
strbuf_reset(&buf);
|
||||
strbuf_addf(&buf, "refs/heads/%s", branch_name);
|
||||
if (!read_ref(buf.buf, &options.orig_head)) {
|
||||
die_if_checked_out(buf.buf, 1);
|
||||
if (!read_ref(buf.buf, &options.orig_head))
|
||||
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))
|
||||
options.head_name = NULL;
|
||||
else
|
||||
die(_("fatal: no such branch/commit '%s'"),
|
||||
|
|
@ -2101,6 +1968,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
state_dir_path("autostash", &options);
|
||||
struct child_process stash = CHILD_PROCESS_INIT;
|
||||
struct object_id oid;
|
||||
struct commit *head =
|
||||
lookup_commit_reference(the_repository,
|
||||
&options.orig_head);
|
||||
|
||||
argv_array_pushl(&stash.args,
|
||||
"stash", "create", "autostash", NULL);
|
||||
|
|
@ -2121,9 +1991,17 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
options.state_dir);
|
||||
write_file(autostash, "%s", oid_to_hex(&oid));
|
||||
printf(_("Created autostash: %s\n"), buf.buf);
|
||||
if (reset_head(NULL, "reset --hard",
|
||||
if (reset_head(&head->object.oid, "reset --hard",
|
||||
NULL, RESET_HEAD_HARD, NULL, NULL) < 0)
|
||||
die(_("could not reset --hard"));
|
||||
printf(_("HEAD is now at %s"),
|
||||
find_unique_abbrev(&head->object.oid,
|
||||
DEFAULT_ABBREV));
|
||||
strbuf_reset(&buf);
|
||||
pp_commit_easy(CMIT_FMT_ONELINE, head, &buf);
|
||||
if (buf.len > 0)
|
||||
printf(" %s", buf.buf);
|
||||
putchar('\n');
|
||||
|
||||
if (discard_index(the_repository->index) < 0 ||
|
||||
repo_read_index(the_repository) < 0)
|
||||
|
|
@ -2144,25 +2022,31 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
|
||||
/*
|
||||
* Check if we are already based on onto with linear history,
|
||||
* in which case we could fast-forward without replacing the commits
|
||||
* with new commits recreated by replaying their changes.
|
||||
*
|
||||
* Note that can_fast_forward() initializes merge_base, so we have to
|
||||
* call it before checking allow_preemptive_ff.
|
||||
* but this should be done only when upstream and onto are the same
|
||||
* and if this is not an interactive rebase.
|
||||
*/
|
||||
if (can_fast_forward(options.onto, options.upstream, options.restrict_revision,
|
||||
&options.orig_head, &merge_base) &&
|
||||
allow_preemptive_ff) {
|
||||
if (can_fast_forward(options.onto, &options.orig_head, &merge_base) &&
|
||||
!is_interactive(&options) && !options.restrict_revision &&
|
||||
options.upstream &&
|
||||
!oidcmp(&options.upstream->object.oid, &options.onto->object.oid)) {
|
||||
int flag;
|
||||
|
||||
if (!(options.flags & REBASE_FORCE)) {
|
||||
/* Lazily switch to the target branch if needed... */
|
||||
if (options.switch_to) {
|
||||
struct object_id oid;
|
||||
|
||||
if (get_oid(options.switch_to, &oid) < 0) {
|
||||
ret = !!error(_("could not parse '%s'"),
|
||||
options.switch_to);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
strbuf_reset(&buf);
|
||||
strbuf_addf(&buf, "%s: checkout %s",
|
||||
getenv(GIT_REFLOG_ACTION_ENVIRONMENT),
|
||||
options.switch_to);
|
||||
if (reset_head(&options.orig_head, "checkout",
|
||||
if (reset_head(&oid, "checkout",
|
||||
options.head_name,
|
||||
RESET_HEAD_RUN_POST_CHECKOUT_HOOK,
|
||||
NULL, buf.buf) < 0) {
|
||||
|
|
@ -2227,7 +2111,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
|
|||
diff_flush(&opts);
|
||||
}
|
||||
|
||||
if (is_merge(&options))
|
||||
if (is_interactive(&options))
|
||||
goto run_rebase;
|
||||
|
||||
/* Detach HEAD and reset the tree */
|
||||
|
|
|
|||
86
third_party/git/builtin/receive-pack.c
vendored
86
third_party/git/builtin/receive-pack.c
vendored
|
|
@ -27,7 +27,6 @@
|
|||
#include "object-store.h"
|
||||
#include "protocol.h"
|
||||
#include "commit-reach.h"
|
||||
#include "worktree.h"
|
||||
|
||||
static const char * const receive_pack_usage[] = {
|
||||
N_("git receive-pack <git-dir>"),
|
||||
|
|
@ -418,22 +417,24 @@ static int copy_to_sideband(int in, int out, void *arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void hmac(unsigned char *out,
|
||||
#define HMAC_BLOCK_SIZE 64
|
||||
|
||||
static void hmac_sha1(unsigned char *out,
|
||||
const char *key_in, size_t key_len,
|
||||
const char *text, size_t text_len)
|
||||
{
|
||||
unsigned char key[GIT_MAX_BLKSZ];
|
||||
unsigned char k_ipad[GIT_MAX_BLKSZ];
|
||||
unsigned char k_opad[GIT_MAX_BLKSZ];
|
||||
unsigned char key[HMAC_BLOCK_SIZE];
|
||||
unsigned char k_ipad[HMAC_BLOCK_SIZE];
|
||||
unsigned char k_opad[HMAC_BLOCK_SIZE];
|
||||
int i;
|
||||
git_hash_ctx ctx;
|
||||
git_SHA_CTX ctx;
|
||||
|
||||
/* RFC 2104 2. (1) */
|
||||
memset(key, '\0', GIT_MAX_BLKSZ);
|
||||
if (the_hash_algo->blksz < key_len) {
|
||||
the_hash_algo->init_fn(&ctx);
|
||||
the_hash_algo->update_fn(&ctx, key_in, key_len);
|
||||
the_hash_algo->final_fn(key, &ctx);
|
||||
memset(key, '\0', HMAC_BLOCK_SIZE);
|
||||
if (HMAC_BLOCK_SIZE < key_len) {
|
||||
git_SHA1_Init(&ctx);
|
||||
git_SHA1_Update(&ctx, key_in, key_len);
|
||||
git_SHA1_Final(key, &ctx);
|
||||
} else {
|
||||
memcpy(key, key_in, key_len);
|
||||
}
|
||||
|
|
@ -445,29 +446,29 @@ static void hmac(unsigned char *out,
|
|||
}
|
||||
|
||||
/* RFC 2104 2. (3) & (4) */
|
||||
the_hash_algo->init_fn(&ctx);
|
||||
the_hash_algo->update_fn(&ctx, k_ipad, sizeof(k_ipad));
|
||||
the_hash_algo->update_fn(&ctx, text, text_len);
|
||||
the_hash_algo->final_fn(out, &ctx);
|
||||
git_SHA1_Init(&ctx);
|
||||
git_SHA1_Update(&ctx, k_ipad, sizeof(k_ipad));
|
||||
git_SHA1_Update(&ctx, text, text_len);
|
||||
git_SHA1_Final(out, &ctx);
|
||||
|
||||
/* RFC 2104 2. (6) & (7) */
|
||||
the_hash_algo->init_fn(&ctx);
|
||||
the_hash_algo->update_fn(&ctx, k_opad, sizeof(k_opad));
|
||||
the_hash_algo->update_fn(&ctx, out, the_hash_algo->rawsz);
|
||||
the_hash_algo->final_fn(out, &ctx);
|
||||
git_SHA1_Init(&ctx);
|
||||
git_SHA1_Update(&ctx, k_opad, sizeof(k_opad));
|
||||
git_SHA1_Update(&ctx, out, GIT_SHA1_RAWSZ);
|
||||
git_SHA1_Final(out, &ctx);
|
||||
}
|
||||
|
||||
static char *prepare_push_cert_nonce(const char *path, timestamp_t stamp)
|
||||
{
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
unsigned char hash[GIT_MAX_RAWSZ];
|
||||
unsigned char sha1[GIT_SHA1_RAWSZ];
|
||||
|
||||
strbuf_addf(&buf, "%s:%"PRItime, path, stamp);
|
||||
hmac(hash, buf.buf, buf.len, cert_nonce_seed, strlen(cert_nonce_seed));
|
||||
hmac_sha1(sha1, buf.buf, buf.len, cert_nonce_seed, strlen(cert_nonce_seed));
|
||||
strbuf_release(&buf);
|
||||
|
||||
/* RFC 2104 5. HMAC-SHA1-80 */
|
||||
strbuf_addf(&buf, "%"PRItime"-%.*s", stamp, (int)the_hash_algo->hexsz, hash_to_hex(hash));
|
||||
strbuf_addf(&buf, "%"PRItime"-%.*s", stamp, GIT_SHA1_HEXSZ, sha1_to_hex(sha1));
|
||||
return strbuf_detach(&buf, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -817,6 +818,16 @@ static int run_update_hook(struct command *cmd)
|
|||
return finish_command(&proc);
|
||||
}
|
||||
|
||||
static int is_ref_checked_out(const char *ref)
|
||||
{
|
||||
if (is_bare_repository())
|
||||
return 0;
|
||||
|
||||
if (!head_name)
|
||||
return 0;
|
||||
return !strcmp(head_name, ref);
|
||||
}
|
||||
|
||||
static char *refuse_unconfigured_deny_msg =
|
||||
N_("By default, updating the current branch in a non-bare repository\n"
|
||||
"is denied, because it will make the index and work tree inconsistent\n"
|
||||
|
|
@ -959,7 +970,7 @@ static const char *push_to_deploy(unsigned char *sha1,
|
|||
if (run_command(&child))
|
||||
return "Working directory has staged changes";
|
||||
|
||||
read_tree[3] = hash_to_hex(sha1);
|
||||
read_tree[3] = sha1_to_hex(sha1);
|
||||
child_process_init(&child);
|
||||
child.argv = read_tree;
|
||||
child.env = env->argv;
|
||||
|
|
@ -976,38 +987,28 @@ static const char *push_to_deploy(unsigned char *sha1,
|
|||
|
||||
static const char *push_to_checkout_hook = "push-to-checkout";
|
||||
|
||||
static const char *push_to_checkout(unsigned char *hash,
|
||||
static const char *push_to_checkout(unsigned char *sha1,
|
||||
struct argv_array *env,
|
||||
const char *work_tree)
|
||||
{
|
||||
argv_array_pushf(env, "GIT_WORK_TREE=%s", absolute_path(work_tree));
|
||||
if (run_hook_le(env->argv, push_to_checkout_hook,
|
||||
hash_to_hex(hash), NULL))
|
||||
sha1_to_hex(sha1), NULL))
|
||||
return "push-to-checkout hook declined";
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *update_worktree(unsigned char *sha1, const struct worktree *worktree)
|
||||
static const char *update_worktree(unsigned char *sha1)
|
||||
{
|
||||
const char *retval, *work_tree, *git_dir = NULL;
|
||||
const char *retval;
|
||||
const char *work_tree = git_work_tree_cfg ? git_work_tree_cfg : "..";
|
||||
struct argv_array env = ARGV_ARRAY_INIT;
|
||||
|
||||
if (worktree && worktree->path)
|
||||
work_tree = worktree->path;
|
||||
else if (git_work_tree_cfg)
|
||||
work_tree = git_work_tree_cfg;
|
||||
else
|
||||
work_tree = "..";
|
||||
|
||||
if (is_bare_repository())
|
||||
return "denyCurrentBranch = updateInstead needs a worktree";
|
||||
if (worktree)
|
||||
git_dir = get_worktree_git_dir(worktree);
|
||||
if (!git_dir)
|
||||
git_dir = get_git_dir();
|
||||
|
||||
argv_array_pushf(&env, "GIT_DIR=%s", absolute_path(git_dir));
|
||||
argv_array_pushf(&env, "GIT_DIR=%s", absolute_path(get_git_dir()));
|
||||
|
||||
if (!find_hook(push_to_checkout_hook))
|
||||
retval = push_to_deploy(sha1, &env, work_tree);
|
||||
|
|
@ -1027,7 +1028,6 @@ static const char *update(struct command *cmd, struct shallow_info *si)
|
|||
struct object_id *old_oid = &cmd->old_oid;
|
||||
struct object_id *new_oid = &cmd->new_oid;
|
||||
int do_update_worktree = 0;
|
||||
const struct worktree *worktree = is_bare_repository() ? NULL : find_shared_symref("HEAD", name);
|
||||
|
||||
/* only refs/... are allowed */
|
||||
if (!starts_with(name, "refs/") || check_refname_format(name + 5, 0)) {
|
||||
|
|
@ -1039,7 +1039,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
|
|||
free(namespaced_name);
|
||||
namespaced_name = strbuf_detach(&namespaced_name_buf, NULL);
|
||||
|
||||
if (worktree) {
|
||||
if (is_ref_checked_out(namespaced_name)) {
|
||||
switch (deny_current_branch) {
|
||||
case DENY_IGNORE:
|
||||
break;
|
||||
|
|
@ -1071,7 +1071,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
|
|||
return "deletion prohibited";
|
||||
}
|
||||
|
||||
if (worktree || (head_name && !strcmp(namespaced_name, head_name))) {
|
||||
if (head_name && !strcmp(namespaced_name, head_name)) {
|
||||
switch (deny_delete_current) {
|
||||
case DENY_IGNORE:
|
||||
break;
|
||||
|
|
@ -1120,7 +1120,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)
|
|||
}
|
||||
|
||||
if (do_update_worktree) {
|
||||
ret = update_worktree(new_oid->hash, find_shared_symref("HEAD", name));
|
||||
ret = update_worktree(new_oid->hash);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
9
third_party/git/builtin/reflog.c
vendored
9
third_party/git/builtin/reflog.c
vendored
|
|
@ -560,16 +560,15 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
|||
|
||||
for (i = 1; i < argc; i++) {
|
||||
const char *arg = argv[i];
|
||||
|
||||
if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n"))
|
||||
flags |= EXPIRE_REFLOGS_DRY_RUN;
|
||||
else if (skip_prefix(arg, "--expire=", &arg)) {
|
||||
if (parse_expiry_date(arg, &cb.cmd.expire_total))
|
||||
else if (starts_with(arg, "--expire=")) {
|
||||
if (parse_expiry_date(arg + 9, &cb.cmd.expire_total))
|
||||
die(_("'%s' is not a valid timestamp"), arg);
|
||||
explicit_expiry |= EXPIRE_TOTAL;
|
||||
}
|
||||
else if (skip_prefix(arg, "--expire-unreachable=", &arg)) {
|
||||
if (parse_expiry_date(arg, &cb.cmd.expire_unreachable))
|
||||
else if (starts_with(arg, "--expire-unreachable=")) {
|
||||
if (parse_expiry_date(arg + 21, &cb.cmd.expire_unreachable))
|
||||
die(_("'%s' is not a valid timestamp"), arg);
|
||||
explicit_expiry |= EXPIRE_UNREACH;
|
||||
}
|
||||
|
|
|
|||
190
third_party/git/builtin/remote.c
vendored
190
third_party/git/builtin/remote.c
vendored
|
|
@ -6,7 +6,6 @@
|
|||
#include "string-list.h"
|
||||
#include "strbuf.h"
|
||||
#include "run-command.h"
|
||||
#include "rebase.h"
|
||||
#include "refs.h"
|
||||
#include "refspec.h"
|
||||
#include "object-store.h"
|
||||
|
|
@ -249,8 +248,9 @@ static int add(int argc, const char **argv)
|
|||
struct branch_info {
|
||||
char *remote_name;
|
||||
struct string_list merge;
|
||||
enum rebase_type rebase;
|
||||
char *push_remote_name;
|
||||
enum {
|
||||
NO_REBASE, NORMAL_REBASE, INTERACTIVE_REBASE, REBASE_MERGES
|
||||
} rebase;
|
||||
};
|
||||
|
||||
static struct string_list branch_list = STRING_LIST_INIT_NODUP;
|
||||
|
|
@ -264,69 +264,59 @@ static const char *abbrev_ref(const char *name, const char *prefix)
|
|||
|
||||
static int config_read_branches(const char *key, const char *value, void *cb)
|
||||
{
|
||||
const char *orig_key = key;
|
||||
char *name;
|
||||
struct string_list_item *item;
|
||||
struct branch_info *info;
|
||||
enum { REMOTE, MERGE, REBASE, PUSH_REMOTE } type;
|
||||
size_t key_len;
|
||||
if (starts_with(key, "branch.")) {
|
||||
const char *orig_key = key;
|
||||
char *name;
|
||||
struct string_list_item *item;
|
||||
struct branch_info *info;
|
||||
enum { REMOTE, MERGE, REBASE } type;
|
||||
size_t key_len;
|
||||
|
||||
if (!starts_with(key, "branch."))
|
||||
return 0;
|
||||
key += 7;
|
||||
if (strip_suffix(key, ".remote", &key_len)) {
|
||||
name = xmemdupz(key, key_len);
|
||||
type = REMOTE;
|
||||
} else if (strip_suffix(key, ".merge", &key_len)) {
|
||||
name = xmemdupz(key, key_len);
|
||||
type = MERGE;
|
||||
} else if (strip_suffix(key, ".rebase", &key_len)) {
|
||||
name = xmemdupz(key, key_len);
|
||||
type = REBASE;
|
||||
} else
|
||||
return 0;
|
||||
|
||||
key += strlen("branch.");
|
||||
if (strip_suffix(key, ".remote", &key_len))
|
||||
type = REMOTE;
|
||||
else if (strip_suffix(key, ".merge", &key_len))
|
||||
type = MERGE;
|
||||
else if (strip_suffix(key, ".rebase", &key_len))
|
||||
type = REBASE;
|
||||
else if (strip_suffix(key, ".pushremote", &key_len))
|
||||
type = PUSH_REMOTE;
|
||||
else
|
||||
return 0;
|
||||
name = xmemdupz(key, key_len);
|
||||
item = string_list_insert(&branch_list, name);
|
||||
|
||||
item = string_list_insert(&branch_list, name);
|
||||
|
||||
if (!item->util)
|
||||
item->util = xcalloc(1, sizeof(struct branch_info));
|
||||
info = item->util;
|
||||
switch (type) {
|
||||
case REMOTE:
|
||||
if (info->remote_name)
|
||||
warning(_("more than one %s"), orig_key);
|
||||
info->remote_name = xstrdup(value);
|
||||
break;
|
||||
case MERGE: {
|
||||
char *space = strchr(value, ' ');
|
||||
value = abbrev_branch(value);
|
||||
while (space) {
|
||||
char *merge;
|
||||
merge = xstrndup(value, space - value);
|
||||
string_list_append(&info->merge, merge);
|
||||
value = abbrev_branch(space + 1);
|
||||
space = strchr(value, ' ');
|
||||
if (!item->util)
|
||||
item->util = xcalloc(1, sizeof(struct branch_info));
|
||||
info = item->util;
|
||||
if (type == REMOTE) {
|
||||
if (info->remote_name)
|
||||
warning(_("more than one %s"), orig_key);
|
||||
info->remote_name = xstrdup(value);
|
||||
} else if (type == MERGE) {
|
||||
char *space = strchr(value, ' ');
|
||||
value = abbrev_branch(value);
|
||||
while (space) {
|
||||
char *merge;
|
||||
merge = xstrndup(value, space - value);
|
||||
string_list_append(&info->merge, merge);
|
||||
value = abbrev_branch(space + 1);
|
||||
space = strchr(value, ' ');
|
||||
}
|
||||
string_list_append(&info->merge, xstrdup(value));
|
||||
} else {
|
||||
int v = git_parse_maybe_bool(value);
|
||||
if (v >= 0)
|
||||
info->rebase = v;
|
||||
else if (!strcmp(value, "preserve"))
|
||||
info->rebase = NORMAL_REBASE;
|
||||
else if (!strcmp(value, "merges"))
|
||||
info->rebase = REBASE_MERGES;
|
||||
else if (!strcmp(value, "interactive"))
|
||||
info->rebase = INTERACTIVE_REBASE;
|
||||
}
|
||||
string_list_append(&info->merge, xstrdup(value));
|
||||
break;
|
||||
}
|
||||
case REBASE:
|
||||
/*
|
||||
* Consider invalid values as false and check the
|
||||
* truth value with >= REBASE_TRUE.
|
||||
*/
|
||||
info->rebase = rebase_parse_value(value);
|
||||
break;
|
||||
case PUSH_REMOTE:
|
||||
if (info->push_remote_name)
|
||||
warning(_("more than one %s"), orig_key);
|
||||
info->push_remote_name = xstrdup(value);
|
||||
break;
|
||||
default:
|
||||
BUG("unexpected type=%d", type);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -615,56 +605,6 @@ static int migrate_file(struct remote *remote)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct push_default_info
|
||||
{
|
||||
const char *old_name;
|
||||
enum config_scope scope;
|
||||
struct strbuf origin;
|
||||
int linenr;
|
||||
};
|
||||
|
||||
static int config_read_push_default(const char *key, const char *value,
|
||||
void *cb)
|
||||
{
|
||||
struct push_default_info* info = cb;
|
||||
if (strcmp(key, "remote.pushdefault") ||
|
||||
!value || strcmp(value, info->old_name))
|
||||
return 0;
|
||||
|
||||
info->scope = current_config_scope();
|
||||
strbuf_reset(&info->origin);
|
||||
strbuf_addstr(&info->origin, current_config_name());
|
||||
info->linenr = current_config_line();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void handle_push_default(const char* old_name, const char* new_name)
|
||||
{
|
||||
struct push_default_info push_default = {
|
||||
old_name, CONFIG_SCOPE_UNKNOWN, STRBUF_INIT, -1 };
|
||||
git_config(config_read_push_default, &push_default);
|
||||
if (push_default.scope >= CONFIG_SCOPE_COMMAND)
|
||||
; /* pass */
|
||||
else if (push_default.scope >= CONFIG_SCOPE_LOCAL) {
|
||||
int result = git_config_set_gently("remote.pushDefault",
|
||||
new_name);
|
||||
if (new_name && result && result != CONFIG_NOTHING_SET)
|
||||
die(_("could not set '%s'"), "remote.pushDefault");
|
||||
else if (!new_name && result && result != CONFIG_NOTHING_SET)
|
||||
die(_("could not unset '%s'"), "remote.pushDefault");
|
||||
} else if (push_default.scope >= CONFIG_SCOPE_SYSTEM) {
|
||||
/* warn */
|
||||
warning(_("The %s configuration remote.pushDefault in:\n"
|
||||
"\t%s:%d\n"
|
||||
"now names the non-existent remote '%s'"),
|
||||
config_scope_name(push_default.scope),
|
||||
push_default.origin.buf, push_default.linenr,
|
||||
old_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int mv(int argc, const char **argv)
|
||||
{
|
||||
struct option options[] = {
|
||||
|
|
@ -740,11 +680,6 @@ static int mv(int argc, const char **argv)
|
|||
strbuf_addf(&buf, "branch.%s.remote", item->string);
|
||||
git_config_set(buf.buf, rename.new_name);
|
||||
}
|
||||
if (info->push_remote_name && !strcmp(info->push_remote_name, rename.old_name)) {
|
||||
strbuf_reset(&buf);
|
||||
strbuf_addf(&buf, "branch.%s.pushremote", item->string);
|
||||
git_config_set(buf.buf, rename.new_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!refspec_updated)
|
||||
|
|
@ -758,8 +693,9 @@ static int mv(int argc, const char **argv)
|
|||
for (i = 0; i < remote_branches.nr; i++) {
|
||||
struct string_list_item *item = remote_branches.items + i;
|
||||
int flag = 0;
|
||||
struct object_id oid;
|
||||
|
||||
read_ref_full(item->string, RESOLVE_REF_READING, NULL, &flag);
|
||||
read_ref_full(item->string, RESOLVE_REF_READING, &oid, &flag);
|
||||
if (!(flag & REF_ISSYMREF))
|
||||
continue;
|
||||
if (delete_ref(NULL, item->string, NULL, REF_NO_DEREF))
|
||||
|
|
@ -800,9 +736,6 @@ static int mv(int argc, const char **argv)
|
|||
die(_("creating '%s' failed"), buf.buf);
|
||||
}
|
||||
string_list_clear(&remote_branches, 1);
|
||||
|
||||
handle_push_default(rename.old_name, rename.new_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -849,13 +782,6 @@ static int rm(int argc, const char **argv)
|
|||
die(_("could not unset '%s'"), buf.buf);
|
||||
}
|
||||
}
|
||||
if (info->push_remote_name && !strcmp(info->push_remote_name, remote->name)) {
|
||||
strbuf_reset(&buf);
|
||||
strbuf_addf(&buf, "branch.%s.pushremote", item->string);
|
||||
result = git_config_set_gently(buf.buf, NULL);
|
||||
if (result && result != CONFIG_NOTHING_SET)
|
||||
die(_("could not unset '%s'"), buf.buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -888,8 +814,6 @@ static int rm(int argc, const char **argv)
|
|||
strbuf_addf(&buf, "remote.%s", remote->name);
|
||||
if (git_config_rename_section(buf.buf, NULL) < 1)
|
||||
return error(_("Could not remove config section '%s'"), buf.buf);
|
||||
|
||||
handle_push_default(remote->name, NULL);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -1020,7 +944,7 @@ static int add_local_to_show_info(struct string_list_item *branch_item, void *cb
|
|||
return 0;
|
||||
if ((n = strlen(branch_item->string)) > show_info->width)
|
||||
show_info->width = n;
|
||||
if (branch_info->rebase >= REBASE_TRUE)
|
||||
if (branch_info->rebase)
|
||||
show_info->any_rebase = 1;
|
||||
|
||||
item = string_list_insert(show_info->list, branch_item->string);
|
||||
|
|
@ -1037,16 +961,16 @@ static int show_local_info_item(struct string_list_item *item, void *cb_data)
|
|||
int width = show_info->width + 4;
|
||||
int i;
|
||||
|
||||
if (branch_info->rebase >= REBASE_TRUE && branch_info->merge.nr > 1) {
|
||||
if (branch_info->rebase && branch_info->merge.nr > 1) {
|
||||
error(_("invalid branch.%s.merge; cannot rebase onto > 1 branch"),
|
||||
item->string);
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf(" %-*s ", show_info->width, item->string);
|
||||
if (branch_info->rebase >= REBASE_TRUE) {
|
||||
if (branch_info->rebase) {
|
||||
const char *msg;
|
||||
if (branch_info->rebase == REBASE_INTERACTIVE)
|
||||
if (branch_info->rebase == INTERACTIVE_REBASE)
|
||||
msg = _("rebases interactively onto remote %s");
|
||||
else if (branch_info->rebase == REBASE_MERGES)
|
||||
msg = _("rebases interactively (with merges) onto "
|
||||
|
|
|
|||
14
third_party/git/builtin/repack.c
vendored
14
third_party/git/builtin/repack.c
vendored
|
|
@ -11,7 +11,6 @@
|
|||
#include "midx.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
#include "promisor-remote.h"
|
||||
|
||||
static int delta_base_offset = 1;
|
||||
static int pack_kept_objects = -1;
|
||||
|
|
@ -191,7 +190,7 @@ static int write_oid(const struct object_id *oid, struct packed_git *pack,
|
|||
die(_("could not start pack-objects to repack promisor objects"));
|
||||
}
|
||||
|
||||
xwrite(cmd->in, oid_to_hex(oid), the_hash_algo->hexsz);
|
||||
xwrite(cmd->in, oid_to_hex(oid), GIT_SHA1_HEXSZ);
|
||||
xwrite(cmd->in, "\n", 1);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -233,13 +232,6 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
|
|||
/*
|
||||
* pack-objects creates the .pack and .idx files, but not the
|
||||
* .promisor file. Create the .promisor file, which is empty.
|
||||
*
|
||||
* NEEDSWORK: fetch-pack sometimes generates non-empty
|
||||
* .promisor files containing the ref names and associated
|
||||
* hashes at the point of generation of the corresponding
|
||||
* packfile, but this would not preserve their contents. Maybe
|
||||
* concatenate the contents of all .promisor files instead of
|
||||
* just creating a new empty file.
|
||||
*/
|
||||
promisor_name = mkpathdup("%s-%s.promisor", packtmp,
|
||||
line.buf);
|
||||
|
|
@ -369,7 +361,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
|
|||
argv_array_push(&cmd.args, "--all");
|
||||
argv_array_push(&cmd.args, "--reflog");
|
||||
argv_array_push(&cmd.args, "--indexed-objects");
|
||||
if (has_promisor_remote())
|
||||
if (repository_format_partial_clone)
|
||||
argv_array_push(&cmd.args, "--exclude-promisor-objects");
|
||||
if (write_bitmaps > 0)
|
||||
argv_array_push(&cmd.args, "--write-bitmap-index");
|
||||
|
|
@ -569,7 +561,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
|
|||
remove_temporary_files();
|
||||
|
||||
if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX, 0))
|
||||
write_midx_file(get_object_directory(), 0);
|
||||
write_midx_file(get_object_directory());
|
||||
|
||||
string_list_clear(&names, 0);
|
||||
string_list_clear(&rollback, 0);
|
||||
|
|
|
|||
12
third_party/git/builtin/replace.c
vendored
12
third_party/git/builtin/replace.c
vendored
|
|
@ -272,7 +272,7 @@ static int import_object(struct object_id *oid, enum object_type type,
|
|||
return error(_("unable to spawn mktree"));
|
||||
}
|
||||
|
||||
if (strbuf_read(&result, cmd.out, the_hash_algo->hexsz + 1) < 0) {
|
||||
if (strbuf_read(&result, cmd.out, 41) < 0) {
|
||||
error_errno(_("unable to read from mktree"));
|
||||
close(fd);
|
||||
close(cmd.out);
|
||||
|
|
@ -358,15 +358,14 @@ static int replace_parents(struct strbuf *buf, int argc, const char **argv)
|
|||
struct strbuf new_parents = STRBUF_INIT;
|
||||
const char *parent_start, *parent_end;
|
||||
int i;
|
||||
const unsigned hexsz = the_hash_algo->hexsz;
|
||||
|
||||
/* find existing parents */
|
||||
parent_start = buf->buf;
|
||||
parent_start += hexsz + 6; /* "tree " + "hex sha1" + "\n" */
|
||||
parent_start += GIT_SHA1_HEXSZ + 6; /* "tree " + "hex sha1" + "\n" */
|
||||
parent_end = parent_start;
|
||||
|
||||
while (starts_with(parent_end, "parent "))
|
||||
parent_end += hexsz + 8; /* "parent " + "hex sha1" + "\n" */
|
||||
parent_end += 48; /* "parent " + "hex sha1" + "\n" */
|
||||
|
||||
/* prepare new parents */
|
||||
for (i = 0; i < argc; i++) {
|
||||
|
|
@ -409,8 +408,7 @@ static int check_one_mergetag(struct commit *commit,
|
|||
struct tag *tag;
|
||||
int i;
|
||||
|
||||
hash_object_file(the_hash_algo, extra->value, extra->len,
|
||||
type_name(OBJ_TAG), &tag_oid);
|
||||
hash_object_file(extra->value, extra->len, type_name(OBJ_TAG), &tag_oid);
|
||||
tag = lookup_tag(the_repository, &tag_oid);
|
||||
if (!tag)
|
||||
return error(_("bad mergetag in commit '%s'"), ref);
|
||||
|
|
@ -423,7 +421,7 @@ static int check_one_mergetag(struct commit *commit,
|
|||
if (get_oid(mergetag_data->argv[i], &oid) < 0)
|
||||
return error(_("not a valid object name: '%s'"),
|
||||
mergetag_data->argv[i]);
|
||||
if (oideq(get_tagged_oid(tag), &oid))
|
||||
if (oideq(&tag->tagged->oid, &oid))
|
||||
return 0; /* found */
|
||||
}
|
||||
|
||||
|
|
|
|||
27
third_party/git/builtin/reset.c
vendored
27
third_party/git/builtin/reset.c
vendored
|
|
@ -30,9 +30,8 @@
|
|||
|
||||
static const char * const git_reset_usage[] = {
|
||||
N_("git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"),
|
||||
N_("git reset [-q] [<tree-ish>] [--] <pathspec>..."),
|
||||
N_("git reset [-q] [--pathspec-from-file [--pathspec-file-nul]] [<tree-ish>]"),
|
||||
N_("git reset --patch [<tree-ish>] [--] [<pathspec>...]"),
|
||||
N_("git reset [-q] [<tree-ish>] [--] <paths>..."),
|
||||
N_("git reset --patch [<tree-ish>] [--] [<paths>...]"),
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -285,8 +284,8 @@ static int git_reset_config(const char *var, const char *value, void *cb)
|
|||
int cmd_reset(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int reset_type = NONE, update_ref_status = 0, quiet = 0;
|
||||
int patch_mode = 0, pathspec_file_nul = 0, unborn;
|
||||
const char *rev, *pathspec_from_file = NULL;
|
||||
int patch_mode = 0, unborn;
|
||||
const char *rev;
|
||||
struct object_id oid;
|
||||
struct pathspec pathspec;
|
||||
int intent_to_add = 0;
|
||||
|
|
@ -307,8 +306,6 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
|
|||
OPT_BOOL('p', "patch", &patch_mode, N_("select hunks interactively")),
|
||||
OPT_BOOL('N', "intent-to-add", &intent_to_add,
|
||||
N_("record only the fact that removed paths will be added later")),
|
||||
OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
|
||||
OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
|
|
@ -319,25 +316,11 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
|
|||
PARSE_OPT_KEEP_DASHDASH);
|
||||
parse_args(&pathspec, argv, prefix, patch_mode, &rev);
|
||||
|
||||
if (pathspec_from_file) {
|
||||
if (patch_mode)
|
||||
die(_("--pathspec-from-file is incompatible with --patch"));
|
||||
|
||||
if (pathspec.nr)
|
||||
die(_("--pathspec-from-file is incompatible with pathspec arguments"));
|
||||
|
||||
parse_pathspec_file(&pathspec, 0,
|
||||
PATHSPEC_PREFER_FULL,
|
||||
prefix, pathspec_from_file, pathspec_file_nul);
|
||||
} else if (pathspec_file_nul) {
|
||||
die(_("--pathspec-file-nul requires --pathspec-from-file"));
|
||||
}
|
||||
|
||||
unborn = !strcmp(rev, "HEAD") && get_oid("HEAD", &oid);
|
||||
if (unborn) {
|
||||
/* reset on unborn branch: treat as reset to empty tree */
|
||||
oidcpy(&oid, the_hash_algo->empty_tree);
|
||||
} else if (!pathspec.nr && !patch_mode) {
|
||||
} else if (!pathspec.nr) {
|
||||
struct commit *commit;
|
||||
if (get_oid_committish(rev, &oid))
|
||||
die(_("Failed to resolve '%s' as a valid revision."), rev);
|
||||
|
|
|
|||
126
third_party/git/builtin/rev-list.c
vendored
126
third_party/git/builtin/rev-list.c
vendored
|
|
@ -18,6 +18,7 @@
|
|||
#include "reflog-walk.h"
|
||||
#include "oidset.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
|
||||
static const char rev_list_usage[] =
|
||||
"git rev-list [OPTION] <commit-id>... [ -- paths... ]\n"
|
||||
|
|
@ -253,26 +254,11 @@ static int finish_object(struct object *obj, const char *name, void *cb_data)
|
|||
static void show_object(struct object *obj, const char *name, void *cb_data)
|
||||
{
|
||||
struct rev_list_info *info = cb_data;
|
||||
struct rev_info *revs = info->revs;
|
||||
|
||||
if (finish_object(obj, name, cb_data))
|
||||
return;
|
||||
display_progress(progress, ++progress_counter);
|
||||
if (info->flags & REV_LIST_QUIET)
|
||||
return;
|
||||
|
||||
if (revs->count) {
|
||||
/*
|
||||
* The object count is always accumulated in the .count_right
|
||||
* field for traversal that is not a left-right traversal,
|
||||
* and cmd_rev_list() made sure that a .count request that
|
||||
* wants to count non-commit objects, which is handled by
|
||||
* the show_object() callback, does not ask for .left_right.
|
||||
*/
|
||||
revs->count_right++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (arg_show_object_names)
|
||||
show_object_with_name(stdout, obj, name);
|
||||
else
|
||||
|
|
@ -379,79 +365,6 @@ static inline int parse_missing_action_value(const char *value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int try_bitmap_count(struct rev_info *revs,
|
||||
struct list_objects_filter_options *filter)
|
||||
{
|
||||
uint32_t commit_count = 0,
|
||||
tag_count = 0,
|
||||
tree_count = 0,
|
||||
blob_count = 0;
|
||||
int max_count;
|
||||
struct bitmap_index *bitmap_git;
|
||||
|
||||
/* This function only handles counting, not general traversal. */
|
||||
if (!revs->count)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* A bitmap result can't know left/right, etc, because we don't
|
||||
* actually traverse.
|
||||
*/
|
||||
if (revs->left_right || revs->cherry_mark)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* If we're counting reachable objects, we can't handle a max count of
|
||||
* commits to traverse, since we don't know which objects go with which
|
||||
* commit.
|
||||
*/
|
||||
if (revs->max_count >= 0 &&
|
||||
(revs->tag_objects || revs->tree_objects || revs->blob_objects))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* This must be saved before doing any walking, since the revision
|
||||
* machinery will count it down to zero while traversing.
|
||||
*/
|
||||
max_count = revs->max_count;
|
||||
|
||||
bitmap_git = prepare_bitmap_walk(revs, filter);
|
||||
if (!bitmap_git)
|
||||
return -1;
|
||||
|
||||
count_bitmap_commit_list(bitmap_git, &commit_count,
|
||||
revs->tree_objects ? &tree_count : NULL,
|
||||
revs->blob_objects ? &blob_count : NULL,
|
||||
revs->tag_objects ? &tag_count : NULL);
|
||||
if (max_count >= 0 && max_count < commit_count)
|
||||
commit_count = max_count;
|
||||
|
||||
printf("%d\n", commit_count + tree_count + blob_count + tag_count);
|
||||
free_bitmap_index(bitmap_git);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int try_bitmap_traversal(struct rev_info *revs,
|
||||
struct list_objects_filter_options *filter)
|
||||
{
|
||||
struct bitmap_index *bitmap_git;
|
||||
|
||||
/*
|
||||
* We can't use a bitmap result with a traversal limit, since the set
|
||||
* of commits we'd get would be essentially random.
|
||||
*/
|
||||
if (revs->max_count >= 0)
|
||||
return -1;
|
||||
|
||||
bitmap_git = prepare_bitmap_walk(revs, filter);
|
||||
if (!bitmap_git)
|
||||
return -1;
|
||||
|
||||
traverse_bitmap_commit_list(bitmap_git, revs, &show_object_fast);
|
||||
free_bitmap_index(bitmap_git);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd_rev_list(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct rev_info revs;
|
||||
|
|
@ -558,6 +471,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
|
|||
parse_list_objects_filter(&filter_options, arg);
|
||||
if (filter_options.choice && !revs.blob_objects)
|
||||
die(_("object filtering requires --objects"));
|
||||
if (filter_options.choice == LOFC_SPARSE_OID &&
|
||||
!filter_options.sparse_oid_value)
|
||||
die(_("invalid sparse value '%s'"),
|
||||
filter_options.filter_spec);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, ("--no-" CL_ARG__FILTER))) {
|
||||
|
|
@ -609,10 +526,8 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
|
|||
if (revs.show_notes)
|
||||
die(_("rev-list does not support display of notes"));
|
||||
|
||||
if (revs.count &&
|
||||
(revs.tag_objects || revs.tree_objects || revs.blob_objects) &&
|
||||
(revs.left_right || revs.cherry_mark))
|
||||
die(_("marked counting is incompatible with --objects"));
|
||||
if (filter_options.choice && use_bitmap_index)
|
||||
die(_("cannot combine --use-bitmap-index with object filtering"));
|
||||
|
||||
save_commit_buffer = (revs.verbose_header ||
|
||||
revs.grep_filter.pattern_list ||
|
||||
|
|
@ -623,11 +538,28 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
|
|||
if (show_progress)
|
||||
progress = start_delayed_progress(show_progress, 0);
|
||||
|
||||
if (use_bitmap_index) {
|
||||
if (!try_bitmap_count(&revs, &filter_options))
|
||||
return 0;
|
||||
if (!try_bitmap_traversal(&revs, &filter_options))
|
||||
return 0;
|
||||
if (use_bitmap_index && !revs.prune) {
|
||||
if (revs.count && !revs.left_right && !revs.cherry_mark) {
|
||||
uint32_t commit_count;
|
||||
int max_count = revs.max_count;
|
||||
struct bitmap_index *bitmap_git;
|
||||
if ((bitmap_git = prepare_bitmap_walk(&revs))) {
|
||||
count_bitmap_commit_list(bitmap_git, &commit_count, NULL, NULL, NULL);
|
||||
if (max_count >= 0 && max_count < commit_count)
|
||||
commit_count = max_count;
|
||||
printf("%d\n", commit_count);
|
||||
free_bitmap_index(bitmap_git);
|
||||
return 0;
|
||||
}
|
||||
} else if (revs.max_count < 0 &&
|
||||
revs.tag_objects && revs.tree_objects && revs.blob_objects) {
|
||||
struct bitmap_index *bitmap_git;
|
||||
if ((bitmap_git = prepare_bitmap_walk(&revs))) {
|
||||
traverse_bitmap_commit_list(bitmap_git, &show_object_fast);
|
||||
free_bitmap_index(bitmap_git);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prepare_revision_walk(&revs))
|
||||
|
|
|
|||
18
third_party/git/builtin/rev-parse.c
vendored
18
third_party/git/builtin/rev-parse.c
vendored
|
|
@ -593,7 +593,6 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
|
|||
const char *name = NULL;
|
||||
struct object_context unused;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
const int hexsz = the_hash_algo->hexsz;
|
||||
|
||||
if (argc > 1 && !strcmp("--parseopt", argv[1]))
|
||||
return cmd_parseopt(argc - 1, argv + 1, prefix);
|
||||
|
|
@ -731,8 +730,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
|
|||
abbrev = strtoul(arg, NULL, 10);
|
||||
if (abbrev < MINIMUM_ABBREV)
|
||||
abbrev = MINIMUM_ABBREV;
|
||||
else if (hexsz <= abbrev)
|
||||
abbrev = hexsz;
|
||||
else if (40 <= abbrev)
|
||||
abbrev = 40;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--sq")) {
|
||||
|
|
@ -803,8 +802,6 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
|
|||
const char *work_tree = get_git_work_tree();
|
||||
if (work_tree)
|
||||
puts(work_tree);
|
||||
else
|
||||
die("this operation must be run in a work tree");
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--show-superproject-working-tree")) {
|
||||
|
|
@ -921,17 +918,6 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
|
|||
show_datestring("--min-age=", arg);
|
||||
continue;
|
||||
}
|
||||
if (opt_with_value(arg, "--show-object-format", &arg)) {
|
||||
const char *val = arg ? arg : "storage";
|
||||
|
||||
if (strcmp(val, "storage") &&
|
||||
strcmp(val, "input") &&
|
||||
strcmp(val, "output"))
|
||||
die("unknown mode for --show-object-format: %s",
|
||||
arg);
|
||||
puts(the_hash_algo->name);
|
||||
continue;
|
||||
}
|
||||
if (show_flag(arg) && verify)
|
||||
die_no_single_rev(quiet);
|
||||
continue;
|
||||
|
|
|
|||
28
third_party/git/builtin/rm.c
vendored
28
third_party/git/builtin/rm.c
vendored
|
|
@ -235,8 +235,7 @@ static int check_local_mod(struct object_id *head, int index_only)
|
|||
}
|
||||
|
||||
static int show_only = 0, force = 0, index_only = 0, recursive = 0, quiet = 0;
|
||||
static int ignore_unmatch = 0, pathspec_file_nul;
|
||||
static char *pathspec_from_file;
|
||||
static int ignore_unmatch = 0;
|
||||
|
||||
static struct option builtin_rm_options[] = {
|
||||
OPT__DRY_RUN(&show_only, N_("dry run")),
|
||||
|
|
@ -246,8 +245,6 @@ static struct option builtin_rm_options[] = {
|
|||
OPT_BOOL('r', NULL, &recursive, N_("allow recursive removal")),
|
||||
OPT_BOOL( 0 , "ignore-unmatch", &ignore_unmatch,
|
||||
N_("exit with a zero status even if nothing matched")),
|
||||
OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
|
||||
OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
|
|
@ -262,24 +259,8 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
|
|||
|
||||
argc = parse_options(argc, argv, prefix, builtin_rm_options,
|
||||
builtin_rm_usage, 0);
|
||||
|
||||
parse_pathspec(&pathspec, 0,
|
||||
PATHSPEC_PREFER_CWD,
|
||||
prefix, argv);
|
||||
|
||||
if (pathspec_from_file) {
|
||||
if (pathspec.nr)
|
||||
die(_("--pathspec-from-file is incompatible with pathspec arguments"));
|
||||
|
||||
parse_pathspec_file(&pathspec, 0,
|
||||
PATHSPEC_PREFER_CWD,
|
||||
prefix, pathspec_from_file, pathspec_file_nul);
|
||||
} else if (pathspec_file_nul) {
|
||||
die(_("--pathspec-file-nul requires --pathspec-from-file"));
|
||||
}
|
||||
|
||||
if (!pathspec.nr)
|
||||
die(_("No pathspec was given. Which files should I remove?"));
|
||||
if (!argc)
|
||||
usage_with_options(builtin_rm_usage, builtin_rm_options);
|
||||
|
||||
if (!index_only)
|
||||
setup_work_tree();
|
||||
|
|
@ -289,6 +270,9 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
|
|||
if (read_cache() < 0)
|
||||
die(_("index file corrupt"));
|
||||
|
||||
parse_pathspec(&pathspec, 0,
|
||||
PATHSPEC_PREFER_CWD,
|
||||
prefix, argv);
|
||||
refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, &pathspec, NULL, NULL);
|
||||
|
||||
seen = xcalloc(pathspec.nr, 1);
|
||||
|
|
|
|||
2
third_party/git/builtin/show-branch.c
vendored
2
third_party/git/builtin/show-branch.c
vendored
|
|
@ -536,7 +536,7 @@ static void append_one_rev(const char *av)
|
|||
append_ref(av, &revkey, 0);
|
||||
return;
|
||||
}
|
||||
if (strpbrk(av, "*?[")) {
|
||||
if (strchr(av, '*') || strchr(av, '?') || strchr(av, '[')) {
|
||||
/* glob style match */
|
||||
int saved_matches = ref_name_cnt;
|
||||
|
||||
|
|
|
|||
13
third_party/git/builtin/show-index.c
vendored
13
third_party/git/builtin/show-index.c
vendored
|
|
@ -11,7 +11,6 @@ int cmd_show_index(int argc, const char **argv, const char *prefix)
|
|||
unsigned nr;
|
||||
unsigned int version;
|
||||
static unsigned int top_index[256];
|
||||
const unsigned hashsz = the_hash_algo->rawsz;
|
||||
|
||||
if (argc != 1)
|
||||
usage(show_index_usage);
|
||||
|
|
@ -37,23 +36,23 @@ int cmd_show_index(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
if (version == 1) {
|
||||
for (i = 0; i < nr; i++) {
|
||||
unsigned int offset, entry[(GIT_MAX_RAWSZ + 4) / sizeof(unsigned int)];
|
||||
unsigned int offset, entry[6];
|
||||
|
||||
if (fread(entry, 4 + hashsz, 1, stdin) != 1)
|
||||
if (fread(entry, 4 + 20, 1, stdin) != 1)
|
||||
die("unable to read entry %u/%u", i, nr);
|
||||
offset = ntohl(entry[0]);
|
||||
printf("%u %s\n", offset, hash_to_hex((void *)(entry+1)));
|
||||
printf("%u %s\n", offset, sha1_to_hex((void *)(entry+1)));
|
||||
}
|
||||
} else {
|
||||
unsigned off64_nr = 0;
|
||||
struct {
|
||||
struct object_id oid;
|
||||
unsigned char sha1[20];
|
||||
uint32_t crc;
|
||||
uint32_t off;
|
||||
} *entries;
|
||||
ALLOC_ARRAY(entries, nr);
|
||||
for (i = 0; i < nr; i++)
|
||||
if (fread(entries[i].oid.hash, hashsz, 1, stdin) != 1)
|
||||
if (fread(entries[i].sha1, 20, 1, stdin) != 1)
|
||||
die("unable to read sha1 %u/%u", i, nr);
|
||||
for (i = 0; i < nr; i++)
|
||||
if (fread(&entries[i].crc, 4, 1, stdin) != 1)
|
||||
|
|
@ -78,7 +77,7 @@ int cmd_show_index(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
printf("%" PRIuMAX " %s (%08"PRIx32")\n",
|
||||
(uintmax_t) offset,
|
||||
oid_to_hex(&entries[i].oid),
|
||||
sha1_to_hex(entries[i].sha1),
|
||||
ntohl(entries[i].crc));
|
||||
}
|
||||
free(entries);
|
||||
|
|
|
|||
631
third_party/git/builtin/sparse-checkout.c
vendored
631
third_party/git/builtin/sparse-checkout.c
vendored
|
|
@ -1,631 +0,0 @@
|
|||
#include "builtin.h"
|
||||
#include "config.h"
|
||||
#include "dir.h"
|
||||
#include "parse-options.h"
|
||||
#include "pathspec.h"
|
||||
#include "repository.h"
|
||||
#include "run-command.h"
|
||||
#include "strbuf.h"
|
||||
#include "string-list.h"
|
||||
#include "cache.h"
|
||||
#include "cache-tree.h"
|
||||
#include "lockfile.h"
|
||||
#include "resolve-undo.h"
|
||||
#include "unpack-trees.h"
|
||||
#include "wt-status.h"
|
||||
#include "quote.h"
|
||||
|
||||
static const char *empty_base = "";
|
||||
|
||||
static char const * const builtin_sparse_checkout_usage[] = {
|
||||
N_("git sparse-checkout (init|list|set|add|disable) <options>"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static char *get_sparse_checkout_filename(void)
|
||||
{
|
||||
return git_pathdup("info/sparse-checkout");
|
||||
}
|
||||
|
||||
static void write_patterns_to_file(FILE *fp, struct pattern_list *pl)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pl->nr; i++) {
|
||||
struct path_pattern *p = pl->patterns[i];
|
||||
|
||||
if (p->flags & PATTERN_FLAG_NEGATIVE)
|
||||
fprintf(fp, "!");
|
||||
|
||||
fprintf(fp, "%s", p->pattern);
|
||||
|
||||
if (p->flags & PATTERN_FLAG_MUSTBEDIR)
|
||||
fprintf(fp, "/");
|
||||
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int sparse_checkout_list(int argc, const char **argv)
|
||||
{
|
||||
struct pattern_list pl;
|
||||
char *sparse_filename;
|
||||
int res;
|
||||
|
||||
memset(&pl, 0, sizeof(pl));
|
||||
|
||||
pl.use_cone_patterns = core_sparse_checkout_cone;
|
||||
|
||||
sparse_filename = get_sparse_checkout_filename();
|
||||
res = add_patterns_from_file_to_list(sparse_filename, "", 0, &pl, NULL);
|
||||
free(sparse_filename);
|
||||
|
||||
if (res < 0) {
|
||||
warning(_("this worktree is not sparse (sparse-checkout file may not exist)"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pl.use_cone_patterns) {
|
||||
int i;
|
||||
struct pattern_entry *pe;
|
||||
struct hashmap_iter iter;
|
||||
struct string_list sl = STRING_LIST_INIT_DUP;
|
||||
|
||||
hashmap_for_each_entry(&pl.recursive_hashmap, &iter, pe, ent) {
|
||||
/* pe->pattern starts with "/", skip it */
|
||||
string_list_insert(&sl, pe->pattern + 1);
|
||||
}
|
||||
|
||||
string_list_sort(&sl);
|
||||
|
||||
for (i = 0; i < sl.nr; i++) {
|
||||
quote_c_style(sl.items[i].string, NULL, stdout, 0);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
write_patterns_to_file(stdout, &pl);
|
||||
clear_pattern_list(&pl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int update_working_directory(struct pattern_list *pl)
|
||||
{
|
||||
int result = 0;
|
||||
struct unpack_trees_options o;
|
||||
struct lock_file lock_file = LOCK_INIT;
|
||||
struct object_id oid;
|
||||
struct tree *tree;
|
||||
struct tree_desc t;
|
||||
struct repository *r = the_repository;
|
||||
|
||||
if (repo_read_index_unmerged(r))
|
||||
die(_("you need to resolve your current index first"));
|
||||
|
||||
if (get_oid("HEAD", &oid))
|
||||
return 0;
|
||||
|
||||
tree = parse_tree_indirect(&oid);
|
||||
parse_tree(tree);
|
||||
init_tree_desc(&t, tree->buffer, tree->size);
|
||||
|
||||
memset(&o, 0, sizeof(o));
|
||||
o.verbose_update = isatty(2);
|
||||
o.merge = 1;
|
||||
o.update = 1;
|
||||
o.fn = oneway_merge;
|
||||
o.head_idx = -1;
|
||||
o.src_index = r->index;
|
||||
o.dst_index = r->index;
|
||||
o.skip_sparse_checkout = 0;
|
||||
o.pl = pl;
|
||||
o.keep_pattern_list = !!pl;
|
||||
|
||||
resolve_undo_clear_index(r->index);
|
||||
setup_work_tree();
|
||||
|
||||
cache_tree_free(&r->index->cache_tree);
|
||||
|
||||
repo_hold_locked_index(r, &lock_file, LOCK_DIE_ON_ERROR);
|
||||
|
||||
core_apply_sparse_checkout = 1;
|
||||
result = unpack_trees(1, &t, &o);
|
||||
|
||||
if (!result) {
|
||||
prime_cache_tree(r, r->index, tree);
|
||||
write_locked_index(r->index, &lock_file, COMMIT_LOCK);
|
||||
} else
|
||||
rollback_lock_file(&lock_file);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static char *escaped_pattern(char *pattern)
|
||||
{
|
||||
char *p = pattern;
|
||||
struct strbuf final = STRBUF_INIT;
|
||||
|
||||
while (*p) {
|
||||
if (is_glob_special(*p))
|
||||
strbuf_addch(&final, '\\');
|
||||
|
||||
strbuf_addch(&final, *p);
|
||||
p++;
|
||||
}
|
||||
|
||||
return strbuf_detach(&final, NULL);
|
||||
}
|
||||
|
||||
static void write_cone_to_file(FILE *fp, struct pattern_list *pl)
|
||||
{
|
||||
int i;
|
||||
struct pattern_entry *pe;
|
||||
struct hashmap_iter iter;
|
||||
struct string_list sl = STRING_LIST_INIT_DUP;
|
||||
struct strbuf parent_pattern = STRBUF_INIT;
|
||||
|
||||
hashmap_for_each_entry(&pl->parent_hashmap, &iter, pe, ent) {
|
||||
if (hashmap_get_entry(&pl->recursive_hashmap, pe, ent, NULL))
|
||||
continue;
|
||||
|
||||
if (!hashmap_contains_parent(&pl->recursive_hashmap,
|
||||
pe->pattern,
|
||||
&parent_pattern))
|
||||
string_list_insert(&sl, pe->pattern);
|
||||
}
|
||||
|
||||
string_list_sort(&sl);
|
||||
string_list_remove_duplicates(&sl, 0);
|
||||
|
||||
fprintf(fp, "/*\n!/*/\n");
|
||||
|
||||
for (i = 0; i < sl.nr; i++) {
|
||||
char *pattern = escaped_pattern(sl.items[i].string);
|
||||
|
||||
if (strlen(pattern))
|
||||
fprintf(fp, "%s/\n!%s/*/\n", pattern, pattern);
|
||||
free(pattern);
|
||||
}
|
||||
|
||||
string_list_clear(&sl, 0);
|
||||
|
||||
hashmap_for_each_entry(&pl->recursive_hashmap, &iter, pe, ent) {
|
||||
if (!hashmap_contains_parent(&pl->recursive_hashmap,
|
||||
pe->pattern,
|
||||
&parent_pattern))
|
||||
string_list_insert(&sl, pe->pattern);
|
||||
}
|
||||
|
||||
strbuf_release(&parent_pattern);
|
||||
|
||||
string_list_sort(&sl);
|
||||
string_list_remove_duplicates(&sl, 0);
|
||||
|
||||
for (i = 0; i < sl.nr; i++) {
|
||||
char *pattern = escaped_pattern(sl.items[i].string);
|
||||
fprintf(fp, "%s/\n", pattern);
|
||||
free(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
static int write_patterns_and_update(struct pattern_list *pl)
|
||||
{
|
||||
char *sparse_filename;
|
||||
FILE *fp;
|
||||
int fd;
|
||||
struct lock_file lk = LOCK_INIT;
|
||||
int result;
|
||||
|
||||
sparse_filename = get_sparse_checkout_filename();
|
||||
|
||||
if (safe_create_leading_directories(sparse_filename))
|
||||
die(_("failed to create directory for sparse-checkout file"));
|
||||
|
||||
fd = hold_lock_file_for_update(&lk, sparse_filename,
|
||||
LOCK_DIE_ON_ERROR);
|
||||
|
||||
result = update_working_directory(pl);
|
||||
if (result) {
|
||||
rollback_lock_file(&lk);
|
||||
free(sparse_filename);
|
||||
clear_pattern_list(pl);
|
||||
update_working_directory(NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
fp = xfdopen(fd, "w");
|
||||
|
||||
if (core_sparse_checkout_cone)
|
||||
write_cone_to_file(fp, pl);
|
||||
else
|
||||
write_patterns_to_file(fp, pl);
|
||||
|
||||
fflush(fp);
|
||||
commit_lock_file(&lk);
|
||||
|
||||
free(sparse_filename);
|
||||
clear_pattern_list(pl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum sparse_checkout_mode {
|
||||
MODE_NO_PATTERNS = 0,
|
||||
MODE_ALL_PATTERNS = 1,
|
||||
MODE_CONE_PATTERNS = 2,
|
||||
};
|
||||
|
||||
static int set_config(enum sparse_checkout_mode mode)
|
||||
{
|
||||
const char *config_path;
|
||||
|
||||
if (git_config_set_gently("extensions.worktreeConfig", "true")) {
|
||||
error(_("failed to set extensions.worktreeConfig setting"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
config_path = git_path("config.worktree");
|
||||
git_config_set_in_file_gently(config_path,
|
||||
"core.sparseCheckout",
|
||||
mode ? "true" : NULL);
|
||||
|
||||
git_config_set_in_file_gently(config_path,
|
||||
"core.sparseCheckoutCone",
|
||||
mode == MODE_CONE_PATTERNS ? "true" : NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char const * const builtin_sparse_checkout_init_usage[] = {
|
||||
N_("git sparse-checkout init [--cone]"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct sparse_checkout_init_opts {
|
||||
int cone_mode;
|
||||
} init_opts;
|
||||
|
||||
static int sparse_checkout_init(int argc, const char **argv)
|
||||
{
|
||||
struct pattern_list pl;
|
||||
char *sparse_filename;
|
||||
int res;
|
||||
struct object_id oid;
|
||||
int mode;
|
||||
struct strbuf pattern = STRBUF_INIT;
|
||||
|
||||
static struct option builtin_sparse_checkout_init_options[] = {
|
||||
OPT_BOOL(0, "cone", &init_opts.cone_mode,
|
||||
N_("initialize the sparse-checkout in cone mode")),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
repo_read_index(the_repository);
|
||||
require_clean_work_tree(the_repository,
|
||||
N_("initialize sparse-checkout"), NULL, 1, 0);
|
||||
|
||||
argc = parse_options(argc, argv, NULL,
|
||||
builtin_sparse_checkout_init_options,
|
||||
builtin_sparse_checkout_init_usage, 0);
|
||||
|
||||
if (init_opts.cone_mode) {
|
||||
mode = MODE_CONE_PATTERNS;
|
||||
core_sparse_checkout_cone = 1;
|
||||
} else
|
||||
mode = MODE_ALL_PATTERNS;
|
||||
|
||||
if (set_config(mode))
|
||||
return 1;
|
||||
|
||||
memset(&pl, 0, sizeof(pl));
|
||||
|
||||
sparse_filename = get_sparse_checkout_filename();
|
||||
res = add_patterns_from_file_to_list(sparse_filename, "", 0, &pl, NULL);
|
||||
|
||||
/* If we already have a sparse-checkout file, use it. */
|
||||
if (res >= 0) {
|
||||
free(sparse_filename);
|
||||
core_apply_sparse_checkout = 1;
|
||||
return update_working_directory(NULL);
|
||||
}
|
||||
|
||||
if (get_oid("HEAD", &oid)) {
|
||||
FILE *fp;
|
||||
|
||||
/* assume we are in a fresh repo, but update the sparse-checkout file */
|
||||
fp = xfopen(sparse_filename, "w");
|
||||
if (!fp)
|
||||
die(_("failed to open '%s'"), sparse_filename);
|
||||
|
||||
free(sparse_filename);
|
||||
fprintf(fp, "/*\n!/*/\n");
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strbuf_addstr(&pattern, "/*");
|
||||
add_pattern(strbuf_detach(&pattern, NULL), empty_base, 0, &pl, 0);
|
||||
strbuf_addstr(&pattern, "!/*/");
|
||||
add_pattern(strbuf_detach(&pattern, NULL), empty_base, 0, &pl, 0);
|
||||
|
||||
return write_patterns_and_update(&pl);
|
||||
}
|
||||
|
||||
static void insert_recursive_pattern(struct pattern_list *pl, struct strbuf *path)
|
||||
{
|
||||
struct pattern_entry *e = xmalloc(sizeof(*e));
|
||||
e->patternlen = path->len;
|
||||
e->pattern = strbuf_detach(path, NULL);
|
||||
hashmap_entry_init(&e->ent,
|
||||
ignore_case ?
|
||||
strihash(e->pattern) :
|
||||
strhash(e->pattern));
|
||||
|
||||
hashmap_add(&pl->recursive_hashmap, &e->ent);
|
||||
|
||||
while (e->patternlen) {
|
||||
char *slash = strrchr(e->pattern, '/');
|
||||
char *oldpattern = e->pattern;
|
||||
size_t newlen;
|
||||
|
||||
if (slash == e->pattern)
|
||||
break;
|
||||
|
||||
newlen = slash - e->pattern;
|
||||
e = xmalloc(sizeof(struct pattern_entry));
|
||||
e->patternlen = newlen;
|
||||
e->pattern = xstrndup(oldpattern, newlen);
|
||||
hashmap_entry_init(&e->ent,
|
||||
ignore_case ?
|
||||
strihash(e->pattern) :
|
||||
strhash(e->pattern));
|
||||
|
||||
if (!hashmap_get_entry(&pl->parent_hashmap, e, ent, NULL))
|
||||
hashmap_add(&pl->parent_hashmap, &e->ent);
|
||||
}
|
||||
}
|
||||
|
||||
static void strbuf_to_cone_pattern(struct strbuf *line, struct pattern_list *pl)
|
||||
{
|
||||
strbuf_trim(line);
|
||||
|
||||
strbuf_trim_trailing_dir_sep(line);
|
||||
|
||||
if (strbuf_normalize_path(line))
|
||||
die(_("could not normalize path %s"), line->buf);
|
||||
|
||||
if (!line->len)
|
||||
return;
|
||||
|
||||
if (line->buf[0] != '/')
|
||||
strbuf_insertstr(line, 0, "/");
|
||||
|
||||
insert_recursive_pattern(pl, line);
|
||||
}
|
||||
|
||||
static char const * const builtin_sparse_checkout_set_usage[] = {
|
||||
N_("git sparse-checkout (set|add) (--stdin | <patterns>)"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct sparse_checkout_set_opts {
|
||||
int use_stdin;
|
||||
} set_opts;
|
||||
|
||||
static void add_patterns_from_input(struct pattern_list *pl,
|
||||
int argc, const char **argv)
|
||||
{
|
||||
int i;
|
||||
if (core_sparse_checkout_cone) {
|
||||
struct strbuf line = STRBUF_INIT;
|
||||
|
||||
hashmap_init(&pl->recursive_hashmap, pl_hashmap_cmp, NULL, 0);
|
||||
hashmap_init(&pl->parent_hashmap, pl_hashmap_cmp, NULL, 0);
|
||||
pl->use_cone_patterns = 1;
|
||||
|
||||
if (set_opts.use_stdin) {
|
||||
struct strbuf unquoted = STRBUF_INIT;
|
||||
while (!strbuf_getline(&line, stdin)) {
|
||||
if (line.buf[0] == '"') {
|
||||
strbuf_reset(&unquoted);
|
||||
if (unquote_c_style(&unquoted, line.buf, NULL))
|
||||
die(_("unable to unquote C-style string '%s'"),
|
||||
line.buf);
|
||||
|
||||
strbuf_swap(&unquoted, &line);
|
||||
}
|
||||
|
||||
strbuf_to_cone_pattern(&line, pl);
|
||||
}
|
||||
|
||||
strbuf_release(&unquoted);
|
||||
} else {
|
||||
for (i = 0; i < argc; i++) {
|
||||
strbuf_setlen(&line, 0);
|
||||
strbuf_addstr(&line, argv[i]);
|
||||
strbuf_to_cone_pattern(&line, pl);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (set_opts.use_stdin) {
|
||||
struct strbuf line = STRBUF_INIT;
|
||||
|
||||
while (!strbuf_getline(&line, stdin)) {
|
||||
size_t len;
|
||||
char *buf = strbuf_detach(&line, &len);
|
||||
add_pattern(buf, empty_base, 0, pl, 0);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < argc; i++)
|
||||
add_pattern(argv[i], empty_base, 0, pl, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum modify_type {
|
||||
REPLACE,
|
||||
ADD,
|
||||
};
|
||||
|
||||
static void add_patterns_cone_mode(int argc, const char **argv,
|
||||
struct pattern_list *pl)
|
||||
{
|
||||
struct strbuf buffer = STRBUF_INIT;
|
||||
struct pattern_entry *pe;
|
||||
struct hashmap_iter iter;
|
||||
struct pattern_list existing;
|
||||
char *sparse_filename = get_sparse_checkout_filename();
|
||||
|
||||
add_patterns_from_input(pl, argc, argv);
|
||||
|
||||
memset(&existing, 0, sizeof(existing));
|
||||
existing.use_cone_patterns = core_sparse_checkout_cone;
|
||||
|
||||
if (add_patterns_from_file_to_list(sparse_filename, "", 0,
|
||||
&existing, NULL))
|
||||
die(_("unable to load existing sparse-checkout patterns"));
|
||||
free(sparse_filename);
|
||||
|
||||
hashmap_for_each_entry(&existing.recursive_hashmap, &iter, pe, ent) {
|
||||
if (!hashmap_contains_parent(&pl->recursive_hashmap,
|
||||
pe->pattern, &buffer) ||
|
||||
!hashmap_contains_parent(&pl->parent_hashmap,
|
||||
pe->pattern, &buffer)) {
|
||||
strbuf_reset(&buffer);
|
||||
strbuf_addstr(&buffer, pe->pattern);
|
||||
insert_recursive_pattern(pl, &buffer);
|
||||
}
|
||||
}
|
||||
|
||||
clear_pattern_list(&existing);
|
||||
strbuf_release(&buffer);
|
||||
}
|
||||
|
||||
static void add_patterns_literal(int argc, const char **argv,
|
||||
struct pattern_list *pl)
|
||||
{
|
||||
char *sparse_filename = get_sparse_checkout_filename();
|
||||
if (add_patterns_from_file_to_list(sparse_filename, "", 0,
|
||||
pl, NULL))
|
||||
die(_("unable to load existing sparse-checkout patterns"));
|
||||
free(sparse_filename);
|
||||
add_patterns_from_input(pl, argc, argv);
|
||||
}
|
||||
|
||||
static int modify_pattern_list(int argc, const char **argv, enum modify_type m)
|
||||
{
|
||||
int result;
|
||||
int changed_config = 0;
|
||||
struct pattern_list pl;
|
||||
memset(&pl, 0, sizeof(pl));
|
||||
|
||||
switch (m) {
|
||||
case ADD:
|
||||
if (core_sparse_checkout_cone)
|
||||
add_patterns_cone_mode(argc, argv, &pl);
|
||||
else
|
||||
add_patterns_literal(argc, argv, &pl);
|
||||
break;
|
||||
|
||||
case REPLACE:
|
||||
add_patterns_from_input(&pl, argc, argv);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!core_apply_sparse_checkout) {
|
||||
set_config(MODE_ALL_PATTERNS);
|
||||
core_apply_sparse_checkout = 1;
|
||||
changed_config = 1;
|
||||
}
|
||||
|
||||
result = write_patterns_and_update(&pl);
|
||||
|
||||
if (result && changed_config)
|
||||
set_config(MODE_NO_PATTERNS);
|
||||
|
||||
clear_pattern_list(&pl);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int sparse_checkout_set(int argc, const char **argv, const char *prefix,
|
||||
enum modify_type m)
|
||||
{
|
||||
static struct option builtin_sparse_checkout_set_options[] = {
|
||||
OPT_BOOL(0, "stdin", &set_opts.use_stdin,
|
||||
N_("read patterns from standard in")),
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
repo_read_index(the_repository);
|
||||
require_clean_work_tree(the_repository,
|
||||
N_("set sparse-checkout patterns"), NULL, 1, 0);
|
||||
|
||||
argc = parse_options(argc, argv, prefix,
|
||||
builtin_sparse_checkout_set_options,
|
||||
builtin_sparse_checkout_set_usage,
|
||||
PARSE_OPT_KEEP_UNKNOWN);
|
||||
|
||||
return modify_pattern_list(argc, argv, m);
|
||||
}
|
||||
|
||||
static int sparse_checkout_disable(int argc, const char **argv)
|
||||
{
|
||||
struct pattern_list pl;
|
||||
struct strbuf match_all = STRBUF_INIT;
|
||||
|
||||
repo_read_index(the_repository);
|
||||
require_clean_work_tree(the_repository,
|
||||
N_("disable sparse-checkout"), NULL, 1, 0);
|
||||
|
||||
memset(&pl, 0, sizeof(pl));
|
||||
hashmap_init(&pl.recursive_hashmap, pl_hashmap_cmp, NULL, 0);
|
||||
hashmap_init(&pl.parent_hashmap, pl_hashmap_cmp, NULL, 0);
|
||||
pl.use_cone_patterns = 0;
|
||||
core_apply_sparse_checkout = 1;
|
||||
|
||||
strbuf_addstr(&match_all, "/*");
|
||||
add_pattern(strbuf_detach(&match_all, NULL), empty_base, 0, &pl, 0);
|
||||
|
||||
if (update_working_directory(&pl))
|
||||
die(_("error while refreshing working directory"));
|
||||
|
||||
clear_pattern_list(&pl);
|
||||
return set_config(MODE_NO_PATTERNS);
|
||||
}
|
||||
|
||||
int cmd_sparse_checkout(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
static struct option builtin_sparse_checkout_options[] = {
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
if (argc == 2 && !strcmp(argv[1], "-h"))
|
||||
usage_with_options(builtin_sparse_checkout_usage,
|
||||
builtin_sparse_checkout_options);
|
||||
|
||||
argc = parse_options(argc, argv, prefix,
|
||||
builtin_sparse_checkout_options,
|
||||
builtin_sparse_checkout_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
|
||||
git_config(git_default_config, NULL);
|
||||
|
||||
if (argc > 0) {
|
||||
if (!strcmp(argv[0], "list"))
|
||||
return sparse_checkout_list(argc, argv);
|
||||
if (!strcmp(argv[0], "init"))
|
||||
return sparse_checkout_init(argc, argv);
|
||||
if (!strcmp(argv[0], "set"))
|
||||
return sparse_checkout_set(argc, argv, prefix, REPLACE);
|
||||
if (!strcmp(argv[0], "add"))
|
||||
return sparse_checkout_set(argc, argv, prefix, ADD);
|
||||
if (!strcmp(argv[0], "disable"))
|
||||
return sparse_checkout_disable(argc, argv);
|
||||
}
|
||||
|
||||
usage_with_options(builtin_sparse_checkout_usage,
|
||||
builtin_sparse_checkout_options);
|
||||
}
|
||||
133
third_party/git/builtin/stash.c
vendored
133
third_party/git/builtin/stash.c
vendored
|
|
@ -27,7 +27,6 @@ static const char * const git_stash_usage[] = {
|
|||
N_("git stash clear"),
|
||||
N_("git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
|
||||
" [-u|--include-untracked] [-a|--all] [-m|--message <message>]\n"
|
||||
" [--pathspec-from-file=<file> [--pathspec-file-nul]]\n"
|
||||
" [--] [<pathspec>...]]"),
|
||||
N_("git stash save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n"
|
||||
" [-u|--include-untracked] [-a|--all] [<message>]"),
|
||||
|
|
@ -397,7 +396,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
|
|||
const struct object_id *bases[1];
|
||||
|
||||
read_cache_preload(NULL);
|
||||
if (refresh_and_write_cache(REFRESH_QUIET, 0, 0))
|
||||
if (refresh_cache(REFRESH_QUIET))
|
||||
return -1;
|
||||
|
||||
if (write_cache_as_tree(&c_tree, 0, NULL))
|
||||
|
|
@ -428,8 +427,6 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
|
|||
return error(_("could not save index tree"));
|
||||
|
||||
reset_head();
|
||||
discard_cache();
|
||||
read_cache();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -484,12 +481,13 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
|
|||
if (ret)
|
||||
return -1;
|
||||
|
||||
/* read back the result of update_index() back from the disk */
|
||||
discard_cache();
|
||||
read_cache();
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
if (quiet) {
|
||||
if (refresh_cache(REFRESH_QUIET))
|
||||
warning("could not refresh index");
|
||||
} else {
|
||||
struct child_process cp = CHILD_PROCESS_INIT;
|
||||
|
||||
/*
|
||||
|
|
@ -499,10 +497,6 @@ static int do_apply_stash(const char *prefix, struct stash_info *info,
|
|||
*/
|
||||
cp.git_cmd = 1;
|
||||
cp.dir = prefix;
|
||||
argv_array_pushf(&cp.env_array, GIT_WORK_TREE_ENVIRONMENT"=%s",
|
||||
absolute_path(get_git_work_tree()));
|
||||
argv_array_pushf(&cp.env_array, GIT_DIR_ENVIRONMENT"=%s",
|
||||
absolute_path(get_git_dir()));
|
||||
argv_array_push(&cp.args, "status");
|
||||
run_command(&cp);
|
||||
}
|
||||
|
|
@ -999,9 +993,9 @@ static int stash_patch(struct stash_info *info, const struct pathspec *ps,
|
|||
{
|
||||
int ret = 0;
|
||||
struct child_process cp_read_tree = CHILD_PROCESS_INIT;
|
||||
struct child_process cp_add_i = CHILD_PROCESS_INIT;
|
||||
struct child_process cp_diff_tree = CHILD_PROCESS_INIT;
|
||||
struct index_state istate = { NULL };
|
||||
char *old_index_env = NULL, *old_repo_index_file;
|
||||
|
||||
remove_path(stash_index_path.buf);
|
||||
|
||||
|
|
@ -1015,19 +1009,16 @@ static int stash_patch(struct stash_info *info, const struct pathspec *ps,
|
|||
}
|
||||
|
||||
/* Find out what the user wants. */
|
||||
old_repo_index_file = the_repository->index_file;
|
||||
the_repository->index_file = stash_index_path.buf;
|
||||
old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT));
|
||||
setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1);
|
||||
|
||||
ret = run_add_interactive(NULL, "--patch=stash", ps);
|
||||
|
||||
the_repository->index_file = old_repo_index_file;
|
||||
if (old_index_env && *old_index_env)
|
||||
setenv(INDEX_ENVIRONMENT, old_index_env, 1);
|
||||
else
|
||||
unsetenv(INDEX_ENVIRONMENT);
|
||||
FREE_AND_NULL(old_index_env);
|
||||
cp_add_i.git_cmd = 1;
|
||||
argv_array_pushl(&cp_add_i.args, "add--interactive", "--patch=stash",
|
||||
"--", NULL);
|
||||
add_pathspecs(&cp_add_i.args, ps);
|
||||
argv_array_pushf(&cp_add_i.env_array, "GIT_INDEX_FILE=%s",
|
||||
stash_index_path.buf);
|
||||
if (run_command(&cp_add_i)) {
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* State of the working tree. */
|
||||
if (write_index_as_tree(&info->w_tree, &istate, stash_index_path.buf, 0,
|
||||
|
|
@ -1091,9 +1082,8 @@ static int stash_working_tree(struct stash_info *info, const struct pathspec *ps
|
|||
}
|
||||
|
||||
cp_upd_index.git_cmd = 1;
|
||||
argv_array_pushl(&cp_upd_index.args, "update-index",
|
||||
"--ignore-skip-worktree-entries",
|
||||
"-z", "--add", "--remove", "--stdin", NULL);
|
||||
argv_array_pushl(&cp_upd_index.args, "update-index", "-z", "--add",
|
||||
"--remove", "--stdin", NULL);
|
||||
argv_array_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s",
|
||||
stash_index_path.buf);
|
||||
|
||||
|
|
@ -1139,10 +1129,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b
|
|||
prepare_fallback_ident("git stash", "git@stash");
|
||||
|
||||
read_cache_preload(NULL);
|
||||
if (refresh_and_write_cache(REFRESH_QUIET, 0, 0) < 0) {
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
refresh_cache(REFRESH_QUIET);
|
||||
|
||||
if (get_oid("HEAD", &info->b_commit)) {
|
||||
if (!quiet)
|
||||
|
|
@ -1303,7 +1290,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
|
|||
free(ps_matched);
|
||||
}
|
||||
|
||||
if (refresh_and_write_cache(REFRESH_QUIET, 0, 0)) {
|
||||
if (refresh_cache(REFRESH_QUIET)) {
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -1396,7 +1383,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q
|
|||
struct child_process cp = CHILD_PROCESS_INIT;
|
||||
cp.git_cmd = 1;
|
||||
argv_array_pushl(&cp.args, "reset", "--hard", "-q",
|
||||
"--no-recurse-submodules", NULL);
|
||||
NULL);
|
||||
if (run_command(&cp)) {
|
||||
ret = -1;
|
||||
goto done;
|
||||
|
|
@ -1452,17 +1439,13 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int push_stash(int argc, const char **argv, const char *prefix,
|
||||
int push_assumed)
|
||||
static int push_stash(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int force_assume = 0;
|
||||
int keep_index = -1;
|
||||
int patch_mode = 0;
|
||||
int include_untracked = 0;
|
||||
int quiet = 0;
|
||||
int pathspec_file_nul = 0;
|
||||
const char *stash_msg = NULL;
|
||||
const char *pathspec_from_file = NULL;
|
||||
struct pathspec ps;
|
||||
struct option options[] = {
|
||||
OPT_BOOL('k', "keep-index", &keep_index,
|
||||
|
|
@ -1476,45 +1459,16 @@ static int push_stash(int argc, const char **argv, const char *prefix,
|
|||
N_("include ignore files"), 2),
|
||||
OPT_STRING('m', "message", &stash_msg, N_("message"),
|
||||
N_("stash message")),
|
||||
OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
|
||||
OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
if (argc) {
|
||||
force_assume = !strcmp(argv[0], "-p");
|
||||
if (argc)
|
||||
argc = parse_options(argc, argv, prefix, options,
|
||||
git_stash_push_usage,
|
||||
PARSE_OPT_KEEP_DASHDASH);
|
||||
}
|
||||
|
||||
if (argc) {
|
||||
if (!strcmp(argv[0], "--")) {
|
||||
argc--;
|
||||
argv++;
|
||||
} else if (push_assumed && !force_assume) {
|
||||
die("subcommand wasn't specified; 'push' can't be assumed due to unexpected token '%s'",
|
||||
argv[0]);
|
||||
}
|
||||
}
|
||||
0);
|
||||
|
||||
parse_pathspec(&ps, 0, PATHSPEC_PREFER_FULL | PATHSPEC_PREFIX_ORIGIN,
|
||||
prefix, argv);
|
||||
|
||||
if (pathspec_from_file) {
|
||||
if (patch_mode)
|
||||
die(_("--pathspec-from-file is incompatible with --patch"));
|
||||
|
||||
if (ps.nr)
|
||||
die(_("--pathspec-from-file is incompatible with pathspec arguments"));
|
||||
|
||||
parse_pathspec_file(&ps, 0,
|
||||
PATHSPEC_PREFER_FULL | PATHSPEC_PREFIX_ORIGIN,
|
||||
prefix, pathspec_from_file, pathspec_file_nul);
|
||||
} else if (pathspec_file_nul) {
|
||||
die(_("--pathspec-file-nul requires --pathspec-from-file"));
|
||||
}
|
||||
|
||||
return do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,
|
||||
include_untracked);
|
||||
}
|
||||
|
|
@ -1584,6 +1538,7 @@ static int use_builtin_stash(void)
|
|||
|
||||
int cmd_stash(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int i = -1;
|
||||
pid_t pid = getpid();
|
||||
const char *index_file;
|
||||
struct argv_array args = ARGV_ARRAY_INIT;
|
||||
|
|
@ -1616,7 +1571,7 @@ int cmd_stash(int argc, const char **argv, const char *prefix)
|
|||
(uintmax_t)pid);
|
||||
|
||||
if (!argc)
|
||||
return !!push_stash(0, NULL, prefix, 0);
|
||||
return !!push_stash(0, NULL, prefix);
|
||||
else if (!strcmp(argv[0], "apply"))
|
||||
return !!apply_stash(argc, argv, prefix);
|
||||
else if (!strcmp(argv[0], "clear"))
|
||||
|
|
@ -1636,15 +1591,45 @@ int cmd_stash(int argc, const char **argv, const char *prefix)
|
|||
else if (!strcmp(argv[0], "create"))
|
||||
return !!create_stash(argc, argv, prefix);
|
||||
else if (!strcmp(argv[0], "push"))
|
||||
return !!push_stash(argc, argv, prefix, 0);
|
||||
return !!push_stash(argc, argv, prefix);
|
||||
else if (!strcmp(argv[0], "save"))
|
||||
return !!save_stash(argc, argv, prefix);
|
||||
else if (*argv[0] != '-')
|
||||
usage_msg_opt(xstrfmt(_("unknown subcommand: %s"), argv[0]),
|
||||
git_stash_usage, options);
|
||||
|
||||
/* Assume 'stash push' */
|
||||
if (strcmp(argv[0], "-p")) {
|
||||
while (++i < argc && strcmp(argv[i], "--")) {
|
||||
/*
|
||||
* `akpqu` is a string which contains all short options,
|
||||
* except `-m` which is verified separately.
|
||||
*/
|
||||
if ((strlen(argv[i]) == 2) && *argv[i] == '-' &&
|
||||
strchr("akpqu", argv[i][1]))
|
||||
continue;
|
||||
|
||||
if (!strcmp(argv[i], "--all") ||
|
||||
!strcmp(argv[i], "--keep-index") ||
|
||||
!strcmp(argv[i], "--no-keep-index") ||
|
||||
!strcmp(argv[i], "--patch") ||
|
||||
!strcmp(argv[i], "--quiet") ||
|
||||
!strcmp(argv[i], "--include-untracked"))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* `-m` and `--message=` are verified separately because
|
||||
* they need to be immediately followed by a string
|
||||
* (i.e.`-m"foobar"` or `--message="foobar"`).
|
||||
*/
|
||||
if (starts_with(argv[i], "-m") ||
|
||||
starts_with(argv[i], "--message="))
|
||||
continue;
|
||||
|
||||
usage_with_options(git_stash_usage, options);
|
||||
}
|
||||
}
|
||||
|
||||
argv_array_push(&args, "push");
|
||||
argv_array_pushv(&args, argv);
|
||||
return !!push_stash(args.argc, args.argv, prefix, 1);
|
||||
return !!push_stash(args.argc, args.argv, prefix);
|
||||
}
|
||||
|
|
|
|||
78
third_party/git/builtin/submodule--helper.c
vendored
78
third_party/git/builtin/submodule--helper.c
vendored
|
|
@ -19,8 +19,6 @@
|
|||
#include "diffcore.h"
|
||||
#include "diff.h"
|
||||
#include "object-store.h"
|
||||
#include "dir.h"
|
||||
#include "advice.h"
|
||||
|
||||
#define OPT_QUIET (1 << 0)
|
||||
#define OPT_CACHED (1 << 1)
|
||||
|
|
@ -426,7 +424,7 @@ static int module_list(int argc, const char **argv, const char *prefix)
|
|||
const struct cache_entry *ce = list.entries[i];
|
||||
|
||||
if (ce_stage(ce))
|
||||
printf("%06o %s U\t", ce->ce_mode, oid_to_hex(&null_oid));
|
||||
printf("%06o %s U\t", ce->ce_mode, sha1_to_hex(null_sha1));
|
||||
else
|
||||
printf("%06o %s %d\t", ce->ce_mode,
|
||||
oid_to_hex(&ce->oid), ce_stage(ce));
|
||||
|
|
@ -782,8 +780,6 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
|
|||
struct argv_array diff_files_args = ARGV_ARRAY_INIT;
|
||||
struct rev_info rev;
|
||||
int diff_files_result;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
const char *git_dir;
|
||||
|
||||
if (!submodule_from_path(the_repository, &null_oid, path))
|
||||
die(_("no submodule mapping found in .gitmodules for path '%s'"),
|
||||
|
|
@ -796,26 +792,17 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
strbuf_addf(&buf, "%s/.git", path);
|
||||
git_dir = read_gitfile(buf.buf);
|
||||
if (!git_dir)
|
||||
git_dir = buf.buf;
|
||||
|
||||
if (!is_submodule_active(the_repository, path) ||
|
||||
!is_git_directory(git_dir)) {
|
||||
if (!is_submodule_active(the_repository, path)) {
|
||||
print_status(flags, '-', path, ce_oid, displaypath);
|
||||
strbuf_release(&buf);
|
||||
goto cleanup;
|
||||
}
|
||||
strbuf_release(&buf);
|
||||
|
||||
argv_array_pushl(&diff_files_args, "diff-files",
|
||||
"--ignore-submodules=dirty", "--quiet", "--",
|
||||
path, NULL);
|
||||
|
||||
git_config(git_diff_basic_config, NULL);
|
||||
|
||||
repo_init_revisions(the_repository, &rev, NULL);
|
||||
repo_init_revisions(the_repository, &rev, prefix);
|
||||
rev.abbrev = 0;
|
||||
diff_files_args.argc = setup_revisions(diff_files_args.argc,
|
||||
diff_files_args.argv,
|
||||
|
|
@ -1235,7 +1222,7 @@ static int module_deinit(int argc, const char **argv, const char *prefix)
|
|||
|
||||
static int clone_submodule(const char *path, const char *gitdir, const char *url,
|
||||
const char *depth, struct string_list *reference, int dissociate,
|
||||
int quiet, int progress, int single_branch)
|
||||
int quiet, int progress)
|
||||
{
|
||||
struct child_process cp = CHILD_PROCESS_INIT;
|
||||
|
||||
|
|
@ -1257,10 +1244,6 @@ static int clone_submodule(const char *path, const char *gitdir, const char *url
|
|||
argv_array_push(&cp.args, "--dissociate");
|
||||
if (gitdir && *gitdir)
|
||||
argv_array_pushl(&cp.args, "--separate-git-dir", gitdir, NULL);
|
||||
if (single_branch >= 0)
|
||||
argv_array_push(&cp.args, single_branch ?
|
||||
"--single-branch" :
|
||||
"--no-single-branch");
|
||||
|
||||
argv_array_push(&cp.args, "--");
|
||||
argv_array_push(&cp.args, url);
|
||||
|
|
@ -1285,13 +1268,6 @@ struct submodule_alternate_setup {
|
|||
#define SUBMODULE_ALTERNATE_SETUP_INIT { NULL, \
|
||||
SUBMODULE_ALTERNATE_ERROR_IGNORE, NULL }
|
||||
|
||||
static const char alternate_error_advice[] = N_(
|
||||
"An alternate computed from a superproject's alternate is invalid.\n"
|
||||
"To allow Git to clone without an alternate in such a case, set\n"
|
||||
"submodule.alternateErrorStrategy to 'info' or, equivalently, clone with\n"
|
||||
"'--reference-if-able' instead of '--reference'."
|
||||
);
|
||||
|
||||
static int add_possible_reference_from_superproject(
|
||||
struct object_directory *odb, void *sas_cb)
|
||||
{
|
||||
|
|
@ -1323,8 +1299,6 @@ static int add_possible_reference_from_superproject(
|
|||
} else {
|
||||
switch (sas->error_mode) {
|
||||
case SUBMODULE_ALTERNATE_ERROR_DIE:
|
||||
if (advice_submodule_alternate_error_strategy_die)
|
||||
advise(_(alternate_error_advice));
|
||||
die(_("submodule '%s' cannot add alternate: %s"),
|
||||
sas->submodule_name, err.buf);
|
||||
case SUBMODULE_ALTERNATE_ERROR_INFO:
|
||||
|
|
@ -1385,9 +1359,8 @@ static int module_clone(int argc, const char **argv, const char *prefix)
|
|||
char *p, *path = NULL, *sm_gitdir;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
struct string_list reference = STRING_LIST_INIT_NODUP;
|
||||
int dissociate = 0, require_init = 0;
|
||||
int dissociate = 0;
|
||||
char *sm_alternate = NULL, *error_strategy = NULL;
|
||||
int single_branch = -1;
|
||||
|
||||
struct option module_clone_options[] = {
|
||||
OPT_STRING(0, "prefix", &prefix,
|
||||
|
|
@ -1413,17 +1386,12 @@ static int module_clone(int argc, const char **argv, const char *prefix)
|
|||
OPT__QUIET(&quiet, "Suppress output for cloning a submodule"),
|
||||
OPT_BOOL(0, "progress", &progress,
|
||||
N_("force cloning progress")),
|
||||
OPT_BOOL(0, "require-init", &require_init,
|
||||
N_("disallow cloning into non-empty directory")),
|
||||
OPT_BOOL(0, "single-branch", &single_branch,
|
||||
N_("clone only one branch, HEAD or --branch")),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
const char *const git_submodule_helper_usage[] = {
|
||||
N_("git submodule--helper clone [--prefix=<path>] [--quiet] "
|
||||
"[--reference <repository>] [--name <name>] [--depth <depth>] "
|
||||
"[--single-branch] "
|
||||
"--url <url> --path <path>"),
|
||||
NULL
|
||||
};
|
||||
|
|
@ -1445,10 +1413,6 @@ static int module_clone(int argc, const char **argv, const char *prefix)
|
|||
} else
|
||||
path = xstrdup(path);
|
||||
|
||||
if (validate_submodule_git_dir(sm_gitdir, name) < 0)
|
||||
die(_("refusing to create/use '%s' in another submodule's "
|
||||
"git dir"), sm_gitdir);
|
||||
|
||||
if (!file_exists(sm_gitdir)) {
|
||||
if (safe_create_leading_directories_const(sm_gitdir) < 0)
|
||||
die(_("could not create directory '%s'"), sm_gitdir);
|
||||
|
|
@ -1456,12 +1420,10 @@ static int module_clone(int argc, const char **argv, const char *prefix)
|
|||
prepare_possible_alternates(name, &reference);
|
||||
|
||||
if (clone_submodule(path, sm_gitdir, url, depth, &reference, dissociate,
|
||||
quiet, progress, single_branch))
|
||||
quiet, progress))
|
||||
die(_("clone of '%s' into submodule path '%s' failed"),
|
||||
url, path);
|
||||
} else {
|
||||
if (require_init && !access(path, X_OK) && !is_empty_dir(path))
|
||||
die(_("directory not empty: '%s'"), path);
|
||||
if (safe_create_leading_directories_const(path) < 0)
|
||||
die(_("could not create directory '%s'"), path);
|
||||
strbuf_addf(&sb, "%s/index", sm_gitdir);
|
||||
|
|
@ -1516,8 +1478,6 @@ static void determine_submodule_update_strategy(struct repository *r,
|
|||
die(_("Invalid update mode '%s' configured for submodule path '%s'"),
|
||||
val, path);
|
||||
} else if (sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) {
|
||||
if (sub->update_strategy.type == SM_UPDATE_COMMAND)
|
||||
BUG("how did we read update = !command from .gitmodules?");
|
||||
out->type = sub->update_strategy.type;
|
||||
out->command = sub->update_strategy.command;
|
||||
} else
|
||||
|
|
@ -1576,11 +1536,9 @@ struct submodule_update_clone {
|
|||
int recommend_shallow;
|
||||
struct string_list references;
|
||||
int dissociate;
|
||||
unsigned require_init;
|
||||
const char *depth;
|
||||
const char *recursive_prefix;
|
||||
const char *prefix;
|
||||
int single_branch;
|
||||
|
||||
/* to be consumed by git-submodule.sh */
|
||||
struct update_clone_data *update_clone;
|
||||
|
|
@ -1595,14 +1553,10 @@ struct submodule_update_clone {
|
|||
|
||||
int max_jobs;
|
||||
};
|
||||
#define SUBMODULE_UPDATE_CLONE_INIT { \
|
||||
.list = MODULE_LIST_INIT, \
|
||||
.update = SUBMODULE_UPDATE_STRATEGY_INIT, \
|
||||
.recommend_shallow = -1, \
|
||||
.references = STRING_LIST_INIT_DUP, \
|
||||
.single_branch = -1, \
|
||||
.max_jobs = 1, \
|
||||
}
|
||||
#define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
|
||||
SUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, 0, \
|
||||
NULL, NULL, NULL, \
|
||||
NULL, 0, 0, 0, NULL, 0, 0, 1}
|
||||
|
||||
|
||||
static void next_submodule_warn_missing(struct submodule_update_clone *suc,
|
||||
|
|
@ -1727,8 +1681,6 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
|
|||
argv_array_pushl(&child->args, "--prefix", suc->prefix, NULL);
|
||||
if (suc->recommend_shallow && sub->recommend_shallow == 1)
|
||||
argv_array_push(&child->args, "--depth=1");
|
||||
if (suc->require_init)
|
||||
argv_array_push(&child->args, "--require-init");
|
||||
argv_array_pushl(&child->args, "--path", sub->path, NULL);
|
||||
argv_array_pushl(&child->args, "--name", sub->name, NULL);
|
||||
argv_array_pushl(&child->args, "--url", url, NULL);
|
||||
|
|
@ -1741,10 +1693,6 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
|
|||
argv_array_push(&child->args, "--dissociate");
|
||||
if (suc->depth)
|
||||
argv_array_push(&child->args, suc->depth);
|
||||
if (suc->single_branch >= 0)
|
||||
argv_array_push(&child->args, suc->single_branch ?
|
||||
"--single-branch" :
|
||||
"--no-single-branch");
|
||||
|
||||
cleanup:
|
||||
strbuf_reset(&displaypath_sb);
|
||||
|
|
@ -1922,15 +1870,11 @@ static int update_clone(int argc, const char **argv, const char *prefix)
|
|||
OPT__QUIET(&suc.quiet, N_("don't print cloning progress")),
|
||||
OPT_BOOL(0, "progress", &suc.progress,
|
||||
N_("force cloning progress")),
|
||||
OPT_BOOL(0, "require-init", &suc.require_init,
|
||||
N_("disallow cloning into non-empty directory")),
|
||||
OPT_BOOL(0, "single-branch", &suc.single_branch,
|
||||
N_("clone only one branch, HEAD or --branch")),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
const char *const git_submodule_helper_usage[] = {
|
||||
N_("git submodule--helper update-clone [--prefix=<path>] [<path>...]"),
|
||||
N_("git submodule--helper update_clone [--prefix=<path>] [<path>...]"),
|
||||
NULL
|
||||
};
|
||||
suc.prefix = prefix;
|
||||
|
|
|
|||
6
third_party/git/builtin/unpack-objects.c
vendored
6
third_party/git/builtin/unpack-objects.c
vendored
|
|
@ -24,7 +24,6 @@ static off_t consumed_bytes;
|
|||
static off_t max_input_size;
|
||||
static git_hash_ctx ctx;
|
||||
static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
|
||||
static struct progress *progress;
|
||||
|
||||
/*
|
||||
* When running under --strict mode, objects whose reachability are
|
||||
|
|
@ -93,7 +92,6 @@ static void use(int bytes)
|
|||
consumed_bytes += bytes;
|
||||
if (max_input_size && consumed_bytes > max_input_size)
|
||||
die(_("pack exceeds maximum allowed size"));
|
||||
display_throughput(progress, consumed_bytes);
|
||||
}
|
||||
|
||||
static void *get_data(unsigned long size)
|
||||
|
|
@ -265,8 +263,7 @@ static void write_object(unsigned nr, enum object_type type,
|
|||
} else {
|
||||
struct object *obj;
|
||||
int eaten;
|
||||
hash_object_file(the_hash_algo, buf, size, type_name(type),
|
||||
&obj_list[nr].oid);
|
||||
hash_object_file(buf, size, type_name(type), &obj_list[nr].oid);
|
||||
added_object(nr, type, buf, size);
|
||||
obj = parse_object_buffer(the_repository, &obj_list[nr].oid,
|
||||
type, size, buf,
|
||||
|
|
@ -487,6 +484,7 @@ static void unpack_one(unsigned nr)
|
|||
static void unpack_all(void)
|
||||
{
|
||||
int i;
|
||||
struct progress *progress = NULL;
|
||||
struct pack_header *hdr = fill(sizeof(struct pack_header));
|
||||
|
||||
nr_objects = ntohl(hdr->hdr_entries);
|
||||
|
|
|
|||
12
third_party/git/builtin/update-index.c
vendored
12
third_party/git/builtin/update-index.c
vendored
|
|
@ -35,7 +35,6 @@ static int verbose;
|
|||
static int mark_valid_only;
|
||||
static int mark_skip_worktree_only;
|
||||
static int mark_fsmonitor_only;
|
||||
static int ignore_skip_worktree_entries;
|
||||
#define MARK_FLAG 1
|
||||
#define UNMARK_FLAG 2
|
||||
static struct strbuf mtime_dir = STRBUF_INIT;
|
||||
|
|
@ -382,8 +381,7 @@ static int process_path(const char *path, struct stat *st, int stat_errno)
|
|||
* so updating it does not make sense.
|
||||
* On the other hand, removing it from index should work
|
||||
*/
|
||||
if (!ignore_skip_worktree_entries && allow_remove &&
|
||||
remove_file_from_cache(path))
|
||||
if (allow_remove && remove_file_from_cache(path))
|
||||
return error("%s: cannot remove from the index", path);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -968,7 +966,6 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
|
|||
struct parse_opt_ctx_t ctx;
|
||||
strbuf_getline_fn getline_fn;
|
||||
int parseopt_state = PARSE_OPT_UNKNOWN;
|
||||
struct repository *r = the_repository;
|
||||
struct option options[] = {
|
||||
OPT_BIT('q', NULL, &refresh_args.flags,
|
||||
N_("continue refresh even when index needs update"),
|
||||
|
|
@ -1016,8 +1013,6 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
|
|||
{OPTION_SET_INT, 0, "no-skip-worktree", &mark_skip_worktree_only, NULL,
|
||||
N_("clear skip-worktree bit"),
|
||||
PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, UNMARK_FLAG},
|
||||
OPT_BOOL(0, "ignore-skip-worktree-entries", &ignore_skip_worktree_entries,
|
||||
N_("do not touch index-only entries")),
|
||||
OPT_SET_INT(0, "info-only", &info_only,
|
||||
N_("add to index only; do not add content to object database"), 1),
|
||||
OPT_SET_INT(0, "force-remove", &force_remove,
|
||||
|
|
@ -1185,12 +1180,11 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
|
|||
remove_split_index(&the_index);
|
||||
}
|
||||
|
||||
prepare_repo_settings(r);
|
||||
switch (untracked_cache) {
|
||||
case UC_UNSPECIFIED:
|
||||
break;
|
||||
case UC_DISABLE:
|
||||
if (r->settings.core_untracked_cache == UNTRACKED_CACHE_WRITE)
|
||||
if (git_config_get_untracked_cache() == 1)
|
||||
warning(_("core.untrackedCache is set to true; "
|
||||
"remove or change it, if you really want to "
|
||||
"disable the untracked cache"));
|
||||
|
|
@ -1202,7 +1196,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
|
|||
return !test_if_untracked_cache_is_supported();
|
||||
case UC_ENABLE:
|
||||
case UC_FORCE:
|
||||
if (r->settings.core_untracked_cache == UNTRACKED_CACHE_REMOVE)
|
||||
if (git_config_get_untracked_cache() == 0)
|
||||
warning(_("core.untrackedCache is set to false; "
|
||||
"remove or change it, if you really want to "
|
||||
"enable the untracked cache"));
|
||||
|
|
|
|||
16
third_party/git/builtin/worktree.c
vendored
16
third_party/git/builtin/worktree.c
vendored
|
|
@ -10,6 +10,7 @@
|
|||
#include "run-command.h"
|
||||
#include "sigchain.h"
|
||||
#include "submodule.h"
|
||||
#include "refs.h"
|
||||
#include "utf8.h"
|
||||
#include "worktree.h"
|
||||
|
||||
|
|
@ -234,7 +235,14 @@ static void validate_worktree_add(const char *path, const struct add_opts *opts)
|
|||
die(_("'%s' already exists"), path);
|
||||
|
||||
worktrees = get_worktrees(0);
|
||||
wt = find_worktree_by_path(worktrees, path);
|
||||
/*
|
||||
* find_worktree()'s suffix matching may undesirably find the main
|
||||
* rather than a linked worktree (for instance, when the basenames
|
||||
* of the main worktree and the one being created are the same).
|
||||
* We're only interested in linked worktrees, so skip the main
|
||||
* worktree with +1.
|
||||
*/
|
||||
wt = find_worktree(worktrees + 1, NULL, path);
|
||||
if (!wt)
|
||||
goto done;
|
||||
|
||||
|
|
@ -342,7 +350,7 @@ static int add_worktree(const char *path, const char *refname,
|
|||
*/
|
||||
strbuf_reset(&sb);
|
||||
strbuf_addf(&sb, "%s/HEAD", sb_repo.buf);
|
||||
write_file(sb.buf, "%s", oid_to_hex(&null_oid));
|
||||
write_file(sb.buf, "%s", sha1_to_hex(null_sha1));
|
||||
strbuf_reset(&sb);
|
||||
strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
|
||||
write_file(sb.buf, "../..");
|
||||
|
|
@ -369,7 +377,7 @@ static int add_worktree(const char *path, const char *refname,
|
|||
if (opts->checkout) {
|
||||
cp.argv = NULL;
|
||||
argv_array_clear(&cp.args);
|
||||
argv_array_pushl(&cp.args, "reset", "--hard", "--no-recurse-submodules", NULL);
|
||||
argv_array_pushl(&cp.args, "reset", "--hard", NULL);
|
||||
if (opts->quiet)
|
||||
argv_array_push(&cp.args, "--quiet");
|
||||
cp.env = child_env.argv;
|
||||
|
|
@ -872,7 +880,7 @@ static void check_clean_worktree(struct worktree *wt,
|
|||
original_path);
|
||||
ret = xread(cp.out, buf, sizeof(buf));
|
||||
if (ret)
|
||||
die(_("'%s' contains modified or untracked files, use --force to delete it"),
|
||||
die(_("'%s' is dirty, use --force to delete it"),
|
||||
original_path);
|
||||
close(cp.out);
|
||||
ret = finish_command(&cp);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue