@@ -424,6 +424,12 @@ be delta compressed, but larger binary media files won't be.
+
Common unit suffixes of 'k', 'm', or 'g' are supported.
+core.tempfileExpire::
+ When an attempt is made to create a temporary file that exists
+ and is older than this config value, the file will be unlinked
+ and recreated. This feature is used to ignore temporary files
+ (e.g. *.lock and *.new) remaining due to abnormal exits.
+
core.excludesFile::
Specifies the pathname to the file that contains patterns to
describe paths that are not meant to be tracked, in addition
@@ -972,6 +972,7 @@ extern size_t packed_git_window_size;
extern size_t packed_git_limit;
extern size_t delta_base_cache_limit;
extern unsigned long big_file_threshold;
+extern const char *tempfile_expire;
extern unsigned long pack_size_limit_cfg;
/*
@@ -1518,6 +1518,11 @@ static int git_default_core_config(const char *var, const char *value, void *cb)
return 0;
}
+ if (!strcmp(var, "core.tempfileexpire")) {
+ git_config_get_expiry(var, &tempfile_expire);
+ return 0;
+ }
+
if (!strcmp(var, "core.packedgitlimit")) {
packed_git_limit = git_config_ulong(var, value);
return 0;
@@ -48,6 +48,7 @@ size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE;
size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT;
size_t delta_base_cache_limit = 96 * 1024 * 1024;
unsigned long big_file_threshold = 512 * 1024 * 1024;
+const char *tempfile_expire = "1.day.ago";
int pager_use_color = 1;
const char *editor_program;
const char *askpass_program;
@@ -231,6 +231,16 @@ test_expect_success 'timeout if packed-refs.lock exists' '
test_must_fail git pack-refs --all --prune
'
+test_expect_success 'success if packed-refs.lock expires' '
+ LOCK=.git/packed-refs.lock &&
+ >"$LOCK" &&
+ test_when_finished "rm -f $LOCK" &&
+ test-tool chmtime -86000 $LOCK &&
+ test_must_fail git pack-refs --all --prune &&
+ test-tool chmtime -400 $LOCK &&
+ git pack-refs --all --prune
+'
+
test_expect_success 'retry acquiring packed-refs.lock' '
LOCK=.git/packed-refs.lock &&
>"$LOCK" &&
@@ -51,6 +51,7 @@
*/
#include "cache.h"
+#include "date.h"
#include "tempfile.h"
#include "sigchain.h"
@@ -137,6 +138,26 @@ struct tempfile *create_tempfile_mode(const char *path, int mode)
strbuf_add_absolute_path(&tempfile->filename, path);
tempfile->fd = open(tempfile->filename.buf,
O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, mode);
+ if (tempfile->fd < 0 && errno == EEXIST) {
+ struct stat st;
+ int err = errno;
+ if (lstat(tempfile->filename.buf, &st) < 0) {
+ warning_errno(_("failed to stat %s"),
+ tempfile->filename.buf);
+ errno = err;
+ } else if (st.st_mtime <= approxidate(tempfile_expire)) {
+ /*
+ * If the file is older than core.tmpfileExpire, it is
+ * probably outdated. We'll try to remove it and try
+ * again.
+ */
+ warning(_("remove outdated tempfile %s"), tempfile->filename.buf);
+ unlink_or_warn(tempfile->filename.buf);
+ tempfile->fd = open(tempfile->filename.buf,
+ O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC,
+ mode);
+ }
+ }
if (O_CLOEXEC && tempfile->fd < 0 && errno == EINVAL)
/* Try again w/o O_CLOEXEC: the kernel might not support it */
tempfile->fd = open(tempfile->filename.buf,