Merge 'jk/git-path' into kn/for-each-tag
* jk/git-path: memoize common git-path "constant" files get_repo_path: refactor path-allocation find_hook: keep our own static buffer refs.c: remove_empty_directories can take a strbuf refs.c: avoid git_path assignment in lock_ref_sha1_basic refs.c: avoid repeated git_path calls in rename_tmp_log refs.c: simplify strbufs in reflog setup and writing path.c: drop git_path_submodule refs.c: remove extra git_path calls from read_loose_refs remote.c: drop extraneous local variable from migrate_file prefer mkpathdup to mkpath in assignments prefer git_pathdup to git_path in some possibly-dangerous cases add_to_alternates_file: don't add duplicate entries t5700: modernize style cache.h: complete set of git_path_submodule helpers cache.h: clarify documentation for git_path, et al
This commit is contained in:
commit
7b8419f094
4
attr.c
4
attr.c
@ -490,6 +490,8 @@ static int git_attr_system(void)
|
||||
return !git_env_bool("GIT_ATTR_NOSYSTEM", 0);
|
||||
}
|
||||
|
||||
static GIT_PATH_FUNC(git_path_info_attributes, INFOATTRIBUTES_FILE)
|
||||
|
||||
static void bootstrap_attr_stack(void)
|
||||
{
|
||||
struct attr_stack *elem;
|
||||
@ -531,7 +533,7 @@ static void bootstrap_attr_stack(void)
|
||||
debug_push(elem);
|
||||
}
|
||||
|
||||
elem = read_attr_from_file(git_path(INFOATTRIBUTES_FILE), 1);
|
||||
elem = read_attr_from_file(git_path_info_attributes(), 1);
|
||||
if (!elem)
|
||||
elem = xcalloc(1, sizeof(*elem));
|
||||
elem->origin = NULL;
|
||||
|
7
bisect.c
7
bisect.c
@ -420,10 +420,13 @@ static int read_bisect_refs(void)
|
||||
return for_each_ref_in("refs/bisect/", register_ref, NULL);
|
||||
}
|
||||
|
||||
static GIT_PATH_FUNC(git_path_bisect_names, "BISECT_NAMES")
|
||||
static GIT_PATH_FUNC(git_path_bisect_expected_rev, "BISECT_EXPECTED_REV")
|
||||
|
||||
static void read_bisect_paths(struct argv_array *array)
|
||||
{
|
||||
struct strbuf str = STRBUF_INIT;
|
||||
const char *filename = git_path("BISECT_NAMES");
|
||||
const char *filename = git_path_bisect_names();
|
||||
FILE *fp = fopen(filename, "r");
|
||||
|
||||
if (!fp)
|
||||
@ -644,7 +647,7 @@ static void exit_if_skipped_commits(struct commit_list *tried,
|
||||
|
||||
static int is_expected_rev(const struct object_id *oid)
|
||||
{
|
||||
const char *filename = git_path("BISECT_EXPECTED_REV");
|
||||
const char *filename = git_path_bisect_expected_rev();
|
||||
struct stat st;
|
||||
struct strbuf str = STRBUF_INIT;
|
||||
FILE *fp;
|
||||
|
14
branch.c
14
branch.c
@ -302,11 +302,11 @@ void create_branch(const char *head,
|
||||
|
||||
void remove_branch_state(void)
|
||||
{
|
||||
unlink(git_path("CHERRY_PICK_HEAD"));
|
||||
unlink(git_path("REVERT_HEAD"));
|
||||
unlink(git_path("MERGE_HEAD"));
|
||||
unlink(git_path("MERGE_RR"));
|
||||
unlink(git_path("MERGE_MSG"));
|
||||
unlink(git_path("MERGE_MODE"));
|
||||
unlink(git_path("SQUASH_MSG"));
|
||||
unlink(git_path_cherry_pick_head());
|
||||
unlink(git_path_revert_head());
|
||||
unlink(git_path_merge_head());
|
||||
unlink(git_path_merge_rr());
|
||||
unlink(git_path_merge_msg());
|
||||
unlink(git_path_merge_mode());
|
||||
unlink(git_path_squash_msg());
|
||||
}
|
||||
|
@ -2227,20 +2227,19 @@ static struct commit_list **append_parent(struct commit_list **tail, const unsig
|
||||
static void append_merge_parents(struct commit_list **tail)
|
||||
{
|
||||
int merge_head;
|
||||
const char *merge_head_file = git_path("MERGE_HEAD");
|
||||
struct strbuf line = STRBUF_INIT;
|
||||
|
||||
merge_head = open(merge_head_file, O_RDONLY);
|
||||
merge_head = open(git_path_merge_head(), O_RDONLY);
|
||||
if (merge_head < 0) {
|
||||
if (errno == ENOENT)
|
||||
return;
|
||||
die("cannot open '%s' for reading", merge_head_file);
|
||||
die("cannot open '%s' for reading", git_path_merge_head());
|
||||
}
|
||||
|
||||
while (!strbuf_getwholeline_fd(&line, merge_head, '\n')) {
|
||||
unsigned char sha1[20];
|
||||
if (line.len < 40 || get_sha1_hex(line.buf, sha1))
|
||||
die("unknown line in '%s': %s", merge_head_file, line.buf);
|
||||
die("unknown line in '%s': %s", git_path_merge_head(), line.buf);
|
||||
tail = append_parent(tail, sha1);
|
||||
}
|
||||
close(merge_head);
|
||||
|
@ -99,51 +99,66 @@ static const char *argv_submodule[] = {
|
||||
"submodule", "update", "--init", "--recursive", NULL
|
||||
};
|
||||
|
||||
static char *get_repo_path(const char *repo, int *is_bundle)
|
||||
static const char *get_repo_path_1(struct strbuf *path, int *is_bundle)
|
||||
{
|
||||
static char *suffix[] = { "/.git", "", ".git/.git", ".git" };
|
||||
static char *bundle_suffix[] = { ".bundle", "" };
|
||||
size_t baselen = path->len;
|
||||
struct stat st;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(suffix); i++) {
|
||||
const char *path;
|
||||
path = mkpath("%s%s", repo, suffix[i]);
|
||||
if (stat(path, &st))
|
||||
strbuf_setlen(path, baselen);
|
||||
strbuf_addstr(path, suffix[i]);
|
||||
if (stat(path->buf, &st))
|
||||
continue;
|
||||
if (S_ISDIR(st.st_mode) && is_git_directory(path)) {
|
||||
if (S_ISDIR(st.st_mode) && is_git_directory(path->buf)) {
|
||||
*is_bundle = 0;
|
||||
return xstrdup(absolute_path(path));
|
||||
return path->buf;
|
||||
} else if (S_ISREG(st.st_mode) && st.st_size > 8) {
|
||||
/* Is it a "gitfile"? */
|
||||
char signature[8];
|
||||
int len, fd = open(path, O_RDONLY);
|
||||
const char *dst;
|
||||
int len, fd = open(path->buf, O_RDONLY);
|
||||
if (fd < 0)
|
||||
continue;
|
||||
len = read_in_full(fd, signature, 8);
|
||||
close(fd);
|
||||
if (len != 8 || strncmp(signature, "gitdir: ", 8))
|
||||
continue;
|
||||
path = read_gitfile(path);
|
||||
if (path) {
|
||||
dst = read_gitfile(path->buf);
|
||||
if (dst) {
|
||||
*is_bundle = 0;
|
||||
return xstrdup(absolute_path(path));
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bundle_suffix); i++) {
|
||||
const char *path;
|
||||
path = mkpath("%s%s", repo, bundle_suffix[i]);
|
||||
if (!stat(path, &st) && S_ISREG(st.st_mode)) {
|
||||
strbuf_setlen(path, baselen);
|
||||
strbuf_addstr(path, bundle_suffix[i]);
|
||||
if (!stat(path->buf, &st) && S_ISREG(st.st_mode)) {
|
||||
*is_bundle = 1;
|
||||
return xstrdup(absolute_path(path));
|
||||
return path->buf;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *get_repo_path(const char *repo, int *is_bundle)
|
||||
{
|
||||
struct strbuf path = STRBUF_INIT;
|
||||
const char *raw;
|
||||
char *canon;
|
||||
|
||||
strbuf_addstr(&path, repo);
|
||||
raw = get_repo_path_1(&path, is_bundle);
|
||||
canon = raw ? xstrdup(absolute_path(raw)) : NULL;
|
||||
strbuf_release(&path);
|
||||
return canon;
|
||||
}
|
||||
|
||||
static char *guess_dir_name(const char *repo, int is_bundle, int is_bare)
|
||||
{
|
||||
const char *end = repo + strlen(repo), *start;
|
||||
|
@ -166,9 +166,9 @@ static int opt_parse_m(const struct option *opt, const char *arg, int unset)
|
||||
|
||||
static void determine_whence(struct wt_status *s)
|
||||
{
|
||||
if (file_exists(git_path("MERGE_HEAD")))
|
||||
if (file_exists(git_path_merge_head()))
|
||||
whence = FROM_MERGE;
|
||||
else if (file_exists(git_path("CHERRY_PICK_HEAD"))) {
|
||||
else if (file_exists(git_path_cherry_pick_head())) {
|
||||
whence = FROM_CHERRY_PICK;
|
||||
if (file_exists(git_path(SEQ_DIR)))
|
||||
sequencer_in_use = 1;
|
||||
@ -725,12 +725,12 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
|
||||
format_commit_message(commit, "fixup! %s\n\n",
|
||||
&sb, &ctx);
|
||||
hook_arg1 = "message";
|
||||
} else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
|
||||
if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
|
||||
} else if (!stat(git_path_merge_msg(), &statbuf)) {
|
||||
if (strbuf_read_file(&sb, git_path_merge_msg(), 0) < 0)
|
||||
die_errno(_("could not read MERGE_MSG"));
|
||||
hook_arg1 = "merge";
|
||||
} else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
|
||||
if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
|
||||
} else if (!stat(git_path_squash_msg(), &statbuf)) {
|
||||
if (strbuf_read_file(&sb, git_path_squash_msg(), 0) < 0)
|
||||
die_errno(_("could not read SQUASH_MSG"));
|
||||
hook_arg1 = "squash";
|
||||
} else if (template_file) {
|
||||
@ -1684,10 +1684,10 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
if (!reflog_msg)
|
||||
reflog_msg = "commit (merge)";
|
||||
pptr = &commit_list_insert(current_head, pptr)->next;
|
||||
fp = fopen(git_path("MERGE_HEAD"), "r");
|
||||
fp = fopen(git_path_merge_head(), "r");
|
||||
if (fp == NULL)
|
||||
die_errno(_("could not open '%s' for reading"),
|
||||
git_path("MERGE_HEAD"));
|
||||
git_path_merge_head());
|
||||
while (strbuf_getline(&m, fp, '\n') != EOF) {
|
||||
struct commit *parent;
|
||||
|
||||
@ -1698,8 +1698,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
fclose(fp);
|
||||
strbuf_release(&m);
|
||||
if (!stat(git_path("MERGE_MODE"), &statbuf)) {
|
||||
if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
|
||||
if (!stat(git_path_merge_mode(), &statbuf)) {
|
||||
if (strbuf_read_file(&sb, git_path_merge_mode(), 0) < 0)
|
||||
die_errno(_("could not read MERGE_MODE"));
|
||||
if (!strcmp(sb.buf, "no-ff"))
|
||||
allow_fast_forward = 0;
|
||||
@ -1775,12 +1775,12 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
ref_transaction_free(transaction);
|
||||
|
||||
unlink(git_path("CHERRY_PICK_HEAD"));
|
||||
unlink(git_path("REVERT_HEAD"));
|
||||
unlink(git_path("MERGE_HEAD"));
|
||||
unlink(git_path("MERGE_MSG"));
|
||||
unlink(git_path("MERGE_MODE"));
|
||||
unlink(git_path("SQUASH_MSG"));
|
||||
unlink(git_path_cherry_pick_head());
|
||||
unlink(git_path_revert_head());
|
||||
unlink(git_path_merge_head());
|
||||
unlink(git_path_merge_msg());
|
||||
unlink(git_path_merge_mode());
|
||||
unlink(git_path_squash_msg());
|
||||
|
||||
if (commit_index_files())
|
||||
die (_("Repository has been updated, but unable to write\n"
|
||||
|
@ -591,7 +591,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
|
||||
const char *what, *kind;
|
||||
struct ref *rm;
|
||||
char *url;
|
||||
const char *filename = dry_run ? "/dev/null" : git_path("FETCH_HEAD");
|
||||
const char *filename = dry_run ? "/dev/null" : git_path_fetch_head();
|
||||
int want_status;
|
||||
|
||||
fp = fopen(filename, "a");
|
||||
@ -834,7 +834,7 @@ static void check_not_current_branch(struct ref *ref_map)
|
||||
|
||||
static int truncate_fetch_head(void)
|
||||
{
|
||||
const char *filename = git_path("FETCH_HEAD");
|
||||
const char *filename = git_path_fetch_head();
|
||||
FILE *fp = fopen(filename, "w");
|
||||
|
||||
if (!fp)
|
||||
|
@ -243,13 +243,14 @@ static void check_unreachable_object(struct object *obj)
|
||||
printf("dangling %s %s\n", typename(obj->type),
|
||||
sha1_to_hex(obj->sha1));
|
||||
if (write_lost_and_found) {
|
||||
const char *filename = git_path("lost-found/%s/%s",
|
||||
char *filename = git_pathdup("lost-found/%s/%s",
|
||||
obj->type == OBJ_COMMIT ? "commit" : "other",
|
||||
sha1_to_hex(obj->sha1));
|
||||
FILE *f;
|
||||
|
||||
if (safe_create_leading_directories_const(filename)) {
|
||||
error("Could not create lost-found");
|
||||
free(filename);
|
||||
return;
|
||||
}
|
||||
if (!(f = fopen(filename, "w")))
|
||||
@ -262,6 +263,7 @@ static void check_unreachable_object(struct object *obj)
|
||||
if (fclose(f))
|
||||
die_errno("Could not finish '%s'",
|
||||
filename);
|
||||
free(filename);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -231,9 +231,9 @@ static struct option builtin_merge_options[] = {
|
||||
/* Cleans up metadata that is uninteresting after a succeeded merge. */
|
||||
static void drop_save(void)
|
||||
{
|
||||
unlink(git_path("MERGE_HEAD"));
|
||||
unlink(git_path("MERGE_MSG"));
|
||||
unlink(git_path("MERGE_MODE"));
|
||||
unlink(git_path_merge_head());
|
||||
unlink(git_path_merge_msg());
|
||||
unlink(git_path_merge_mode());
|
||||
}
|
||||
|
||||
static int save_state(unsigned char *stash)
|
||||
@ -338,7 +338,7 @@ static void squash_message(struct commit *commit, struct commit_list *remotehead
|
||||
struct pretty_print_context ctx = {0};
|
||||
|
||||
printf(_("Squash commit -- not updating HEAD\n"));
|
||||
filename = git_path("SQUASH_MSG");
|
||||
filename = git_path_squash_msg();
|
||||
fd = open(filename, O_WRONLY | O_CREAT, 0666);
|
||||
if (fd < 0)
|
||||
die_errno(_("Could not write to '%s'"), filename);
|
||||
@ -754,7 +754,7 @@ static void add_strategies(const char *string, unsigned attr)
|
||||
|
||||
static void write_merge_msg(struct strbuf *msg)
|
||||
{
|
||||
const char *filename = git_path("MERGE_MSG");
|
||||
const char *filename = git_path_merge_msg();
|
||||
int fd = open(filename, O_WRONLY | O_CREAT, 0666);
|
||||
if (fd < 0)
|
||||
die_errno(_("Could not open '%s' for writing"),
|
||||
@ -766,7 +766,7 @@ static void write_merge_msg(struct strbuf *msg)
|
||||
|
||||
static void read_merge_msg(struct strbuf *msg)
|
||||
{
|
||||
const char *filename = git_path("MERGE_MSG");
|
||||
const char *filename = git_path_merge_msg();
|
||||
strbuf_reset(msg);
|
||||
if (strbuf_read_file(msg, filename, 0) < 0)
|
||||
die_errno(_("Could not read from '%s'"), filename);
|
||||
@ -799,10 +799,10 @@ static void prepare_to_commit(struct commit_list *remoteheads)
|
||||
strbuf_commented_addf(&msg, _(merge_editor_comment), comment_line_char);
|
||||
write_merge_msg(&msg);
|
||||
if (run_commit_hook(0 < option_edit, get_index_file(), "prepare-commit-msg",
|
||||
git_path("MERGE_MSG"), "merge", NULL))
|
||||
git_path_merge_msg(), "merge", NULL))
|
||||
abort_commit(remoteheads, NULL);
|
||||
if (0 < option_edit) {
|
||||
if (launch_editor(git_path("MERGE_MSG"), NULL, NULL))
|
||||
if (launch_editor(git_path_merge_msg(), NULL, NULL))
|
||||
abort_commit(remoteheads, NULL);
|
||||
}
|
||||
read_merge_msg(&msg);
|
||||
@ -865,7 +865,7 @@ static int suggest_conflicts(void)
|
||||
FILE *fp;
|
||||
struct strbuf msgbuf = STRBUF_INIT;
|
||||
|
||||
filename = git_path("MERGE_MSG");
|
||||
filename = git_path_merge_msg();
|
||||
fp = fopen(filename, "a");
|
||||
if (!fp)
|
||||
die_errno(_("Could not open '%s' for writing"), filename);
|
||||
@ -967,7 +967,7 @@ static void write_merge_state(struct commit_list *remoteheads)
|
||||
}
|
||||
strbuf_addf(&buf, "%s\n", sha1_to_hex(sha1));
|
||||
}
|
||||
filename = git_path("MERGE_HEAD");
|
||||
filename = git_path_merge_head();
|
||||
fd = open(filename, O_WRONLY | O_CREAT, 0666);
|
||||
if (fd < 0)
|
||||
die_errno(_("Could not open '%s' for writing"), filename);
|
||||
@ -977,7 +977,7 @@ static void write_merge_state(struct commit_list *remoteheads)
|
||||
strbuf_addch(&merge_msg, '\n');
|
||||
write_merge_msg(&merge_msg);
|
||||
|
||||
filename = git_path("MERGE_MODE");
|
||||
filename = git_path_merge_mode();
|
||||
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (fd < 0)
|
||||
die_errno(_("Could not open '%s' for writing"), filename);
|
||||
@ -1070,7 +1070,7 @@ static void handle_fetch_head(struct commit_list **remotes, struct strbuf *merge
|
||||
if (!merge_names)
|
||||
merge_names = &fetch_head_file;
|
||||
|
||||
filename = git_path("FETCH_HEAD");
|
||||
filename = git_path_fetch_head();
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
die_errno(_("could not open '%s' for reading"), filename);
|
||||
@ -1204,7 +1204,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
int nargc = 2;
|
||||
const char *nargv[] = {"reset", "--merge", NULL};
|
||||
|
||||
if (!file_exists(git_path("MERGE_HEAD")))
|
||||
if (!file_exists(git_path_merge_head()))
|
||||
die(_("There is no merge to abort (MERGE_HEAD missing)."));
|
||||
|
||||
/* Invoke 'git reset --merge' */
|
||||
@ -1215,7 +1215,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
if (read_cache_unmerged())
|
||||
die_resolve_conflict("merge");
|
||||
|
||||
if (file_exists(git_path("MERGE_HEAD"))) {
|
||||
if (file_exists(git_path_merge_head())) {
|
||||
/*
|
||||
* There is no unmerged entry, don't advise 'git
|
||||
* add/rm <file>', just 'git commit'.
|
||||
@ -1226,7 +1226,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
|
||||
else
|
||||
die(_("You have not concluded your merge (MERGE_HEAD exists)."));
|
||||
}
|
||||
if (file_exists(git_path("CHERRY_PICK_HEAD"))) {
|
||||
if (file_exists(git_path_cherry_pick_head())) {
|
||||
if (advice_resolve_conflict)
|
||||
die(_("You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
|
||||
"Please, commit your changes before you merge."));
|
||||
|
@ -581,7 +581,6 @@ static int migrate_file(struct remote *remote)
|
||||
{
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
int i;
|
||||
const char *path = NULL;
|
||||
|
||||
strbuf_addf(&buf, "remote.%s.url", remote->name);
|
||||
for (i = 0; i < remote->url_nr; i++)
|
||||
@ -601,11 +600,9 @@ static int migrate_file(struct remote *remote)
|
||||
return error(_("Could not append '%s' to '%s'"),
|
||||
remote->fetch_refspec[i], buf.buf);
|
||||
if (remote->origin == REMOTE_REMOTES)
|
||||
path = git_path("remotes/%s", remote->name);
|
||||
unlink_or_warn(git_path("remotes/%s", remote->name));
|
||||
else if (remote->origin == REMOTE_BRANCHES)
|
||||
path = git_path("branches/%s", remote->name);
|
||||
if (path)
|
||||
unlink_or_warn(path);
|
||||
unlink_or_warn(git_path("branches/%s", remote->name));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -285,8 +285,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
|
||||
failed = 0;
|
||||
for_each_string_list_item(item, &names) {
|
||||
for (ext = 0; ext < ARRAY_SIZE(exts); ext++) {
|
||||
const char *fname_old;
|
||||
char *fname;
|
||||
char *fname, *fname_old;
|
||||
fname = mkpathdup("%s/pack-%s%s", packdir,
|
||||
item->string, exts[ext].name);
|
||||
if (!file_exists(fname)) {
|
||||
@ -294,7 +293,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
|
||||
continue;
|
||||
}
|
||||
|
||||
fname_old = mkpath("%s/old-%s%s", packdir,
|
||||
fname_old = mkpathdup("%s/old-%s%s", packdir,
|
||||
item->string, exts[ext].name);
|
||||
if (file_exists(fname_old))
|
||||
if (unlink(fname_old))
|
||||
@ -302,10 +301,12 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
|
||||
|
||||
if (!failed && rename(fname, fname_old)) {
|
||||
free(fname);
|
||||
free(fname_old);
|
||||
failed = 1;
|
||||
break;
|
||||
} else {
|
||||
string_list_append(&rollback, fname);
|
||||
free(fname_old);
|
||||
}
|
||||
}
|
||||
if (failed)
|
||||
@ -314,13 +315,13 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
|
||||
if (failed) {
|
||||
struct string_list rollback_failure = STRING_LIST_INIT_DUP;
|
||||
for_each_string_list_item(item, &rollback) {
|
||||
const char *fname_old;
|
||||
char *fname;
|
||||
char *fname, *fname_old;
|
||||
fname = mkpathdup("%s/%s", packdir, item->string);
|
||||
fname_old = mkpath("%s/old-%s", packdir, item->string);
|
||||
fname_old = mkpathdup("%s/old-%s", packdir, item->string);
|
||||
if (rename(fname_old, fname))
|
||||
string_list_append(&rollback_failure, fname);
|
||||
free(fname);
|
||||
free(fname_old);
|
||||
}
|
||||
|
||||
if (rollback_failure.nr) {
|
||||
@ -368,13 +369,14 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
|
||||
/* Remove the "old-" files */
|
||||
for_each_string_list_item(item, &names) {
|
||||
for (ext = 0; ext < ARRAY_SIZE(exts); ext++) {
|
||||
const char *fname;
|
||||
fname = mkpath("%s/old-%s%s",
|
||||
packdir,
|
||||
item->string,
|
||||
exts[ext].name);
|
||||
char *fname;
|
||||
fname = mkpathdup("%s/old-%s%s",
|
||||
packdir,
|
||||
item->string,
|
||||
exts[ext].name);
|
||||
if (remove_path(fname))
|
||||
warning(_("removing '%s' failed"), fname);
|
||||
free(fname);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ static const char *reset_type_names[] = {
|
||||
|
||||
static inline int is_merge(void)
|
||||
{
|
||||
return !access(git_path("MERGE_HEAD"), F_OK);
|
||||
return !access(git_path_merge_head(), F_OK);
|
||||
}
|
||||
|
||||
static int reset_index(const unsigned char *sha1, int reset_type, int quiet)
|
||||
|
47
cache.h
47
cache.h
@ -708,22 +708,59 @@ extern int check_repository_format(void);
|
||||
#define DATA_CHANGED 0x0020
|
||||
#define TYPE_CHANGED 0x0040
|
||||
|
||||
/*
|
||||
* Return a statically allocated filename, either generically (mkpath), in
|
||||
* the repository directory (git_path), or in a submodule's repository
|
||||
* directory (git_path_submodule). In all cases, note that the result
|
||||
* may be overwritten by another call to _any_ of the functions. Consider
|
||||
* using the safer "dup" or "strbuf" formats below (in some cases, the
|
||||
* unsafe versions have already been removed).
|
||||
*/
|
||||
extern const char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
|
||||
extern const char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
|
||||
|
||||
extern char *mksnpath(char *buf, size_t n, const char *fmt, ...)
|
||||
__attribute__((format (printf, 3, 4)));
|
||||
extern void strbuf_git_path(struct strbuf *sb, const char *fmt, ...)
|
||||
__attribute__((format (printf, 2, 3)));
|
||||
extern void strbuf_git_path_submodule(struct strbuf *sb, const char *path,
|
||||
const char *fmt, ...)
|
||||
__attribute__((format (printf, 3, 4)));
|
||||
extern char *git_pathdup(const char *fmt, ...)
|
||||
__attribute__((format (printf, 1, 2)));
|
||||
extern char *mkpathdup(const char *fmt, ...)
|
||||
__attribute__((format (printf, 1, 2)));
|
||||
|
||||
/* Return a statically allocated filename matching the sha1 signature */
|
||||
extern const char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
|
||||
extern const char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
|
||||
extern const char *git_path_submodule(const char *path, const char *fmt, ...)
|
||||
extern char *git_pathdup_submodule(const char *path, const char *fmt, ...)
|
||||
__attribute__((format (printf, 2, 3)));
|
||||
|
||||
extern void report_linked_checkout_garbage(void);
|
||||
|
||||
/*
|
||||
* You can define a static memoized git path like:
|
||||
*
|
||||
* static GIT_PATH_FUNC(git_path_foo, "FOO");
|
||||
*
|
||||
* or use one of the global ones below.
|
||||
*/
|
||||
#define GIT_PATH_FUNC(func, filename) \
|
||||
const char *func(void) \
|
||||
{ \
|
||||
static char *ret; \
|
||||
if (!ret) \
|
||||
ret = git_pathdup(filename); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
const char *git_path_cherry_pick_head(void);
|
||||
const char *git_path_revert_head(void);
|
||||
const char *git_path_squash_msg(void);
|
||||
const char *git_path_merge_msg(void);
|
||||
const char *git_path_merge_rr(void);
|
||||
const char *git_path_merge_mode(void);
|
||||
const char *git_path_merge_head(void);
|
||||
const char *git_path_fetch_head(void);
|
||||
const char *git_path_shallow(void);
|
||||
|
||||
/*
|
||||
* Return the name of the file in the local object database that would
|
||||
* be used to store a loose object with the specified sha1. The
|
||||
|
@ -516,7 +516,7 @@ int cmd_fetch__tool(int argc, const char **argv, const char *prefix)
|
||||
|
||||
if (argc != 8)
|
||||
return error("append-fetch-head takes 6 args");
|
||||
filename = git_path("FETCH_HEAD");
|
||||
filename = git_path_fetch_head();
|
||||
fp = fopen(filename, "a");
|
||||
if (!fp)
|
||||
return error("cannot open %s: %s", filename, strerror(errno));
|
||||
@ -534,7 +534,7 @@ int cmd_fetch__tool(int argc, const char **argv, const char *prefix)
|
||||
|
||||
if (argc != 5)
|
||||
return error("fetch-native-store takes 3 args");
|
||||
filename = git_path("FETCH_HEAD");
|
||||
filename = git_path_fetch_head();
|
||||
fp = fopen(filename, "a");
|
||||
if (!fp)
|
||||
return error("cannot open %s: %s", filename, strerror(errno));
|
||||
|
4
dir.c
4
dir.c
@ -2185,6 +2185,8 @@ int remove_dir_recursively(struct strbuf *path, int flag)
|
||||
return remove_dir_recurse(path, flag, NULL);
|
||||
}
|
||||
|
||||
static GIT_PATH_FUNC(git_path_info_exclude, "info/exclude")
|
||||
|
||||
void setup_standard_excludes(struct dir_struct *dir)
|
||||
{
|
||||
const char *path;
|
||||
@ -2199,7 +2201,7 @@ void setup_standard_excludes(struct dir_struct *dir)
|
||||
dir->untracked ? &dir->ss_excludes_file : NULL);
|
||||
|
||||
/* per repository user preference */
|
||||
path = git_path("info/exclude");
|
||||
path = git_path_info_exclude();
|
||||
if (!access_or_warn(path, R_OK, 0))
|
||||
add_excludes_from_file_1(dir, path,
|
||||
dir->untracked ? &dir->ss_info_exclude : NULL);
|
||||
|
@ -407,7 +407,7 @@ static void dump_marks_helper(FILE *, uintmax_t, struct mark_set *);
|
||||
|
||||
static void write_crash_report(const char *err)
|
||||
{
|
||||
const char *loc = git_path("fast_import_crash_%"PRIuMAX, (uintmax_t) getpid());
|
||||
char *loc = git_pathdup("fast_import_crash_%"PRIuMAX, (uintmax_t) getpid());
|
||||
FILE *rpt = fopen(loc, "w");
|
||||
struct branch *b;
|
||||
unsigned long lu;
|
||||
@ -415,6 +415,7 @@ static void write_crash_report(const char *err)
|
||||
|
||||
if (!rpt) {
|
||||
error("can't write crash report %s: %s", loc, strerror(errno));
|
||||
free(loc);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -488,6 +489,7 @@ static void write_crash_report(const char *err)
|
||||
fputs("-------------------\n", rpt);
|
||||
fputs("END OF CRASH REPORT\n", rpt);
|
||||
fclose(rpt);
|
||||
free(loc);
|
||||
}
|
||||
|
||||
static void end_packfile(void);
|
||||
|
@ -948,7 +948,7 @@ static void update_shallow(struct fetch_pack_args *args,
|
||||
|
||||
if (args->depth > 0 && alternate_shallow_file) {
|
||||
if (*alternate_shallow_file == '\0') { /* --unshallow */
|
||||
unlink_or_warn(git_path("shallow"));
|
||||
unlink_or_warn(git_path_shallow());
|
||||
rollback_lock_file(&shallow_lock);
|
||||
} else
|
||||
commit_lock_file(&shallow_lock);
|
||||
|
@ -164,7 +164,7 @@ static void send_strbuf(const char *type, struct strbuf *buf)
|
||||
|
||||
static void send_local_file(const char *the_type, const char *name)
|
||||
{
|
||||
const char *p = git_path("%s", name);
|
||||
char *p = git_pathdup("%s", name);
|
||||
size_t buf_alloc = 8192;
|
||||
char *buf = xmalloc(buf_alloc);
|
||||
int fd;
|
||||
@ -191,6 +191,7 @@ static void send_local_file(const char *the_type, const char *name)
|
||||
}
|
||||
close(fd);
|
||||
free(buf);
|
||||
free(p);
|
||||
}
|
||||
|
||||
static void get_text_file(char *name)
|
||||
|
@ -295,7 +295,7 @@ static void write_buf_to_worktree(const unsigned char *obj,
|
||||
const char *buf, unsigned long size)
|
||||
{
|
||||
int fd;
|
||||
const char *path = git_path(NOTES_MERGE_WORKTREE "/%s", sha1_to_hex(obj));
|
||||
char *path = git_pathdup(NOTES_MERGE_WORKTREE "/%s", sha1_to_hex(obj));
|
||||
if (safe_create_leading_directories_const(path))
|
||||
die_errno("unable to create directory for '%s'", path);
|
||||
if (file_exists(path))
|
||||
@ -320,6 +320,7 @@ static void write_buf_to_worktree(const unsigned char *obj,
|
||||
}
|
||||
|
||||
close(fd);
|
||||
free(path);
|
||||
}
|
||||
|
||||
static void write_note_to_worktree(const unsigned char *obj,
|
||||
|
37
path.c
37
path.c
@ -224,11 +224,10 @@ const char *mkpath(const char *fmt, ...)
|
||||
return cleanup_path(pathname->buf);
|
||||
}
|
||||
|
||||
const char *git_path_submodule(const char *path, const char *fmt, ...)
|
||||
static void do_submodule_path(struct strbuf *buf, const char *path,
|
||||
const char *fmt, va_list args)
|
||||
{
|
||||
struct strbuf *buf = get_pathname();
|
||||
const char *git_dir;
|
||||
va_list args;
|
||||
|
||||
strbuf_addstr(buf, path);
|
||||
if (buf->len && buf->buf[buf->len - 1] != '/')
|
||||
@ -242,11 +241,27 @@ const char *git_path_submodule(const char *path, const char *fmt, ...)
|
||||
}
|
||||
strbuf_addch(buf, '/');
|
||||
|
||||
va_start(args, fmt);
|
||||
strbuf_vaddf(buf, fmt, args);
|
||||
va_end(args);
|
||||
strbuf_cleanup_path(buf);
|
||||
return buf->buf;
|
||||
}
|
||||
|
||||
char *git_pathdup_submodule(const char *path, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
va_start(args, fmt);
|
||||
do_submodule_path(&buf, path, fmt, args);
|
||||
va_end(args);
|
||||
return strbuf_detach(&buf, NULL);
|
||||
}
|
||||
|
||||
void strbuf_git_path_submodule(struct strbuf *buf, const char *path,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
do_submodule_path(buf, path, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
int validate_headref(const char *path)
|
||||
@ -918,3 +933,13 @@ char *xdg_config_home(const char *filename)
|
||||
return mkpathdup("%s/.config/git/%s", home, filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GIT_PATH_FUNC(git_path_cherry_pick_head, "CHERRY_PICK_HEAD")
|
||||
GIT_PATH_FUNC(git_path_revert_head, "REVERT_HEAD")
|
||||
GIT_PATH_FUNC(git_path_squash_msg, "SQUASH_MSG")
|
||||
GIT_PATH_FUNC(git_path_merge_msg, "MERGE_MSG")
|
||||
GIT_PATH_FUNC(git_path_merge_rr, "MERGE_RR")
|
||||
GIT_PATH_FUNC(git_path_merge_mode, "MERGE_MODE")
|
||||
GIT_PATH_FUNC(git_path_merge_head, "MERGE_HEAD")
|
||||
GIT_PATH_FUNC(git_path_fetch_head, "FETCH_HEAD")
|
||||
GIT_PATH_FUNC(git_path_shallow, "shallow")
|
||||
|
160
refs.c
160
refs.c
@ -1288,12 +1288,12 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir)
|
||||
*/
|
||||
static struct packed_ref_cache *get_packed_ref_cache(struct ref_cache *refs)
|
||||
{
|
||||
const char *packed_refs_file;
|
||||
char *packed_refs_file;
|
||||
|
||||
if (*refs->name)
|
||||
packed_refs_file = git_path_submodule(refs->name, "packed-refs");
|
||||
packed_refs_file = git_pathdup_submodule(refs->name, "packed-refs");
|
||||
else
|
||||
packed_refs_file = git_path("packed-refs");
|
||||
packed_refs_file = git_pathdup("packed-refs");
|
||||
|
||||
if (refs->packed &&
|
||||
!stat_validity_check(&refs->packed->validity, packed_refs_file))
|
||||
@ -1312,6 +1312,7 @@ static struct packed_ref_cache *get_packed_ref_cache(struct ref_cache *refs)
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
free(packed_refs_file);
|
||||
return refs->packed;
|
||||
}
|
||||
|
||||
@ -1351,19 +1352,23 @@ static void read_loose_refs(const char *dirname, struct ref_dir *dir)
|
||||
{
|
||||
struct ref_cache *refs = dir->ref_cache;
|
||||
DIR *d;
|
||||
const char *path;
|
||||
struct dirent *de;
|
||||
int dirnamelen = strlen(dirname);
|
||||
struct strbuf refname;
|
||||
struct strbuf path = STRBUF_INIT;
|
||||
size_t path_baselen;
|
||||
|
||||
if (*refs->name)
|
||||
path = git_path_submodule(refs->name, "%s", dirname);
|
||||
strbuf_git_path_submodule(&path, refs->name, "%s", dirname);
|
||||
else
|
||||
path = git_path("%s", dirname);
|
||||
strbuf_git_path(&path, "%s", dirname);
|
||||
path_baselen = path.len;
|
||||
|
||||
d = opendir(path);
|
||||
if (!d)
|
||||
d = opendir(path.buf);
|
||||
if (!d) {
|
||||
strbuf_release(&path);
|
||||
return;
|
||||
}
|
||||
|
||||
strbuf_init(&refname, dirnamelen + 257);
|
||||
strbuf_add(&refname, dirname, dirnamelen);
|
||||
@ -1372,17 +1377,14 @@ static void read_loose_refs(const char *dirname, struct ref_dir *dir)
|
||||
unsigned char sha1[20];
|
||||
struct stat st;
|
||||
int flag;
|
||||
const char *refdir;
|
||||
|
||||
if (de->d_name[0] == '.')
|
||||
continue;
|
||||
if (ends_with(de->d_name, ".lock"))
|
||||
continue;
|
||||
strbuf_addstr(&refname, de->d_name);
|
||||
refdir = *refs->name
|
||||
? git_path_submodule(refs->name, "%s", refname.buf)
|
||||
: git_path("%s", refname.buf);
|
||||
if (stat(refdir, &st) < 0) {
|
||||
strbuf_addstr(&path, de->d_name);
|
||||
if (stat(path.buf, &st) < 0) {
|
||||
; /* silently ignore */
|
||||
} else if (S_ISDIR(st.st_mode)) {
|
||||
strbuf_addch(&refname, '/');
|
||||
@ -1429,8 +1431,10 @@ static void read_loose_refs(const char *dirname, struct ref_dir *dir)
|
||||
create_ref_entry(refname.buf, sha1, flag, 0));
|
||||
}
|
||||
strbuf_setlen(&refname, dirnamelen);
|
||||
strbuf_setlen(&path, path_baselen);
|
||||
}
|
||||
strbuf_release(&refname);
|
||||
strbuf_release(&path);
|
||||
closedir(d);
|
||||
}
|
||||
|
||||
@ -1481,14 +1485,15 @@ static int resolve_gitlink_ref_recursive(struct ref_cache *refs,
|
||||
{
|
||||
int fd, len;
|
||||
char buffer[128], *p;
|
||||
const char *path;
|
||||
char *path;
|
||||
|
||||
if (recursion > MAXDEPTH || strlen(refname) > MAXREFLEN)
|
||||
return -1;
|
||||
path = *refs->name
|
||||
? git_path_submodule(refs->name, "%s", refname)
|
||||
: git_path("%s", refname);
|
||||
? git_pathdup_submodule(refs->name, "%s", refname)
|
||||
: git_pathdup("%s", refname);
|
||||
fd = open(path, O_RDONLY);
|
||||
free(path);
|
||||
if (fd < 0)
|
||||
return resolve_gitlink_packed_ref(refs, refname, sha1);
|
||||
|
||||
@ -2285,25 +2290,14 @@ static int verify_lock(struct ref_lock *lock,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int remove_empty_directories(const char *file)
|
||||
static int remove_empty_directories(struct strbuf *path)
|
||||
{
|
||||
/* we want to create a file but there is a directory there;
|
||||
/*
|
||||
* we want to create a file but there is a directory there;
|
||||
* if that is an empty directory (or a directory that contains
|
||||
* only empty directories), remove them.
|
||||
*/
|
||||
struct strbuf path;
|
||||
int result, save_errno;
|
||||
|
||||
strbuf_init(&path, 20);
|
||||
strbuf_addstr(&path, file);
|
||||
|
||||
result = remove_dir_recursively(&path, REMOVE_DIR_EMPTY_ONLY);
|
||||
save_errno = errno;
|
||||
|
||||
strbuf_release(&path);
|
||||
errno = save_errno;
|
||||
|
||||
return result;
|
||||
return remove_dir_recursively(path, REMOVE_DIR_EMPTY_ONLY);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2403,7 +2397,8 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
|
||||
unsigned int flags, int *type_p,
|
||||
struct strbuf *err)
|
||||
{
|
||||
const char *ref_file;
|
||||
struct strbuf ref_file = STRBUF_INIT;
|
||||
struct strbuf orig_ref_file = STRBUF_INIT;
|
||||
const char *orig_refname = refname;
|
||||
struct ref_lock *lock;
|
||||
int last_errno = 0;
|
||||
@ -2427,20 +2422,19 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
|
||||
refname = resolve_ref_unsafe(refname, resolve_flags,
|
||||
lock->old_oid.hash, &type);
|
||||
if (!refname && errno == EISDIR) {
|
||||
/* we are trying to lock foo but we used to
|
||||
/*
|
||||
* we are trying to lock foo but we used to
|
||||
* have foo/bar which now does not exist;
|
||||
* it is normal for the empty directory 'foo'
|
||||
* to remain.
|
||||
*/
|
||||
ref_file = git_path("%s", orig_refname);
|
||||
if (remove_empty_directories(ref_file)) {
|
||||
strbuf_git_path(&orig_ref_file, "%s", orig_refname);
|
||||
if (remove_empty_directories(&orig_ref_file)) {
|
||||
last_errno = errno;
|
||||
|
||||
if (!verify_refname_available(orig_refname, extras, skip,
|
||||
get_loose_refs(&ref_cache), err))
|
||||
strbuf_addf(err, "there are still refs under '%s'",
|
||||
orig_refname);
|
||||
|
||||
goto error_return;
|
||||
}
|
||||
refname = resolve_ref_unsafe(orig_refname, resolve_flags,
|
||||
@ -2480,10 +2474,10 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
|
||||
}
|
||||
lock->ref_name = xstrdup(refname);
|
||||
lock->orig_ref_name = xstrdup(orig_refname);
|
||||
ref_file = git_path("%s", refname);
|
||||
strbuf_git_path(&ref_file, "%s", refname);
|
||||
|
||||
retry:
|
||||
switch (safe_create_leading_directories_const(ref_file)) {
|
||||
switch (safe_create_leading_directories_const(ref_file.buf)) {
|
||||
case SCLD_OK:
|
||||
break; /* success */
|
||||
case SCLD_VANISHED:
|
||||
@ -2492,11 +2486,12 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
|
||||
/* fall through */
|
||||
default:
|
||||
last_errno = errno;
|
||||
strbuf_addf(err, "unable to create directory for %s", ref_file);
|
||||
strbuf_addf(err, "unable to create directory for %s",
|
||||
ref_file.buf);
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
if (hold_lock_file_for_update(lock->lk, ref_file, lflags) < 0) {
|
||||
if (hold_lock_file_for_update(lock->lk, ref_file.buf, lflags) < 0) {
|
||||
last_errno = errno;
|
||||
if (errno == ENOENT && --attempts_remaining > 0)
|
||||
/*
|
||||
@ -2506,7 +2501,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
|
||||
*/
|
||||
goto retry;
|
||||
else {
|
||||
unable_to_lock_message(ref_file, errno, err);
|
||||
unable_to_lock_message(ref_file.buf, errno, err);
|
||||
goto error_return;
|
||||
}
|
||||
}
|
||||
@ -2514,12 +2509,17 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
|
||||
last_errno = errno;
|
||||
goto error_return;
|
||||
}
|
||||
return lock;
|
||||
goto out;
|
||||
|
||||
error_return:
|
||||
unlock_ref(lock);
|
||||
lock = NULL;
|
||||
|
||||
out:
|
||||
strbuf_release(&ref_file);
|
||||
strbuf_release(&orig_ref_file);
|
||||
errno = last_errno;
|
||||
return NULL;
|
||||
return lock;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2925,9 +2925,13 @@ out:
|
||||
static int rename_tmp_log(const char *newrefname)
|
||||
{
|
||||
int attempts_remaining = 4;
|
||||
struct strbuf path = STRBUF_INIT;
|
||||
int ret = -1;
|
||||
|
||||
retry:
|
||||
switch (safe_create_leading_directories_const(git_path("logs/%s", newrefname))) {
|
||||
strbuf_reset(&path);
|
||||
strbuf_git_path(&path, "logs/%s", newrefname);
|
||||
switch (safe_create_leading_directories_const(path.buf)) {
|
||||
case SCLD_OK:
|
||||
break; /* success */
|
||||
case SCLD_VANISHED:
|
||||
@ -2936,19 +2940,19 @@ static int rename_tmp_log(const char *newrefname)
|
||||
/* fall through */
|
||||
default:
|
||||
error("unable to create directory for %s", newrefname);
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (rename(git_path(TMP_RENAMED_LOG), git_path("logs/%s", newrefname))) {
|
||||
if (rename(git_path(TMP_RENAMED_LOG), path.buf)) {
|
||||
if ((errno==EISDIR || errno==ENOTDIR) && --attempts_remaining > 0) {
|
||||
/*
|
||||
* rename(a, b) when b is an existing
|
||||
* directory ought to result in ISDIR, but
|
||||
* Solaris 5.8 gives ENOTDIR. Sheesh.
|
||||
*/
|
||||
if (remove_empty_directories(git_path("logs/%s", newrefname))) {
|
||||
if (remove_empty_directories(&path)) {
|
||||
error("Directory not empty: logs/%s", newrefname);
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
goto retry;
|
||||
} else if (errno == ENOENT && --attempts_remaining > 0) {
|
||||
@ -2961,10 +2965,13 @@ static int rename_tmp_log(const char *newrefname)
|
||||
} else {
|
||||
error("unable to move logfile "TMP_RENAMED_LOG" to logs/%s: %s",
|
||||
newrefname, strerror(errno));
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
ret = 0;
|
||||
out:
|
||||
strbuf_release(&path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rename_ref_available(const char *oldname, const char *newname)
|
||||
@ -3028,7 +3035,14 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
|
||||
if (!read_ref_full(newrefname, RESOLVE_REF_READING, sha1, NULL) &&
|
||||
delete_ref(newrefname, sha1, REF_NODEREF)) {
|
||||
if (errno==EISDIR) {
|
||||
if (remove_empty_directories(git_path("%s", newrefname))) {
|
||||
struct strbuf path = STRBUF_INIT;
|
||||
int result;
|
||||
|
||||
strbuf_git_path(&path, "%s", newrefname);
|
||||
result = remove_empty_directories(&path);
|
||||
strbuf_release(&path);
|
||||
|
||||
if (result) {
|
||||
error("Directory not empty: %s", newrefname);
|
||||
goto rollback;
|
||||
}
|
||||
@ -3145,25 +3159,21 @@ static int should_autocreate_reflog(const char *refname)
|
||||
* should_autocreate_reflog returns non-zero. Otherwise, create it
|
||||
* regardless of the ref name. Fill in *err and return -1 on failure.
|
||||
*/
|
||||
static int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct strbuf *err, int force_create)
|
||||
static int log_ref_setup(const char *refname, struct strbuf *logfile, struct strbuf *err, int force_create)
|
||||
{
|
||||
int logfd, oflags = O_APPEND | O_WRONLY;
|
||||
char *logfile;
|
||||
|
||||
strbuf_git_path(sb_logfile, "logs/%s", refname);
|
||||
logfile = sb_logfile->buf;
|
||||
/* make sure the rest of the function can't change "logfile" */
|
||||
sb_logfile = NULL;
|
||||
strbuf_git_path(logfile, "logs/%s", refname);
|
||||
if (force_create || should_autocreate_reflog(refname)) {
|
||||
if (safe_create_leading_directories(logfile) < 0) {
|
||||
if (safe_create_leading_directories(logfile->buf) < 0) {
|
||||
strbuf_addf(err, "unable to create directory for %s: "
|
||||
"%s", logfile, strerror(errno));
|
||||
"%s", logfile->buf, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
oflags |= O_CREAT;
|
||||
}
|
||||
|
||||
logfd = open(logfile, oflags, 0666);
|
||||
logfd = open(logfile->buf, oflags, 0666);
|
||||
if (logfd < 0) {
|
||||
if (!(oflags & O_CREAT) && (errno == ENOENT || errno == EISDIR))
|
||||
return 0;
|
||||
@ -3171,20 +3181,20 @@ static int log_ref_setup(const char *refname, struct strbuf *sb_logfile, struct
|
||||
if (errno == EISDIR) {
|
||||
if (remove_empty_directories(logfile)) {
|
||||
strbuf_addf(err, "There are still logs under "
|
||||
"'%s'", logfile);
|
||||
"'%s'", logfile->buf);
|
||||
return -1;
|
||||
}
|
||||
logfd = open(logfile, oflags, 0666);
|
||||
logfd = open(logfile->buf, oflags, 0666);
|
||||
}
|
||||
|
||||
if (logfd < 0) {
|
||||
strbuf_addf(err, "unable to append to %s: %s",
|
||||
logfile, strerror(errno));
|
||||
logfile->buf, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
adjust_shared_perm(logfile);
|
||||
adjust_shared_perm(logfile->buf);
|
||||
close(logfd);
|
||||
return 0;
|
||||
}
|
||||
@ -3228,36 +3238,32 @@ static int log_ref_write_fd(int fd, const unsigned char *old_sha1,
|
||||
|
||||
static int log_ref_write_1(const char *refname, const unsigned char *old_sha1,
|
||||
const unsigned char *new_sha1, const char *msg,
|
||||
struct strbuf *sb_log_file, int flags,
|
||||
struct strbuf *logfile, int flags,
|
||||
struct strbuf *err)
|
||||
{
|
||||
int logfd, result, oflags = O_APPEND | O_WRONLY;
|
||||
char *log_file;
|
||||
|
||||
if (log_all_ref_updates < 0)
|
||||
log_all_ref_updates = !is_bare_repository();
|
||||
|
||||
result = log_ref_setup(refname, sb_log_file, err, flags & REF_FORCE_CREATE_REFLOG);
|
||||
result = log_ref_setup(refname, logfile, err, flags & REF_FORCE_CREATE_REFLOG);
|
||||
|
||||
if (result)
|
||||
return result;
|
||||
log_file = sb_log_file->buf;
|
||||
/* make sure the rest of the function can't change "log_file" */
|
||||
sb_log_file = NULL;
|
||||
|
||||
logfd = open(log_file, oflags);
|
||||
logfd = open(logfile->buf, oflags);
|
||||
if (logfd < 0)
|
||||
return 0;
|
||||
result = log_ref_write_fd(logfd, old_sha1, new_sha1,
|
||||
git_committer_info(0), msg);
|
||||
if (result) {
|
||||
strbuf_addf(err, "unable to append to %s: %s", log_file,
|
||||
strbuf_addf(err, "unable to append to %s: %s", logfile->buf,
|
||||
strerror(errno));
|
||||
close(logfd);
|
||||
return -1;
|
||||
}
|
||||
if (close(logfd)) {
|
||||
strbuf_addf(err, "unable to append to %s: %s", log_file,
|
||||
strbuf_addf(err, "unable to append to %s: %s", logfile->buf,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
@ -3378,7 +3384,7 @@ static int commit_ref_update(struct ref_lock *lock,
|
||||
int create_symref(const char *ref_target, const char *refs_heads_master,
|
||||
const char *logmsg)
|
||||
{
|
||||
const char *lockpath;
|
||||
char *lockpath = NULL;
|
||||
char ref[1000];
|
||||
int fd, len, written;
|
||||
char *git_HEAD = git_pathdup("%s", ref_target);
|
||||
@ -3405,7 +3411,7 @@ int create_symref(const char *ref_target, const char *refs_heads_master,
|
||||
error("refname too long: %s", refs_heads_master);
|
||||
goto error_free_return;
|
||||
}
|
||||
lockpath = mkpath("%s.lock", git_HEAD);
|
||||
lockpath = mkpathdup("%s.lock", git_HEAD);
|
||||
fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666);
|
||||
if (fd < 0) {
|
||||
error("Unable to open %s for writing", lockpath);
|
||||
@ -3425,9 +3431,11 @@ int create_symref(const char *ref_target, const char *refs_heads_master,
|
||||
error_unlink_return:
|
||||
unlink_or_warn(lockpath);
|
||||
error_free_return:
|
||||
free(lockpath);
|
||||
free(git_HEAD);
|
||||
return -1;
|
||||
}
|
||||
free(lockpath);
|
||||
|
||||
#ifndef NO_SYMLINK_HEAD
|
||||
done:
|
||||
|
19
rerere.c
19
rerere.c
@ -20,8 +20,6 @@ static int rerere_enabled = -1;
|
||||
/* automatically update cleanly resolved paths to the index */
|
||||
static int rerere_autoupdate;
|
||||
|
||||
static char *merge_rr_path;
|
||||
|
||||
const char *rerere_path(const char *hex, const char *file)
|
||||
{
|
||||
return git_path("rr-cache/%s/%s", hex, file);
|
||||
@ -37,7 +35,7 @@ static void read_rr(struct string_list *rr)
|
||||
{
|
||||
unsigned char sha1[20];
|
||||
char buf[PATH_MAX];
|
||||
FILE *in = fopen(merge_rr_path, "r");
|
||||
FILE *in = fopen(git_path_merge_rr(), "r");
|
||||
if (!in)
|
||||
return;
|
||||
while (fread(buf, 40, 1, in) == 1) {
|
||||
@ -577,21 +575,21 @@ static void git_rerere_config(void)
|
||||
git_config(git_default_config, NULL);
|
||||
}
|
||||
|
||||
static GIT_PATH_FUNC(git_path_rr_cache, "rr-cache")
|
||||
|
||||
static int is_rerere_enabled(void)
|
||||
{
|
||||
const char *rr_cache;
|
||||
int rr_cache_exists;
|
||||
|
||||
if (!rerere_enabled)
|
||||
return 0;
|
||||
|
||||
rr_cache = git_path("rr-cache");
|
||||
rr_cache_exists = is_directory(rr_cache);
|
||||
rr_cache_exists = is_directory(git_path_rr_cache());
|
||||
if (rerere_enabled < 0)
|
||||
return rr_cache_exists;
|
||||
|
||||
if (!rr_cache_exists && mkdir_in_gitdir(rr_cache))
|
||||
die("Could not create directory %s", rr_cache);
|
||||
if (!rr_cache_exists && mkdir_in_gitdir(git_path_rr_cache()))
|
||||
die("Could not create directory %s", git_path_rr_cache());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -605,8 +603,7 @@ int setup_rerere(struct string_list *merge_rr, int flags)
|
||||
|
||||
if (flags & (RERERE_AUTOUPDATE|RERERE_NOAUTOUPDATE))
|
||||
rerere_autoupdate = !!(flags & RERERE_AUTOUPDATE);
|
||||
merge_rr_path = git_pathdup("MERGE_RR");
|
||||
fd = hold_lock_file_for_update(&write_lock, merge_rr_path,
|
||||
fd = hold_lock_file_for_update(&write_lock, git_path_merge_rr(),
|
||||
LOCK_DIE_ON_ERROR);
|
||||
read_rr(merge_rr);
|
||||
return fd;
|
||||
@ -741,5 +738,5 @@ void rerere_clear(struct string_list *merge_rr)
|
||||
if (!has_rerere_resolution(name))
|
||||
unlink_rr_item(name);
|
||||
}
|
||||
unlink_or_warn(git_path("MERGE_RR"));
|
||||
unlink_or_warn(git_path_merge_rr());
|
||||
}
|
||||
|
@ -797,11 +797,13 @@ int finish_async(struct async *async)
|
||||
|
||||
const char *find_hook(const char *name)
|
||||
{
|
||||
const char *path = git_path("hooks/%s", name);
|
||||
if (access(path, X_OK) < 0)
|
||||
path = NULL;
|
||||
static struct strbuf path = STRBUF_INIT;
|
||||
|
||||
return path;
|
||||
strbuf_reset(&path);
|
||||
strbuf_git_path(&path, "hooks/%s", name);
|
||||
if (access(path.buf, X_OK) < 0)
|
||||
return NULL;
|
||||
return path.buf;
|
||||
}
|
||||
|
||||
int run_hook_ve(const char *const *env, const char *name, va_list args)
|
||||
|
@ -52,6 +52,11 @@ int start_command(struct child_process *);
|
||||
int finish_command(struct child_process *);
|
||||
int run_command(struct child_process *);
|
||||
|
||||
/*
|
||||
* Returns the path to the hook file, or NULL if the hook is missing
|
||||
* or disabled. Note that this points to static storage that will be
|
||||
* overwritten by further calls to find_hook and run_hook_*.
|
||||
*/
|
||||
extern const char *find_hook(const char *name);
|
||||
LAST_ARG_MUST_BE_NULL
|
||||
extern int run_hook_le(const char *const *env, const char *name, ...);
|
||||
|
87
sequencer.c
87
sequencer.c
@ -21,6 +21,11 @@
|
||||
const char sign_off_header[] = "Signed-off-by: ";
|
||||
static const char cherry_picked_prefix[] = "(cherry picked from commit ";
|
||||
|
||||
static GIT_PATH_FUNC(git_path_todo_file, SEQ_TODO_FILE)
|
||||
static GIT_PATH_FUNC(git_path_opts_file, SEQ_OPTS_FILE)
|
||||
static GIT_PATH_FUNC(git_path_seq_dir, SEQ_DIR)
|
||||
static GIT_PATH_FUNC(git_path_head_file, SEQ_HEAD_FILE)
|
||||
|
||||
static int is_rfc2822_line(const char *buf, int len)
|
||||
{
|
||||
int i;
|
||||
@ -186,7 +191,7 @@ static void print_advice(int show_hint, struct replay_opts *opts)
|
||||
* (typically rebase --interactive) wants to take care
|
||||
* of the commit itself so remove CHERRY_PICK_HEAD
|
||||
*/
|
||||
unlink(git_path("CHERRY_PICK_HEAD"));
|
||||
unlink(git_path_cherry_pick_head());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -467,7 +472,6 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
|
||||
struct commit *base, *next, *parent;
|
||||
const char *base_label, *next_label;
|
||||
struct commit_message msg = { NULL, NULL, NULL, NULL };
|
||||
char *defmsg = NULL;
|
||||
struct strbuf msgbuf = STRBUF_INIT;
|
||||
int res, unborn = 0, allow;
|
||||
|
||||
@ -537,8 +541,6 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
|
||||
* reverse of it if we are revert.
|
||||
*/
|
||||
|
||||
defmsg = git_pathdup("MERGE_MSG");
|
||||
|
||||
if (opts->action == REPLAY_REVERT) {
|
||||
base = commit;
|
||||
base_label = msg.label;
|
||||
@ -585,12 +587,12 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
|
||||
if (!opts->strategy || !strcmp(opts->strategy, "recursive") || opts->action == REPLAY_REVERT) {
|
||||
res = do_recursive_merge(base, next, base_label, next_label,
|
||||
head, &msgbuf, opts);
|
||||
write_message(&msgbuf, defmsg);
|
||||
write_message(&msgbuf, git_path_merge_msg());
|
||||
} else {
|
||||
struct commit_list *common = NULL;
|
||||
struct commit_list *remotes = NULL;
|
||||
|
||||
write_message(&msgbuf, defmsg);
|
||||
write_message(&msgbuf, git_path_merge_msg());
|
||||
|
||||
commit_list_insert(base, &common);
|
||||
commit_list_insert(next, &remotes);
|
||||
@ -628,11 +630,10 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
|
||||
goto leave;
|
||||
}
|
||||
if (!opts->no_commit)
|
||||
res = run_git_commit(defmsg, opts, allow);
|
||||
res = run_git_commit(git_path_merge_msg(), opts, allow);
|
||||
|
||||
leave:
|
||||
free_message(commit, &msg);
|
||||
free(defmsg);
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -756,24 +757,23 @@ static int parse_insn_buffer(char *buf, struct commit_list **todo_list,
|
||||
static void read_populate_todo(struct commit_list **todo_list,
|
||||
struct replay_opts *opts)
|
||||
{
|
||||
const char *todo_file = git_path(SEQ_TODO_FILE);
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
int fd, res;
|
||||
|
||||
fd = open(todo_file, O_RDONLY);
|
||||
fd = open(git_path_todo_file(), O_RDONLY);
|
||||
if (fd < 0)
|
||||
die_errno(_("Could not open %s"), todo_file);
|
||||
die_errno(_("Could not open %s"), git_path_todo_file());
|
||||
if (strbuf_read(&buf, fd, 0) < 0) {
|
||||
close(fd);
|
||||
strbuf_release(&buf);
|
||||
die(_("Could not read %s."), todo_file);
|
||||
die(_("Could not read %s."), git_path_todo_file());
|
||||
}
|
||||
close(fd);
|
||||
|
||||
res = parse_insn_buffer(buf.buf, todo_list, opts);
|
||||
strbuf_release(&buf);
|
||||
if (res)
|
||||
die(_("Unusable instruction sheet: %s"), todo_file);
|
||||
die(_("Unusable instruction sheet: %s"), git_path_todo_file());
|
||||
}
|
||||
|
||||
static int populate_opts_cb(const char *key, const char *value, void *data)
|
||||
@ -813,12 +813,10 @@ static int populate_opts_cb(const char *key, const char *value, void *data)
|
||||
|
||||
static void read_populate_opts(struct replay_opts **opts_ptr)
|
||||
{
|
||||
const char *opts_file = git_path(SEQ_OPTS_FILE);
|
||||
|
||||
if (!file_exists(opts_file))
|
||||
if (!file_exists(git_path_opts_file()))
|
||||
return;
|
||||
if (git_config_from_file(populate_opts_cb, opts_file, *opts_ptr) < 0)
|
||||
die(_("Malformed options sheet: %s"), opts_file);
|
||||
if (git_config_from_file(populate_opts_cb, git_path_opts_file(), *opts_ptr) < 0)
|
||||
die(_("Malformed options sheet: %s"), git_path_opts_file());
|
||||
}
|
||||
|
||||
static void walk_revs_populate_todo(struct commit_list **todo_list,
|
||||
@ -836,31 +834,29 @@ static void walk_revs_populate_todo(struct commit_list **todo_list,
|
||||
|
||||
static int create_seq_dir(void)
|
||||
{
|
||||
const char *seq_dir = git_path(SEQ_DIR);
|
||||
|
||||
if (file_exists(seq_dir)) {
|
||||
if (file_exists(git_path_seq_dir())) {
|
||||
error(_("a cherry-pick or revert is already in progress"));
|
||||
advise(_("try \"git cherry-pick (--continue | --quit | --abort)\""));
|
||||
return -1;
|
||||
}
|
||||
else if (mkdir(seq_dir, 0777) < 0)
|
||||
die_errno(_("Could not create sequencer directory %s"), seq_dir);
|
||||
else if (mkdir(git_path_seq_dir(), 0777) < 0)
|
||||
die_errno(_("Could not create sequencer directory %s"),
|
||||
git_path_seq_dir());
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void save_head(const char *head)
|
||||
{
|
||||
const char *head_file = git_path(SEQ_HEAD_FILE);
|
||||
static struct lock_file head_lock;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
int fd;
|
||||
|
||||
fd = hold_lock_file_for_update(&head_lock, head_file, LOCK_DIE_ON_ERROR);
|
||||
fd = hold_lock_file_for_update(&head_lock, git_path_head_file(), LOCK_DIE_ON_ERROR);
|
||||
strbuf_addf(&buf, "%s\n", head);
|
||||
if (write_in_full(fd, buf.buf, buf.len) < 0)
|
||||
die_errno(_("Could not write to %s"), head_file);
|
||||
die_errno(_("Could not write to %s"), git_path_head_file());
|
||||
if (commit_lock_file(&head_lock) < 0)
|
||||
die(_("Error wrapping up %s."), head_file);
|
||||
die(_("Error wrapping up %s."), git_path_head_file());
|
||||
}
|
||||
|
||||
static int reset_for_rollback(const unsigned char *sha1)
|
||||
@ -877,8 +873,8 @@ static int rollback_single_pick(void)
|
||||
{
|
||||
unsigned char head_sha1[20];
|
||||
|
||||
if (!file_exists(git_path("CHERRY_PICK_HEAD")) &&
|
||||
!file_exists(git_path("REVERT_HEAD")))
|
||||
if (!file_exists(git_path_cherry_pick_head()) &&
|
||||
!file_exists(git_path_revert_head()))
|
||||
return error(_("no cherry-pick or revert in progress"));
|
||||
if (read_ref_full("HEAD", 0, head_sha1, NULL))
|
||||
return error(_("cannot resolve HEAD"));
|
||||
@ -889,13 +885,11 @@ static int rollback_single_pick(void)
|
||||
|
||||
static int sequencer_rollback(struct replay_opts *opts)
|
||||
{
|
||||
const char *filename;
|
||||
FILE *f;
|
||||
unsigned char sha1[20];
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
filename = git_path(SEQ_HEAD_FILE);
|
||||
f = fopen(filename, "r");
|
||||
f = fopen(git_path_head_file(), "r");
|
||||
if (!f && errno == ENOENT) {
|
||||
/*
|
||||
* There is no multiple-cherry-pick in progress.
|
||||
@ -905,18 +899,18 @@ static int sequencer_rollback(struct replay_opts *opts)
|
||||
return rollback_single_pick();
|
||||
}
|
||||
if (!f)
|
||||
return error(_("cannot open %s: %s"), filename,
|
||||
return error(_("cannot open %s: %s"), git_path_head_file(),
|
||||
strerror(errno));
|
||||
if (strbuf_getline(&buf, f, '\n')) {
|
||||
error(_("cannot read %s: %s"), filename, ferror(f) ?
|
||||
strerror(errno) : _("unexpected end of file"));
|
||||
error(_("cannot read %s: %s"), git_path_head_file(),
|
||||
ferror(f) ? strerror(errno) : _("unexpected end of file"));
|
||||
fclose(f);
|
||||
goto fail;
|
||||
}
|
||||
fclose(f);
|
||||
if (get_sha1_hex(buf.buf, sha1) || buf.buf[40] != '\0') {
|
||||
error(_("stored pre-cherry-pick HEAD file '%s' is corrupt"),
|
||||
filename);
|
||||
git_path_head_file());
|
||||
goto fail;
|
||||
}
|
||||
if (reset_for_rollback(sha1))
|
||||
@ -931,28 +925,27 @@ fail:
|
||||
|
||||
static void save_todo(struct commit_list *todo_list, struct replay_opts *opts)
|
||||
{
|
||||
const char *todo_file = git_path(SEQ_TODO_FILE);
|
||||
static struct lock_file todo_lock;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
int fd;
|
||||
|
||||
fd = hold_lock_file_for_update(&todo_lock, todo_file, LOCK_DIE_ON_ERROR);
|
||||
fd = hold_lock_file_for_update(&todo_lock, git_path_todo_file(), LOCK_DIE_ON_ERROR);
|
||||
if (format_todo(&buf, todo_list, opts) < 0)
|
||||
die(_("Could not format %s."), todo_file);
|
||||
die(_("Could not format %s."), git_path_todo_file());
|
||||
if (write_in_full(fd, buf.buf, buf.len) < 0) {
|
||||
strbuf_release(&buf);
|
||||
die_errno(_("Could not write to %s"), todo_file);
|
||||
die_errno(_("Could not write to %s"), git_path_todo_file());
|
||||
}
|
||||
if (commit_lock_file(&todo_lock) < 0) {
|
||||
strbuf_release(&buf);
|
||||
die(_("Error wrapping up %s."), todo_file);
|
||||
die(_("Error wrapping up %s."), git_path_todo_file());
|
||||
}
|
||||
strbuf_release(&buf);
|
||||
}
|
||||
|
||||
static void save_opts(struct replay_opts *opts)
|
||||
{
|
||||
const char *opts_file = git_path(SEQ_OPTS_FILE);
|
||||
const char *opts_file = git_path_opts_file();
|
||||
|
||||
if (opts->no_commit)
|
||||
git_config_set_in_file(opts_file, "options.no-commit", "true");
|
||||
@ -1013,8 +1006,8 @@ static int continue_single_pick(void)
|
||||
{
|
||||
const char *argv[] = { "commit", NULL };
|
||||
|
||||
if (!file_exists(git_path("CHERRY_PICK_HEAD")) &&
|
||||
!file_exists(git_path("REVERT_HEAD")))
|
||||
if (!file_exists(git_path_cherry_pick_head()) &&
|
||||
!file_exists(git_path_revert_head()))
|
||||
return error(_("no cherry-pick or revert in progress"));
|
||||
return run_command_v_opt(argv, RUN_GIT_CMD);
|
||||
}
|
||||
@ -1023,14 +1016,14 @@ static int sequencer_continue(struct replay_opts *opts)
|
||||
{
|
||||
struct commit_list *todo_list = NULL;
|
||||
|
||||
if (!file_exists(git_path(SEQ_TODO_FILE)))
|
||||
if (!file_exists(git_path_todo_file()))
|
||||
return continue_single_pick();
|
||||
read_populate_opts(&opts);
|
||||
read_populate_todo(&todo_list, opts);
|
||||
|
||||
/* Verify that the conflict has been resolved */
|
||||
if (file_exists(git_path("CHERRY_PICK_HEAD")) ||
|
||||
file_exists(git_path("REVERT_HEAD"))) {
|
||||
if (file_exists(git_path_cherry_pick_head()) ||
|
||||
file_exists(git_path_revert_head())) {
|
||||
int ret = continue_single_pick();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
47
sha1_file.c
47
sha1_file.c
@ -404,13 +404,46 @@ void read_info_alternates(const char * relative_base, int depth)
|
||||
void add_to_alternates_file(const char *reference)
|
||||
{
|
||||
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
|
||||
int fd = hold_lock_file_for_append(lock, git_path("objects/info/alternates"), LOCK_DIE_ON_ERROR);
|
||||
const char *alt = mkpath("%s\n", reference);
|
||||
write_or_die(fd, alt, strlen(alt));
|
||||
if (commit_lock_file(lock))
|
||||
die("could not close alternates file");
|
||||
if (alt_odb_tail)
|
||||
link_alt_odb_entries(alt, strlen(alt), '\n', NULL, 0);
|
||||
char *alts = git_pathdup("objects/info/alternates");
|
||||
FILE *in, *out;
|
||||
|
||||
hold_lock_file_for_update(lock, alts, LOCK_DIE_ON_ERROR);
|
||||
out = fdopen_lock_file(lock, "w");
|
||||
if (!out)
|
||||
die_errno("unable to fdopen alternates lockfile");
|
||||
|
||||
in = fopen(alts, "r");
|
||||
if (in) {
|
||||
struct strbuf line = STRBUF_INIT;
|
||||
int found = 0;
|
||||
|
||||
while (strbuf_getline(&line, in, '\n') != EOF) {
|
||||
if (!strcmp(reference, line.buf)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
fprintf_or_die(out, "%s\n", line.buf);
|
||||
}
|
||||
|
||||
strbuf_release(&line);
|
||||
fclose(in);
|
||||
|
||||
if (found) {
|
||||
rollback_lock_file(lock);
|
||||
lock = NULL;
|
||||
}
|
||||
}
|
||||
else if (errno != ENOENT)
|
||||
die_errno("unable to read alternates file");
|
||||
|
||||
if (lock) {
|
||||
fprintf_or_die(out, "%s\n", reference);
|
||||
if (commit_lock_file(lock))
|
||||
die_errno("unable to move new alternates file into place");
|
||||
if (alt_odb_tail)
|
||||
link_alt_odb_entries(reference, strlen(reference), '\n', NULL, 0);
|
||||
}
|
||||
free(alts);
|
||||
}
|
||||
|
||||
int foreach_alt_odb(alt_odb_fn fn, void *cb)
|
||||
|
10
shallow.c
10
shallow.c
@ -48,7 +48,7 @@ int is_repository_shallow(void)
|
||||
return is_shallow;
|
||||
|
||||
if (!path)
|
||||
path = git_path("shallow");
|
||||
path = git_path_shallow();
|
||||
/*
|
||||
* fetch-pack sets '--shallow-file ""' as an indicator that no
|
||||
* shallow file should be used. We could just open it and it
|
||||
@ -142,7 +142,7 @@ static void check_shallow_file_for_update(void)
|
||||
if (is_shallow == -1)
|
||||
die("BUG: shallow must be initialized by now");
|
||||
|
||||
if (!stat_validity_check(&shallow_stat, git_path("shallow")))
|
||||
if (!stat_validity_check(&shallow_stat, git_path_shallow()))
|
||||
die("shallow file has changed since we read it");
|
||||
}
|
||||
|
||||
@ -261,7 +261,7 @@ void setup_alternate_shallow(struct lock_file *shallow_lock,
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
int fd;
|
||||
|
||||
fd = hold_lock_file_for_update(shallow_lock, git_path("shallow"),
|
||||
fd = hold_lock_file_for_update(shallow_lock, git_path_shallow(),
|
||||
LOCK_DIE_ON_ERROR);
|
||||
check_shallow_file_for_update();
|
||||
if (write_shallow_commits(&sb, 0, extra)) {
|
||||
@ -308,7 +308,7 @@ void prune_shallow(int show_only)
|
||||
strbuf_release(&sb);
|
||||
return;
|
||||
}
|
||||
fd = hold_lock_file_for_update(&shallow_lock, git_path("shallow"),
|
||||
fd = hold_lock_file_for_update(&shallow_lock, git_path_shallow(),
|
||||
LOCK_DIE_ON_ERROR);
|
||||
check_shallow_file_for_update();
|
||||
if (write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY)) {
|
||||
@ -317,7 +317,7 @@ void prune_shallow(int show_only)
|
||||
shallow_lock.filename.buf);
|
||||
commit_lock_file(&shallow_lock);
|
||||
} else {
|
||||
unlink(git_path("shallow"));
|
||||
unlink(git_path_shallow());
|
||||
rollback_lock_file(&shallow_lock);
|
||||
}
|
||||
strbuf_release(&sb);
|
||||
|
@ -10,49 +10,51 @@ base_dir=`pwd`
|
||||
|
||||
U=$base_dir/UPLOAD_LOG
|
||||
|
||||
test_expect_success 'preparing first repository' \
|
||||
'test_create_repo A && cd A &&
|
||||
echo first > file1 &&
|
||||
git add file1 &&
|
||||
git commit -m initial'
|
||||
# create a commit in repo $1 with name $2
|
||||
commit_in () {
|
||||
(
|
||||
cd "$1" &&
|
||||
echo "$2" >"$2" &&
|
||||
git add "$2" &&
|
||||
git commit -m "$2"
|
||||
)
|
||||
}
|
||||
|
||||
cd "$base_dir"
|
||||
# check that there are $2 loose objects in repo $1
|
||||
test_objcount () {
|
||||
echo "$2" >expect &&
|
||||
git -C "$1" count-objects >actual.raw &&
|
||||
cut -d' ' -f1 <actual.raw >actual &&
|
||||
test_cmp expect actual
|
||||
}
|
||||
|
||||
test_expect_success 'preparing second repository' \
|
||||
'git clone A B && cd B &&
|
||||
echo second > file2 &&
|
||||
git add file2 &&
|
||||
git commit -m addition &&
|
||||
git repack -a -d &&
|
||||
git prune'
|
||||
test_expect_success 'preparing first repository' '
|
||||
test_create_repo A &&
|
||||
commit_in A file1
|
||||
'
|
||||
|
||||
cd "$base_dir"
|
||||
test_expect_success 'preparing second repository' '
|
||||
git clone A B &&
|
||||
commit_in B file2 &&
|
||||
git -C B repack -ad &&
|
||||
git -C B prune
|
||||
'
|
||||
|
||||
test_expect_success 'cloning with reference (-l -s)' \
|
||||
'git clone -l -s --reference B A C'
|
||||
test_expect_success 'cloning with reference (-l -s)' '
|
||||
git clone -l -s --reference B A C
|
||||
'
|
||||
|
||||
cd "$base_dir"
|
||||
test_expect_success 'existence of info/alternates' '
|
||||
test_line_count = 2 C/.git/objects/info/alternates
|
||||
'
|
||||
|
||||
test_expect_success 'existence of info/alternates' \
|
||||
'test_line_count = 2 C/.git/objects/info/alternates'
|
||||
test_expect_success 'pulling from reference' '
|
||||
git -C C pull ../B master
|
||||
'
|
||||
|
||||
cd "$base_dir"
|
||||
|
||||
test_expect_success 'pulling from reference' \
|
||||
'cd C &&
|
||||
git pull ../B master'
|
||||
|
||||
cd "$base_dir"
|
||||
|
||||
test_expect_success 'that reference gets used' \
|
||||
'cd C &&
|
||||
echo "0 objects, 0 kilobytes" > expected &&
|
||||
git count-objects > current &&
|
||||
test_cmp expected current'
|
||||
|
||||
cd "$base_dir"
|
||||
|
||||
rm -f "$U.D"
|
||||
test_expect_success 'that reference gets used' '
|
||||
test_objcount C 0
|
||||
'
|
||||
|
||||
test_expect_success 'cloning with reference (no -l -s)' '
|
||||
GIT_TRACE_PACKET=$U.D git clone --reference B "file://$(pwd)/A" D
|
||||
@ -63,95 +65,69 @@ test_expect_success 'fetched no objects' '
|
||||
! grep " want" "$U.D"
|
||||
'
|
||||
|
||||
cd "$base_dir"
|
||||
test_expect_success 'existence of info/alternates' '
|
||||
test_line_count = 1 D/.git/objects/info/alternates
|
||||
'
|
||||
|
||||
test_expect_success 'existence of info/alternates' \
|
||||
'test_line_count = 1 D/.git/objects/info/alternates'
|
||||
test_expect_success 'pulling from reference' '
|
||||
git -C D pull ../B master
|
||||
'
|
||||
|
||||
cd "$base_dir"
|
||||
test_expect_success 'that reference gets used' '
|
||||
test_objcount D 0
|
||||
'
|
||||
|
||||
test_expect_success 'pulling from reference' \
|
||||
'cd D && git pull ../B master'
|
||||
test_expect_success 'updating origin' '
|
||||
commit_in A file3 &&
|
||||
git -C A repack -ad &&
|
||||
git -C A prune
|
||||
'
|
||||
|
||||
cd "$base_dir"
|
||||
|
||||
test_expect_success 'that reference gets used' \
|
||||
'cd D && echo "0 objects, 0 kilobytes" > expected &&
|
||||
git count-objects > current &&
|
||||
test_cmp expected current'
|
||||
|
||||
cd "$base_dir"
|
||||
|
||||
test_expect_success 'updating origin' \
|
||||
'cd A &&
|
||||
echo third > file3 &&
|
||||
git add file3 &&
|
||||
git commit -m update &&
|
||||
git repack -a -d &&
|
||||
git prune'
|
||||
|
||||
cd "$base_dir"
|
||||
|
||||
test_expect_success 'pulling changes from origin' \
|
||||
'cd C &&
|
||||
git pull origin'
|
||||
|
||||
cd "$base_dir"
|
||||
test_expect_success 'pulling changes from origin' '
|
||||
git -C C pull origin
|
||||
'
|
||||
|
||||
# the 2 local objects are commit and tree from the merge
|
||||
test_expect_success 'that alternate to origin gets used' \
|
||||
'cd C &&
|
||||
echo "2 objects" > expected &&
|
||||
git count-objects | cut -d, -f1 > current &&
|
||||
test_cmp expected current'
|
||||
test_expect_success 'that alternate to origin gets used' '
|
||||
test_objcount C 2
|
||||
'
|
||||
|
||||
cd "$base_dir"
|
||||
|
||||
test_expect_success 'pulling changes from origin' \
|
||||
'cd D &&
|
||||
git pull origin'
|
||||
|
||||
cd "$base_dir"
|
||||
test_expect_success 'pulling changes from origin' '
|
||||
git -C D pull origin
|
||||
'
|
||||
|
||||
# the 5 local objects are expected; file3 blob, commit in A to add it
|
||||
# and its tree, and 2 are our tree and the merge commit.
|
||||
test_expect_success 'check objects expected to exist locally' \
|
||||
'cd D &&
|
||||
echo "5 objects" > expected &&
|
||||
git count-objects | cut -d, -f1 > current &&
|
||||
test_cmp expected current'
|
||||
test_expect_success 'check objects expected to exist locally' '
|
||||
test_objcount D 5
|
||||
'
|
||||
|
||||
cd "$base_dir"
|
||||
test_expect_success 'preparing alternate repository #1' '
|
||||
test_create_repo F &&
|
||||
commit_in F file1
|
||||
'
|
||||
|
||||
test_expect_success 'preparing alternate repository #1' \
|
||||
'test_create_repo F && cd F &&
|
||||
echo first > file1 &&
|
||||
git add file1 &&
|
||||
git commit -m initial'
|
||||
test_expect_success 'cloning alternate repo #2 and adding changes to repo #1' '
|
||||
git clone F G &&
|
||||
commit_in F file2
|
||||
'
|
||||
|
||||
cd "$base_dir"
|
||||
test_expect_success 'cloning alternate repo #1, using #2 as reference' '
|
||||
git clone --reference G F H
|
||||
'
|
||||
|
||||
test_expect_success 'cloning alternate repo #2 and adding changes to repo #1' \
|
||||
'git clone F G && cd F &&
|
||||
echo second > file2 &&
|
||||
git add file2 &&
|
||||
git commit -m addition'
|
||||
test_expect_success 'cloning with reference being subset of source (-l -s)' '
|
||||
git clone -l -s --reference A B E
|
||||
'
|
||||
|
||||
cd "$base_dir"
|
||||
|
||||
test_expect_success 'cloning alternate repo #1, using #2 as reference' \
|
||||
'git clone --reference G F H'
|
||||
|
||||
cd "$base_dir"
|
||||
|
||||
test_expect_success 'cloning with reference being subset of source (-l -s)' \
|
||||
'git clone -l -s --reference A B E'
|
||||
|
||||
cd "$base_dir"
|
||||
test_expect_success 'cloning with multiple references drops duplicates' '
|
||||
git clone -s --reference B --reference A --reference B A dups &&
|
||||
test_line_count = 2 dups/.git/objects/info/alternates
|
||||
'
|
||||
|
||||
test_expect_success 'clone with reference from a tagged repository' '
|
||||
(
|
||||
cd A && git tag -a -m 'tagged' HEAD
|
||||
cd A && git tag -a -m tagged HEAD
|
||||
) &&
|
||||
git clone --reference=A A I
|
||||
'
|
||||
@ -168,8 +144,6 @@ test_expect_success 'prepare branched repository' '
|
||||
)
|
||||
'
|
||||
|
||||
rm -f "$U.K"
|
||||
|
||||
test_expect_success 'fetch with incomplete alternates' '
|
||||
git init K &&
|
||||
echo "$base_dir/A/.git/objects" >K/.git/objects/info/alternates &&
|
||||
|
@ -1029,10 +1029,12 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
|
||||
if (!core_apply_sparse_checkout || !o->update)
|
||||
o->skip_sparse_checkout = 1;
|
||||
if (!o->skip_sparse_checkout) {
|
||||
if (add_excludes_from_file_to_list(git_path("info/sparse-checkout"), "", 0, &el, 0) < 0)
|
||||
char *sparse = git_pathdup("info/sparse-checkout");
|
||||
if (add_excludes_from_file_to_list(sparse, "", 0, &el, 0) < 0)
|
||||
o->skip_sparse_checkout = 1;
|
||||
else
|
||||
o->el = ⪙
|
||||
free(sparse);
|
||||
}
|
||||
|
||||
memset(&o->result, 0, sizeof(o->result));
|
||||
|
@ -1171,7 +1171,7 @@ static void show_rebase_in_progress(struct wt_status *s,
|
||||
status_printf_ln(s, color,
|
||||
_(" (use \"git rebase --abort\" to check out the original branch)"));
|
||||
}
|
||||
} else if (state->rebase_in_progress || !stat(git_path("MERGE_MSG"), &st)) {
|
||||
} else if (state->rebase_in_progress || !stat(git_path_merge_msg(), &st)) {
|
||||
print_rebase_state(s, state, color);
|
||||
if (s->hints)
|
||||
status_printf_ln(s, color,
|
||||
@ -1368,7 +1368,7 @@ void wt_status_get_state(struct wt_status_state *state,
|
||||
struct stat st;
|
||||
unsigned char sha1[20];
|
||||
|
||||
if (!stat(git_path("MERGE_HEAD"), &st)) {
|
||||
if (!stat(git_path_merge_head(), &st)) {
|
||||
state->merge_in_progress = 1;
|
||||
} else if (!stat(git_path("rebase-apply"), &st)) {
|
||||
if (!stat(git_path("rebase-apply/applying"), &st)) {
|
||||
@ -1387,7 +1387,7 @@ void wt_status_get_state(struct wt_status_state *state,
|
||||
state->rebase_in_progress = 1;
|
||||
state->branch = read_and_strip_branch("rebase-merge/head-name");
|
||||
state->onto = read_and_strip_branch("rebase-merge/onto");
|
||||
} else if (!stat(git_path("CHERRY_PICK_HEAD"), &st) &&
|
||||
} else if (!stat(git_path_cherry_pick_head(), &st) &&
|
||||
!get_sha1("CHERRY_PICK_HEAD", sha1)) {
|
||||
state->cherry_pick_in_progress = 1;
|
||||
hashcpy(state->cherry_pick_head_sha1, sha1);
|
||||
@ -1396,7 +1396,7 @@ void wt_status_get_state(struct wt_status_state *state,
|
||||
state->bisect_in_progress = 1;
|
||||
state->branch = read_and_strip_branch("BISECT_START");
|
||||
}
|
||||
if (!stat(git_path("REVERT_HEAD"), &st) &&
|
||||
if (!stat(git_path_revert_head(), &st) &&
|
||||
!get_sha1("REVERT_HEAD", sha1)) {
|
||||
state->revert_in_progress = 1;
|
||||
hashcpy(state->revert_head_sha1, sha1);
|
||||
|
Loading…
Reference in New Issue
Block a user