Log ref updates to logs/refs/<ref>
If config parameter core.logAllRefUpdates is true or the log file already exists then append a line to ".git/logs/refs/<ref>" whenever git-update-ref <ref> is executed. Each log line contains the following information: oldsha1 <SP> newsha1 <SP> committer <LF> where committer is the current user, date, time and timezone in the standard GIT ident format. If the caller is unable to append to the log file then git-update-ref will fail without updating <ref>. An optional message may be included in the log line with the -m flag. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
committed by
Junio C Hamano
parent
5b16b09021
commit
6de08ae688
56
refs.c
56
refs.c
@ -302,6 +302,7 @@ static struct ref_lock* lock_ref_sha1_basic(const char *path,
|
||||
|
||||
lock->ref_file = strdup(path);
|
||||
lock->lock_file = strdup(mkpath("%s.lock", lock->ref_file));
|
||||
lock->log_file = strdup(git_path("logs/%s", lock->ref_file + plen));
|
||||
|
||||
if (safe_create_leading_directories(lock->lock_file))
|
||||
die("unable to create directory for %s", lock->lock_file);
|
||||
@ -343,9 +344,60 @@ void unlock_ref (struct ref_lock *lock)
|
||||
free(lock->ref_file);
|
||||
if (lock->lock_file)
|
||||
free(lock->lock_file);
|
||||
if (lock->log_file)
|
||||
free(lock->log_file);
|
||||
free(lock);
|
||||
}
|
||||
|
||||
static int log_ref_write(struct ref_lock *lock,
|
||||
const unsigned char *sha1, const char *msg)
|
||||
{
|
||||
int logfd, written, oflags = O_APPEND | O_WRONLY;
|
||||
unsigned maxlen, len;
|
||||
char *logrec;
|
||||
const char *comitter;
|
||||
|
||||
if (log_all_ref_updates) {
|
||||
if (safe_create_leading_directories(lock->log_file) < 0)
|
||||
return error("unable to create directory for %s",
|
||||
lock->log_file);
|
||||
oflags |= O_CREAT;
|
||||
}
|
||||
|
||||
logfd = open(lock->log_file, oflags, 0666);
|
||||
if (logfd < 0) {
|
||||
if (!log_all_ref_updates && errno == ENOENT)
|
||||
return 0;
|
||||
return error("Unable to append to %s: %s",
|
||||
lock->log_file, strerror(errno));
|
||||
}
|
||||
|
||||
setup_ident();
|
||||
comitter = git_committer_info(1);
|
||||
if (msg) {
|
||||
maxlen = strlen(comitter) + strlen(msg) + 2*40 + 5;
|
||||
logrec = xmalloc(maxlen);
|
||||
len = snprintf(logrec, maxlen, "%s %s %s\t%s\n",
|
||||
sha1_to_hex(lock->old_sha1),
|
||||
sha1_to_hex(sha1),
|
||||
comitter,
|
||||
msg);
|
||||
} else {
|
||||
maxlen = strlen(comitter) + 2*40 + 4;
|
||||
logrec = xmalloc(maxlen);
|
||||
len = snprintf(logrec, maxlen, "%s %s %s\n",
|
||||
sha1_to_hex(lock->old_sha1),
|
||||
sha1_to_hex(sha1),
|
||||
comitter);
|
||||
}
|
||||
written = len <= maxlen ? write(logfd, logrec, len) : -1;
|
||||
free(logrec);
|
||||
close(logfd);
|
||||
if (written != len)
|
||||
return error("Unable to append to %s", lock->log_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int write_ref_sha1(struct ref_lock *lock,
|
||||
const unsigned char *sha1, const char *logmsg)
|
||||
{
|
||||
@ -364,6 +416,10 @@ int write_ref_sha1(struct ref_lock *lock,
|
||||
unlock_ref(lock);
|
||||
return -1;
|
||||
}
|
||||
if (log_ref_write(lock, sha1, logmsg) < 0) {
|
||||
unlock_ref(lock);
|
||||
return -1;
|
||||
}
|
||||
if (rename(lock->lock_file, lock->ref_file) < 0) {
|
||||
error("Couldn't set %s", lock->ref_file);
|
||||
unlock_ref(lock);
|
||||
|
||||
Reference in New Issue
Block a user