зеркало из https://github.com/microsoft/git.git
git_snpath(): retire and replace with strbuf_git_path()
In the previous patch, git_snpath() is modified to allocate a new strbuf buffer because vsnpath() needs that. But that makes it awkward because git_snpath() receives a pre-allocated buffer from outside and has to copy data back. Rename it to strbuf_git_path() and make it receive strbuf directly. Using git_path() in update_refs_for_switch() which used to call git_snpath() is safe because that function and all of its callers do not keep any pointer to the round-robin buffer pool allocated by get_pathname(). Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
dcf692625a
Коммит
1a83c240f2
|
@ -588,18 +588,21 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
|
|||
if (opts->new_orphan_branch) {
|
||||
if (opts->new_branch_log && !log_all_ref_updates) {
|
||||
int temp;
|
||||
char log_file[PATH_MAX];
|
||||
const char *ref_name = mkpath("refs/heads/%s", opts->new_orphan_branch);
|
||||
struct strbuf log_file = STRBUF_INIT;
|
||||
int ret;
|
||||
const char *ref_name;
|
||||
|
||||
ref_name = mkpath("refs/heads/%s", opts->new_orphan_branch);
|
||||
temp = log_all_ref_updates;
|
||||
log_all_ref_updates = 1;
|
||||
if (log_ref_setup(ref_name, log_file, sizeof(log_file))) {
|
||||
ret = log_ref_setup(ref_name, &log_file);
|
||||
log_all_ref_updates = temp;
|
||||
strbuf_release(&log_file);
|
||||
if (ret) {
|
||||
fprintf(stderr, _("Can not do reflog for '%s'\n"),
|
||||
opts->new_orphan_branch);
|
||||
log_all_ref_updates = temp;
|
||||
return;
|
||||
}
|
||||
log_all_ref_updates = temp;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
4
cache.h
4
cache.h
|
@ -679,8 +679,8 @@ extern int check_repository_format(void);
|
|||
|
||||
extern char *mksnpath(char *buf, size_t n, const char *fmt, ...)
|
||||
__attribute__((format (printf, 3, 4)));
|
||||
extern char *git_snpath(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 char *git_pathdup(const char *fmt, ...)
|
||||
__attribute__((format (printf, 1, 2)));
|
||||
extern char *mkpathdup(const char *fmt, ...)
|
||||
|
|
11
path.c
11
path.c
|
@ -70,19 +70,12 @@ static void vsnpath(struct strbuf *buf, const char *fmt, va_list args)
|
|||
strbuf_cleanup_path(buf);
|
||||
}
|
||||
|
||||
char *git_snpath(char *buf, size_t n, const char *fmt, ...)
|
||||
void strbuf_git_path(struct strbuf *sb, const char *fmt, ...)
|
||||
{
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnpath(&sb, fmt, args);
|
||||
vsnpath(sb, fmt, args);
|
||||
va_end(args);
|
||||
if (sb.len >= n)
|
||||
strlcpy(buf, bad_path, n);
|
||||
else
|
||||
memcpy(buf, sb.buf, sb.len + 1);
|
||||
strbuf_release(&sb);
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *git_pathdup(const char *fmt, ...)
|
||||
|
|
51
refs.c
51
refs.c
|
@ -1444,7 +1444,11 @@ static int resolve_missing_loose_ref(const char *refname,
|
|||
}
|
||||
|
||||
/* This function needs to return a meaningful errno on failure */
|
||||
const char *resolve_ref_unsafe(const char *refname, int resolve_flags, unsigned char *sha1, int *flags)
|
||||
static const char *resolve_ref_unsafe_1(const char *refname,
|
||||
int resolve_flags,
|
||||
unsigned char *sha1,
|
||||
int *flags,
|
||||
struct strbuf *sb_path)
|
||||
{
|
||||
int depth = MAXDEPTH;
|
||||
ssize_t len;
|
||||
|
@ -1475,7 +1479,7 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags, unsigned
|
|||
bad_name = 1;
|
||||
}
|
||||
for (;;) {
|
||||
char path[PATH_MAX];
|
||||
const char *path;
|
||||
struct stat st;
|
||||
char *buf;
|
||||
int fd;
|
||||
|
@ -1485,7 +1489,9 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags, unsigned
|
|||
return NULL;
|
||||
}
|
||||
|
||||
git_snpath(path, sizeof(path), "%s", refname);
|
||||
strbuf_reset(sb_path);
|
||||
strbuf_git_path(sb_path, "%s", refname);
|
||||
path = sb_path->buf;
|
||||
|
||||
/*
|
||||
* We might have to loop back here to avoid a race
|
||||
|
@ -1612,6 +1618,16 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags, unsigned
|
|||
}
|
||||
}
|
||||
|
||||
const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
|
||||
unsigned char *sha1, int *flags)
|
||||
{
|
||||
struct strbuf sb_path = STRBUF_INIT;
|
||||
const char *ret = resolve_ref_unsafe_1(refname, resolve_flags,
|
||||
sha1, flags, &sb_path);
|
||||
strbuf_release(&sb_path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *resolve_refdup(const char *ref, int resolve_flags, unsigned char *sha1, int *flags)
|
||||
{
|
||||
const char *ret = resolve_ref_unsafe(ref, resolve_flags, sha1, flags);
|
||||
|
@ -2941,11 +2957,15 @@ static int copy_msg(char *buf, const char *msg)
|
|||
}
|
||||
|
||||
/* This function must set a meaningful errno on failure */
|
||||
int log_ref_setup(const char *refname, char *logfile, int bufsize)
|
||||
int log_ref_setup(const char *refname, struct strbuf *sb_logfile)
|
||||
{
|
||||
int logfd, oflags = O_APPEND | O_WRONLY;
|
||||
char *logfile;
|
||||
|
||||
git_snpath(logfile, bufsize, "logs/%s", refname);
|
||||
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;
|
||||
if (log_all_ref_updates &&
|
||||
(starts_with(refname, "refs/heads/") ||
|
||||
starts_with(refname, "refs/remotes/") ||
|
||||
|
@ -2990,22 +3010,26 @@ int log_ref_setup(const char *refname, char *logfile, int bufsize)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int log_ref_write(const char *refname, const unsigned char *old_sha1,
|
||||
const unsigned char *new_sha1, const char *msg)
|
||||
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 logfd, result, written, oflags = O_APPEND | O_WRONLY;
|
||||
unsigned maxlen, len;
|
||||
int msglen;
|
||||
char log_file[PATH_MAX];
|
||||
const char *log_file;
|
||||
char *logrec;
|
||||
const char *committer;
|
||||
|
||||
if (log_all_ref_updates < 0)
|
||||
log_all_ref_updates = !is_bare_repository();
|
||||
|
||||
result = log_ref_setup(refname, log_file, sizeof(log_file));
|
||||
result = log_ref_setup(refname, sb_log_file);
|
||||
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);
|
||||
if (logfd < 0)
|
||||
|
@ -3038,6 +3062,15 @@ static int log_ref_write(const char *refname, const unsigned char *old_sha1,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int log_ref_write(const char *refname, const unsigned char *old_sha1,
|
||||
const unsigned char *new_sha1, const char *msg)
|
||||
{
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
int ret = log_ref_write_1(refname, old_sha1, new_sha1, msg, &sb);
|
||||
strbuf_release(&sb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int is_branch(const char *refname)
|
||||
{
|
||||
return !strcmp(refname, "HEAD") || starts_with(refname, "refs/heads/");
|
||||
|
|
2
refs.h
2
refs.h
|
@ -210,7 +210,7 @@ extern void unlock_ref(struct ref_lock *lock);
|
|||
/*
|
||||
* Setup reflog before using. Set errno to something meaningful on failure.
|
||||
*/
|
||||
int log_ref_setup(const char *refname, char *logfile, int bufsize);
|
||||
int log_ref_setup(const char *refname, struct strbuf *logfile);
|
||||
|
||||
/** Reads log for the value of ref during at_time. **/
|
||||
extern int read_ref_at(const char *refname, unsigned int flags,
|
||||
|
|
Загрузка…
Ссылка в новой задаче