From: Junio C Hamano <gitster@pobox.com>
To: Ronnie Sahlberg <sahlberg@google.com>
Cc: Duy Nguyen <pclouds@gmail.com>,
Git Mailing List <git@vger.kernel.org>,
Jonathan Nieder <jrnieder@gmail.com>
Subject: Re: What's cooking in git.git (Sep 2014, #01; Tue, 2)
Date: Thu, 04 Sep 2014 10:25:43 -0700 [thread overview]
Message-ID: <xmqqa96fuwko.fsf@gitster.dls.corp.google.com> (raw)
In-Reply-To: <xmqqmwafux3y.fsf@gitster.dls.corp.google.com> (Junio C. Hamano's message of "Thu, 04 Sep 2014 10:14:09 -0700")
Junio C Hamano <gitster@pobox.com> writes:
> You can see the interactions by checking
>
> $ git show 'pu^{/^Merge branch .nd/multi}' refs.c
Here is how it may look like.
Merge branch 'nd/multiple-work-trees' into pu
diff --cc refs.c
index b50b329,00b2312..f04d934
--- a/refs.c
+++ b/refs.c
@@@ -1359,34 -1533,33 +1359,38 @@@ static const char *handle_missing_loose
}
}
-const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int reading, int *flag)
+/* This function needs to return a meaningful errno on failure */
+const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int flags, int *ref_flag)
{
+ struct strbuf sb_path = STRBUF_INIT;
int depth = MAXDEPTH;
ssize_t len;
char buffer[256];
static char refname_buffer[256];
+ const char *ret;
- if (flag)
- *flag = 0;
+ if (ref_flag)
+ *ref_flag = 0;
- if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL))
+ if (!(flags & RESOLVE_REF_ALLOW_BAD_NAME) &&
+ check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
+ errno = EINVAL;
return NULL;
-
+ }
for (;;) {
- char path[PATH_MAX];
+ const char *path;
struct stat st;
char *buf;
int fd;
- if (--depth < 0)
+ if (--depth < 0) {
+ errno = ELOOP;
- return NULL;
+ goto fail;
+ }
- 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
@@@ -1400,11 -1573,11 +1404,12 @@@
stat_ref:
if (lstat(path, &st) < 0) {
if (errno == ENOENT)
- return handle_missing_loose_ref(refname, sha1,
+ ret = handle_missing_loose_ref(refname, sha1,
- reading, flag);
+ flags & RESOLVE_REF_READING,
+ ref_flag);
else
- return NULL;
+ ret = NULL;
+ goto done;
}
/* Follow "normalized" - ie "refs/.." symlinks by hand */
@@@ -1444,16 -1617,13 +1449,17 @@@
/* inconsistent with lstat; retry */
goto stat_ref;
else
- return NULL;
+ goto fail;
}
+
len = read_in_full(fd, buffer, sizeof(buffer)-1);
- close(fd);
- if (len < 0)
+ if (len < 0) {
+ int save_errno = errno;
+ close(fd);
+ errno = save_errno;
- return NULL;
+ goto fail;
+ }
+ close(fd);
while (len && isspace(buffer[len-1]))
len--;
buffer[len] = '\0';
@@@ -1468,31 -1638,35 +1474,37 @@@
*/
if (get_sha1_hex(buffer, sha1) ||
(buffer[40] != '\0' && !isspace(buffer[40]))) {
- if (flag)
- *flag |= REF_ISBROKEN;
+ if (ref_flag)
+ *ref_flag |= REF_ISBROKEN;
+ errno = EINVAL;
- return NULL;
+ goto fail;
}
- return refname;
+ ret = refname;
+ goto done;
}
- if (flag)
- *flag |= REF_ISSYMREF;
+ if (ref_flag)
+ *ref_flag |= REF_ISSYMREF;
buf = buffer + 4;
while (isspace(*buf))
buf++;
if (check_refname_format(buf, REFNAME_ALLOW_ONELEVEL)) {
- if (flag)
- *flag |= REF_ISBROKEN;
+ if (ref_flag)
+ *ref_flag |= REF_ISBROKEN;
+ errno = EINVAL;
- return NULL;
+ goto fail;
}
refname = strcpy(refname_buffer, buf);
}
+ fail:
+ ret = NULL;
+ done:
+ strbuf_release(&sb_path);
+ return ret;
}
-char *resolve_refdup(const char *ref, unsigned char *sha1, int reading, int *flag)
+char *resolve_refdup(const char *ref, unsigned char *sha1, int flags, int *ref_flag)
{
- const char *ret = resolve_ref_unsafe(ref, sha1, reading, flag);
+ const char *ret = resolve_ref_unsafe(ref, sha1, flags, ref_flag);
return ret ? xstrdup(ret) : NULL;
}
@@@ -2106,16 -2263,11 +2118,16 @@@ int dwim_log(const char *str, int len,
return logs_found;
}
+/*
+ * Locks a "refs/" ref returning the lock on success and NULL on failure.
+ * On failure errno is set to something meaningful.
+ */
static struct ref_lock *lock_ref_sha1_basic(const char *refname,
const unsigned char *old_sha1,
- int flags, int *type_p)
+ int flags, int *type_p,
+ const char **skip, int skipnum)
{
- char *ref_file;
+ const char *ref_file;
const char *orig_refname = refname;
struct ref_lock *lock;
int last_errno = 0;
@@@ -2750,52 -2952,41 +2762,57 @@@ static int copy_msg(char *buf, const ch
return cp - buf;
}
-int log_ref_setup(const char *refname, struct strbuf *logfile)
+/* This function must set a meaningful errno on failure */
+int create_reflog(const char *refname)
{
int logfd, oflags = O_APPEND | O_WRONLY;
- char logfile[PATH_MAX];
-
- git_snpath(logfile, sizeof(logfile), "logs/%s", refname);
- if (starts_with(refname, "refs/heads/") ||
- starts_with(refname, "refs/remotes/") ||
- starts_with(refname, "refs/notes/") ||
- !strcmp(refname, "HEAD")) {
- if (safe_create_leading_directories(logfile) < 0) {
++ struct strbuf logfile = STRBUF_INIT;
+
- strbuf_git_path(logfile, "logs/%s", refname);
++ strbuf_git_path(&logfile, "logs/%s", refname);
+ if (log_all_ref_updates &&
+ (starts_with(refname, "refs/heads/") ||
+ starts_with(refname, "refs/remotes/") ||
+ starts_with(refname, "refs/notes/") ||
+ !strcmp(refname, "HEAD"))) {
- if (safe_create_leading_directories(logfile->buf) < 0)
- return error("unable to create directory for %s",
- logfile->buf);
++ if (safe_create_leading_directories(logfile.buf) < 0) {
+ int save_errno = errno;
- error("unable to create directory for %s", logfile);
++ error("unable to create directory for %s", logfile.buf);
++ strbuf_release(&logfile);
+ errno = save_errno;
+ return -1;
+ }
oflags |= O_CREAT;
}
- logfd = open(logfile, oflags, 0666);
- logfd = open(logfile->buf, oflags, 0666);
++ logfd = open(logfile.buf, oflags, 0666);
if (logfd < 0) {
if (!(oflags & O_CREAT) && errno == ENOENT)
return 0;
if ((oflags & O_CREAT) && errno == EISDIR) {
- if (remove_empty_directories(logfile)) {
- if (remove_empty_directories(logfile->buf)) {
- return error("There are still logs under '%s'",
- logfile->buf);
++ if (remove_empty_directories(logfile.buf)) {
+ int save_errno = errno;
+ error("There are still logs under '%s'",
- logfile);
++ logfile.buf);
++ strbuf_release(&logfile);
+ errno = save_errno;
+ return -1;
}
- logfd = open(logfile, oflags, 0666);
- logfd = open(logfile->buf, oflags, 0666);
++ logfd = open(logfile.buf, oflags, 0666);
}
- if (logfd < 0)
- return error("Unable to append to %s: %s",
- logfile->buf, strerror(errno));
+ if (logfd < 0) {
+ int save_errno = errno;
- error("Unable to append to %s: %s", logfile,
++ error("Unable to append to %s: %s", logfile.buf,
+ strerror(errno));
++ strbuf_release(&logfile);
+ errno = save_errno;
+ return -1;
+ }
}
- adjust_shared_perm(logfile);
- adjust_shared_perm(logfile->buf);
++ adjust_shared_perm(logfile.buf);
++ strbuf_release(&logfile);
close(logfd);
return 0;
}
@@@ -2817,54 -3023,18 +2834,58 @@@ static int log_ref_write_fd(int fd, con
committer);
if (msglen)
len += copy_msg(logrec + len - 1, msg) - 1;
- written = len <= maxlen ? write_in_full(logfd, logrec, len) : -1;
+
+ written = len <= maxlen ? write_in_full(fd, logrec, len) : -1;
free(logrec);
- if (close(logfd) != 0 || written != len) {
- error("Unable to append to %s", log_file);
- result = -1;
- }
-done:
- strbuf_release(&sb_log_file);
- return result;
+ if (written != len)
+ return -1;
+
+ return 0;
+}
+
+static int log_ref_write(const char *refname, const unsigned char *old_sha1,
+ const unsigned char *new_sha1, const char *msg)
+{
+ int logfd, result = 0, oflags = O_APPEND | O_WRONLY;
- char log_file[PATH_MAX];
++ struct strbuf logfile = STRBUF_INIT;
++ int status = 0;
+
+ if (log_all_ref_updates < 0)
+ log_all_ref_updates = !is_bare_repository();
+
+ if (log_all_ref_updates && !reflog_exists(refname))
+ result = create_reflog(refname);
+
+ if (result)
+ return result;
+
- git_snpath(log_file, sizeof(log_file), "logs/%s", refname);
++ strbuf_git_path(&logfile, "logs/%s", refname);
+
- logfd = open(log_file, oflags);
++ logfd = open(logfile.buf, oflags);
+ if (logfd < 0)
- return 0;
++ goto fini;
+ result = log_ref_write_fd(logfd, old_sha1, new_sha1,
+ git_committer_info(0), msg);
+ if (result) {
+ int save_errno = errno;
+ close(logfd);
- error("Unable to append to %s", log_file);
++ error("Unable to append to %s", logfile.buf);
+ errno = save_errno;
- return -1;
++ status = -1;
++ goto fini;
+ }
+ if (close(logfd)) {
+ int save_errno = errno;
- error("Unable to append to %s", log_file);
++ error("Unable to append to %s", logfile.buf);
+ errno = save_errno;
- return -1;
++ status = -1;
+ }
- return 0;
++fini:
++ strbuf_release(&logfile);
++ return status;
}
-static int is_branch(const char *refname)
+int is_branch(const char *refname)
{
return !strcmp(refname, "HEAD") || starts_with(refname, "refs/heads/");
}
next prev parent reply other threads:[~2014-09-04 17:26 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-02 22:06 What's cooking in git.git (Sep 2014, #01; Tue, 2) Junio C Hamano
2014-09-03 6:27 ` Johannes Sixt
2014-09-03 18:45 ` Torsten Bögershausen
2014-09-03 19:18 ` Junio C Hamano
2014-09-03 19:30 ` Keller, Jacob E
2014-09-04 13:46 ` Duy Nguyen
2014-09-04 16:51 ` Junio C Hamano
2014-09-04 17:14 ` Junio C Hamano
2014-09-04 17:25 ` Junio C Hamano [this message]
2014-09-05 1:18 ` Duy Nguyen
2014-09-05 0:47 ` Duy Nguyen
2015-03-26 13:46 ` Tommy38
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqqa96fuwko.fsf@gitster.dls.corp.google.com \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=jrnieder@gmail.com \
--cc=pclouds@gmail.com \
--cc=sahlberg@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).