mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-13 23:05:27 +00:00
Merge pull request #3170 from CmdrMoozy/nsec_fix
git_index_entry__init_from_stat: set nsec fields in entry stats
This commit is contained in:
commit
75a0ccf52f
@ -20,6 +20,7 @@ SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Mo
|
|||||||
|
|
||||||
INCLUDE(CheckLibraryExists)
|
INCLUDE(CheckLibraryExists)
|
||||||
INCLUDE(CheckFunctionExists)
|
INCLUDE(CheckFunctionExists)
|
||||||
|
INCLUDE(CheckStructHasMember)
|
||||||
INCLUDE(AddCFlagIfSupported)
|
INCLUDE(AddCFlagIfSupported)
|
||||||
INCLUDE(FindPkgConfig)
|
INCLUDE(FindPkgConfig)
|
||||||
|
|
||||||
@ -85,6 +86,12 @@ IF (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
|||||||
OPTION( USE_OPENSSL "Link with and use openssl library" ON )
|
OPTION( USE_OPENSSL "Link with and use openssl library" ON )
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtim.tv_nsec sys/stat.h
|
||||||
|
HAVE_STRUCT_STAT_NSEC LANGUAGE C)
|
||||||
|
IF(HAVE_STRUCT_STAT_NSEC OR WIN32)
|
||||||
|
OPTION( USE_NSEC "Care about sub-second file mtimes and ctimes" OFF )
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
# This variable will contain the libraries we need to put into
|
# This variable will contain the libraries we need to put into
|
||||||
# libgit2.pc's Requires.private. That is, what we're linking to or
|
# libgit2.pc's Requires.private. That is, what we're linking to or
|
||||||
# what someone who's statically linking us needs to link to.
|
# what someone who's statically linking us needs to link to.
|
||||||
@ -516,6 +523,10 @@ IF (THREADSAFE)
|
|||||||
ADD_DEFINITIONS(-DGIT_THREADS)
|
ADD_DEFINITIONS(-DGIT_THREADS)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
IF (USE_NSEC)
|
||||||
|
ADD_DEFINITIONS(-DGIT_USE_NSEC)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
|
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
|
||||||
|
|
||||||
# Collect sourcefiles
|
# Collect sourcefiles
|
||||||
|
@ -101,8 +101,9 @@ GIT_EXTERN(void) git_libgit2_version(int *major, int *minor, int *rev);
|
|||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GIT_FEATURE_THREADS = (1 << 0),
|
GIT_FEATURE_THREADS = (1 << 0),
|
||||||
GIT_FEATURE_HTTPS = (1 << 1),
|
GIT_FEATURE_HTTPS = (1 << 1),
|
||||||
GIT_FEATURE_SSH = (1 << 2),
|
GIT_FEATURE_SSH = (1 << 2),
|
||||||
|
GIT_FEATURE_NSEC = (1 << 3),
|
||||||
} git_feature_t;
|
} git_feature_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
# include <ws2tcpip.h>
|
# include <ws2tcpip.h>
|
||||||
# include "win32/msvc-compat.h"
|
# include "win32/msvc-compat.h"
|
||||||
# include "win32/mingw-compat.h"
|
# include "win32/mingw-compat.h"
|
||||||
|
# include "win32/win32-compat.h"
|
||||||
# include "win32/error.h"
|
# include "win32/error.h"
|
||||||
# include "win32/version.h"
|
# include "win32/version.h"
|
||||||
# ifdef GIT_THREADS
|
# ifdef GIT_THREADS
|
||||||
|
31
src/diff.c
31
src/diff.c
@ -706,6 +706,31 @@ static bool diff_time_eq(
|
|||||||
(!use_nanos || a->nanoseconds == b->nanoseconds);
|
(!use_nanos || a->nanoseconds == b->nanoseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test if the given index time is newer than the given existing index entry.
|
||||||
|
* If the timestamps are exactly equivalent, then the given index time is
|
||||||
|
* considered "racily newer" than the existing index entry.
|
||||||
|
*/
|
||||||
|
static bool diff_newer_than_index(
|
||||||
|
const git_index_time *a, const git_index *b, bool use_nanos)
|
||||||
|
{
|
||||||
|
bool is_newer = false;
|
||||||
|
|
||||||
|
if(!b)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
is_newer = is_newer || (a->seconds > (int32_t) b->stamp.mtime.tv_sec);
|
||||||
|
is_newer = is_newer || (!use_nanos &&
|
||||||
|
(a->seconds == (int32_t) b->stamp.mtime.tv_sec));
|
||||||
|
if(use_nanos)
|
||||||
|
{
|
||||||
|
is_newer = is_newer || ((a->seconds == (int32_t) b->stamp.mtime.tv_sec) &&
|
||||||
|
(a->nanoseconds >= (uint32_t) b->stamp.mtime.tv_nsec));
|
||||||
|
}
|
||||||
|
|
||||||
|
return is_newer;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
git_repository *repo;
|
git_repository *repo;
|
||||||
git_iterator *old_iter;
|
git_iterator *old_iter;
|
||||||
@ -838,7 +863,11 @@ static int maybe_modified(
|
|||||||
*/
|
*/
|
||||||
} else if (git_oid_iszero(&nitem->id) && new_is_workdir) {
|
} else if (git_oid_iszero(&nitem->id) && new_is_workdir) {
|
||||||
bool use_ctime = ((diff->diffcaps & GIT_DIFFCAPS_TRUST_CTIME) != 0);
|
bool use_ctime = ((diff->diffcaps & GIT_DIFFCAPS_TRUST_CTIME) != 0);
|
||||||
|
#ifdef GIT_USE_NSEC
|
||||||
bool use_nanos = ((diff->diffcaps & GIT_DIFFCAPS_TRUST_NANOSECS) != 0);
|
bool use_nanos = ((diff->diffcaps & GIT_DIFFCAPS_TRUST_NANOSECS) != 0);
|
||||||
|
#else
|
||||||
|
bool use_nanos = false;
|
||||||
|
#endif
|
||||||
git_index *index;
|
git_index *index;
|
||||||
git_iterator_index(&index, info->new_iter);
|
git_iterator_index(&index, info->new_iter);
|
||||||
|
|
||||||
@ -863,7 +892,7 @@ static int maybe_modified(
|
|||||||
oitem->ino != nitem->ino ||
|
oitem->ino != nitem->ino ||
|
||||||
oitem->uid != nitem->uid ||
|
oitem->uid != nitem->uid ||
|
||||||
oitem->gid != nitem->gid ||
|
oitem->gid != nitem->gid ||
|
||||||
(index && nitem->mtime.seconds >= index->stamp.mtime))
|
diff_newer_than_index(&nitem->mtime, index, use_nanos))
|
||||||
{
|
{
|
||||||
status = GIT_DELTA_MODIFIED;
|
status = GIT_DELTA_MODIFIED;
|
||||||
modified_uncertain = true;
|
modified_uncertain = true;
|
||||||
|
@ -1034,6 +1034,11 @@ int git_futils_filestamp_check(
|
|||||||
git_futils_filestamp *stamp, const char *path)
|
git_futils_filestamp *stamp, const char *path)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
const struct timespec *statmtime = &st.st_mtimespec;
|
||||||
|
#else
|
||||||
|
const struct timespec *statmtime = &st.st_mtim;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* if the stamp is NULL, then always reload */
|
/* if the stamp is NULL, then always reload */
|
||||||
if (stamp == NULL)
|
if (stamp == NULL)
|
||||||
@ -1042,12 +1047,18 @@ int git_futils_filestamp_check(
|
|||||||
if (p_stat(path, &st) < 0)
|
if (p_stat(path, &st) < 0)
|
||||||
return GIT_ENOTFOUND;
|
return GIT_ENOTFOUND;
|
||||||
|
|
||||||
if (stamp->mtime == (git_time_t)st.st_mtime &&
|
if (stamp->mtime.tv_sec == statmtime->tv_sec &&
|
||||||
|
#if defined(GIT_USE_NSEC)
|
||||||
|
stamp->mtime.tv_nsec == statmtime->tv_nsec &&
|
||||||
|
#endif
|
||||||
stamp->size == (git_off_t)st.st_size &&
|
stamp->size == (git_off_t)st.st_size &&
|
||||||
stamp->ino == (unsigned int)st.st_ino)
|
stamp->ino == (unsigned int)st.st_ino)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
stamp->mtime = (git_time_t)st.st_mtime;
|
stamp->mtime.tv_sec = statmtime->tv_sec;
|
||||||
|
#if defined(GIT_USE_NSEC)
|
||||||
|
stamp->mtime.tv_nsec = statmtime->tv_nsec;
|
||||||
|
#endif
|
||||||
stamp->size = (git_off_t)st.st_size;
|
stamp->size = (git_off_t)st.st_size;
|
||||||
stamp->ino = (unsigned int)st.st_ino;
|
stamp->ino = (unsigned int)st.st_ino;
|
||||||
|
|
||||||
@ -1069,8 +1080,17 @@ void git_futils_filestamp_set(
|
|||||||
void git_futils_filestamp_set_from_stat(
|
void git_futils_filestamp_set_from_stat(
|
||||||
git_futils_filestamp *stamp, struct stat *st)
|
git_futils_filestamp *stamp, struct stat *st)
|
||||||
{
|
{
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
const struct timespec *statmtime = &st->st_mtimespec;
|
||||||
|
#else
|
||||||
|
const struct timespec *statmtime = &st->st_mtim;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (st) {
|
if (st) {
|
||||||
stamp->mtime = (git_time_t)st->st_mtime;
|
stamp->mtime = *statmtime;
|
||||||
|
#if !defined(GIT_USE_NSEC)
|
||||||
|
stamp->mtime.tv_nsec = 0;
|
||||||
|
#endif
|
||||||
stamp->size = (git_off_t)st->st_size;
|
stamp->size = (git_off_t)st->st_size;
|
||||||
stamp->ino = (unsigned int)st->st_ino;
|
stamp->ino = (unsigned int)st->st_ino;
|
||||||
} else {
|
} else {
|
||||||
|
@ -310,7 +310,7 @@ extern int git_futils_fake_symlink(const char *new, const char *old);
|
|||||||
* versions could be implemented in the future.
|
* versions could be implemented in the future.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
git_time_t mtime;
|
struct timespec mtime;
|
||||||
git_off_t size;
|
git_off_t size;
|
||||||
unsigned int ino;
|
unsigned int ino;
|
||||||
} git_futils_filestamp;
|
} git_futils_filestamp;
|
||||||
|
24
src/index.c
24
src/index.c
@ -719,18 +719,27 @@ int git_index__changed_relative_to(
|
|||||||
return !!git_oid_cmp(&index->checksum, checksum);
|
return !!git_oid_cmp(&index->checksum, checksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_racy_timestamp(git_time_t stamp, git_index_entry *entry)
|
static bool is_racy_timestamp(const struct timespec *stamp, git_index_entry *entry)
|
||||||
{
|
{
|
||||||
/* Git special-cases submodules in the check */
|
/* Git special-cases submodules in the check */
|
||||||
if (S_ISGITLINK(entry->mode))
|
if (S_ISGITLINK(entry->mode))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* If we never read the index, we can't have this race either */
|
/* If we never read the index, we can't have this race either */
|
||||||
if (stamp == 0)
|
if(stamp->tv_sec == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* If the timestamp is the same or newer than the index, it's racy */
|
/* If the timestamp is the same or newer than the index, it's racy */
|
||||||
return ((int32_t) stamp) <= entry->mtime.seconds;
|
#if defined(GIT_USE_NSEC)
|
||||||
|
if((int32_t) stamp->tv_sec < entry->mtime.seconds)
|
||||||
|
return true;
|
||||||
|
else if((int32_t) stamp->tv_sec > entry->mtime.seconds)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return (uint32_t) stamp->tv_nsec <= entry->mtime.nanoseconds;
|
||||||
|
#else
|
||||||
|
return ((int32_t) stamp->tv_sec) <= entry->mtime.seconds;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -742,7 +751,6 @@ static int truncate_racily_clean(git_index *index)
|
|||||||
size_t i;
|
size_t i;
|
||||||
int error;
|
int error;
|
||||||
git_index_entry *entry;
|
git_index_entry *entry;
|
||||||
git_time_t ts = index->stamp.mtime;
|
|
||||||
git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
|
git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
|
||||||
git_diff *diff;
|
git_diff *diff;
|
||||||
|
|
||||||
@ -756,7 +764,7 @@ static int truncate_racily_clean(git_index *index)
|
|||||||
|
|
||||||
diff_opts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE | GIT_DIFF_IGNORE_SUBMODULES | GIT_DIFF_DISABLE_PATHSPEC_MATCH;
|
diff_opts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE | GIT_DIFF_IGNORE_SUBMODULES | GIT_DIFF_DISABLE_PATHSPEC_MATCH;
|
||||||
git_vector_foreach(&index->entries, i, entry) {
|
git_vector_foreach(&index->entries, i, entry) {
|
||||||
if (!is_racy_timestamp(ts, entry))
|
if (!is_racy_timestamp(&index->stamp.mtime, entry))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* TODO: use the (non-fnmatching) filelist iterator */
|
/* TODO: use the (non-fnmatching) filelist iterator */
|
||||||
@ -858,8 +866,10 @@ void git_index_entry__init_from_stat(
|
|||||||
{
|
{
|
||||||
entry->ctime.seconds = (git_time_t)st->st_ctime;
|
entry->ctime.seconds = (git_time_t)st->st_ctime;
|
||||||
entry->mtime.seconds = (git_time_t)st->st_mtime;
|
entry->mtime.seconds = (git_time_t)st->st_mtime;
|
||||||
/* entry->mtime.nanoseconds = st->st_mtimensec; */
|
#if defined(GIT_USE_NSEC)
|
||||||
/* entry->ctime.nanoseconds = st->st_ctimensec; */
|
entry->mtime.nanoseconds = st->st_mtim.tv_nsec;
|
||||||
|
entry->ctime.nanoseconds = st->st_ctim.tv_nsec;
|
||||||
|
#endif
|
||||||
entry->dev = st->st_rdev;
|
entry->dev = st->st_rdev;
|
||||||
entry->ino = st->st_ino;
|
entry->ino = st->st_ino;
|
||||||
entry->mode = (!trust_mode && S_ISREG(st->st_mode)) ?
|
entry->mode = (!trust_mode && S_ISREG(st->st_mode)) ?
|
||||||
|
@ -33,6 +33,9 @@ int git_libgit2_features()
|
|||||||
#endif
|
#endif
|
||||||
#if defined(GIT_SSH)
|
#if defined(GIT_SSH)
|
||||||
| GIT_FEATURE_SSH
|
| GIT_FEATURE_SSH
|
||||||
|
#endif
|
||||||
|
#if defined(GIT_USE_NSEC)
|
||||||
|
| GIT_FEATURE_NSEC
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,6 @@
|
|||||||
|
|
||||||
#undef stat
|
#undef stat
|
||||||
|
|
||||||
#if _WIN32_WINNT >= 0x0601
|
|
||||||
#define stat __stat64
|
|
||||||
#else
|
|
||||||
#define stat _stati64
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if _WIN32_WINNT < 0x0600 && !defined(__MINGW64_VERSION_MAJOR)
|
#if _WIN32_WINNT < 0x0600 && !defined(__MINGW64_VERSION_MAJOR)
|
||||||
#undef MemoryBarrier
|
#undef MemoryBarrier
|
||||||
void __mingworg_MemoryBarrier(void);
|
void __mingworg_MemoryBarrier(void);
|
||||||
|
@ -9,9 +9,6 @@
|
|||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
/* 64-bit stat information, regardless of USE_32BIT_TIME_T define */
|
|
||||||
#define stat __stat64
|
|
||||||
|
|
||||||
typedef unsigned short mode_t;
|
typedef unsigned short mode_t;
|
||||||
typedef SSIZE_T ssize_t;
|
typedef SSIZE_T ssize_t;
|
||||||
|
|
||||||
|
@ -76,17 +76,23 @@ size_t git_win32__path_trim_end(wchar_t *str, size_t len);
|
|||||||
size_t git_win32__canonicalize_path(wchar_t *str, size_t len);
|
size_t git_win32__canonicalize_path(wchar_t *str, size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a FILETIME structure to a time_t.
|
* Converts a FILETIME structure to a struct timespec.
|
||||||
*
|
*
|
||||||
* @param FILETIME A pointer to a FILETIME
|
* @param FILETIME A pointer to a FILETIME
|
||||||
* @return A time_t containing the same time
|
* @param ts A pointer to the timespec structure to fill in
|
||||||
*/
|
*/
|
||||||
GIT_INLINE(time_t) git_win32__filetime_to_time_t(const FILETIME *ft)
|
GIT_INLINE(void) git_win32__filetime_to_timespec(
|
||||||
|
const FILETIME *ft,
|
||||||
|
struct timespec *ts)
|
||||||
{
|
{
|
||||||
long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
|
long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
|
||||||
winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */
|
winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */
|
||||||
winTime /= 10000000; /* Nano to seconds resolution */
|
ts->tv_sec = (time_t)(winTime / 10000000);
|
||||||
return (time_t)winTime;
|
#ifdef GIT_USE_NSEC
|
||||||
|
ts->tv_nsec = (winTime % 10000000) * 100;
|
||||||
|
#else
|
||||||
|
ts->tv_nsec = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
GIT_INLINE(void) git_win32__timeval_to_filetime(
|
GIT_INLINE(void) git_win32__timeval_to_filetime(
|
||||||
@ -122,9 +128,9 @@ GIT_INLINE(int) git_win32__file_attribute_to_stat(
|
|||||||
st->st_size = ((git_off_t)attrdata->nFileSizeHigh << 32) + attrdata->nFileSizeLow;
|
st->st_size = ((git_off_t)attrdata->nFileSizeHigh << 32) + attrdata->nFileSizeLow;
|
||||||
st->st_dev = _getdrive() - 1;
|
st->st_dev = _getdrive() - 1;
|
||||||
st->st_rdev = st->st_dev;
|
st->st_rdev = st->st_dev;
|
||||||
st->st_atime = git_win32__filetime_to_time_t(&(attrdata->ftLastAccessTime));
|
git_win32__filetime_to_timespec(&(attrdata->ftLastAccessTime), &(st->st_atim));
|
||||||
st->st_mtime = git_win32__filetime_to_time_t(&(attrdata->ftLastWriteTime));
|
git_win32__filetime_to_timespec(&(attrdata->ftLastWriteTime), &(st->st_mtim));
|
||||||
st->st_ctime = git_win32__filetime_to_time_t(&(attrdata->ftCreationTime));
|
git_win32__filetime_to_timespec(&(attrdata->ftCreationTime), &(st->st_ctim));
|
||||||
|
|
||||||
if (attrdata->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && path) {
|
if (attrdata->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && path) {
|
||||||
git_win32_path target;
|
git_win32_path target;
|
||||||
|
42
src/win32/win32-compat.h
Normal file
42
src/win32/win32-compat.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||||
|
* a Linking Exception. For full terms see the included COPYING file.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDE_win32_compat__
|
||||||
|
#define INCLUDE_win32_compat__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
struct p_timespec {
|
||||||
|
time_t tv_sec;
|
||||||
|
long tv_nsec;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define timespec p_timespec
|
||||||
|
|
||||||
|
struct p_stat {
|
||||||
|
_dev_t st_dev;
|
||||||
|
_ino_t st_ino;
|
||||||
|
mode_t st_mode;
|
||||||
|
short st_nlink;
|
||||||
|
short st_uid;
|
||||||
|
short st_gid;
|
||||||
|
_dev_t st_rdev;
|
||||||
|
uint64_t st_size;
|
||||||
|
struct timespec st_atim;
|
||||||
|
struct timespec st_mtim;
|
||||||
|
struct timespec st_ctim;
|
||||||
|
#define st_atime st_atim.tv_sec
|
||||||
|
#define st_mtime st_mtim.tv_sec
|
||||||
|
#define st_ctime st_ctim.tv_sec
|
||||||
|
};
|
||||||
|
|
||||||
|
#define stat p_stat
|
||||||
|
|
||||||
|
#endif /* INCLUDE_win32_compat__ */
|
@ -132,7 +132,7 @@ int checkout_count_callback(
|
|||||||
|
|
||||||
void tick_index(git_index *index)
|
void tick_index(git_index *index)
|
||||||
{
|
{
|
||||||
git_time_t ts;
|
struct timespec ts;
|
||||||
struct timeval times[2];
|
struct timeval times[2];
|
||||||
|
|
||||||
cl_assert(index->on_disk);
|
cl_assert(index->on_disk);
|
||||||
@ -141,10 +141,10 @@ void tick_index(git_index *index)
|
|||||||
cl_git_pass(git_index_read(index, true));
|
cl_git_pass(git_index_read(index, true));
|
||||||
ts = index->stamp.mtime;
|
ts = index->stamp.mtime;
|
||||||
|
|
||||||
times[0].tv_sec = ts;
|
times[0].tv_sec = ts.tv_sec;
|
||||||
times[0].tv_usec = 0;
|
times[0].tv_usec = ts.tv_nsec / 1000;
|
||||||
times[1].tv_sec = ts + 5;
|
times[1].tv_sec = ts.tv_sec + 5;
|
||||||
times[1].tv_usec = 0;
|
times[1].tv_usec = ts.tv_nsec / 1000;
|
||||||
|
|
||||||
cl_git_pass(p_utimes(git_index_path(index), times));
|
cl_git_pass(p_utimes(git_index_path(index), times));
|
||||||
cl_git_pass(git_index_read(index, true));
|
cl_git_pass(git_index_read(index, true));
|
||||||
|
@ -28,4 +28,10 @@ void test_core_features__0(void)
|
|||||||
#else
|
#else
|
||||||
cl_assert((caps & GIT_FEATURE_SSH) == 0);
|
cl_assert((caps & GIT_FEATURE_SSH) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(GIT_USE_NSEC)
|
||||||
|
cl_assert((caps & GIT_FEATURE_NSEC) != 0);
|
||||||
|
#else
|
||||||
|
cl_assert((caps & GIT_FEATURE_NSEC) == 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -63,10 +63,10 @@ void test_index_racy__write_index_just_after_file(void)
|
|||||||
cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "A"));
|
cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "A"));
|
||||||
cl_git_mkfile(path.ptr, "A");
|
cl_git_mkfile(path.ptr, "A");
|
||||||
/* Force the file's timestamp to be a second after we wrote the index */
|
/* Force the file's timestamp to be a second after we wrote the index */
|
||||||
times[0].tv_sec = index->stamp.mtime + 1;
|
times[0].tv_sec = index->stamp.mtime.tv_sec + 1;
|
||||||
times[0].tv_usec = 0;
|
times[0].tv_usec = index->stamp.mtime.tv_nsec / 1000;
|
||||||
times[1].tv_sec = index->stamp.mtime + 1;
|
times[1].tv_sec = index->stamp.mtime.tv_sec + 1;
|
||||||
times[1].tv_usec = 0;
|
times[1].tv_usec = index->stamp.mtime.tv_nsec / 1000;
|
||||||
cl_git_pass(p_utimes(path.ptr, times));
|
cl_git_pass(p_utimes(path.ptr, times));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -82,10 +82,10 @@ void test_index_racy__write_index_just_after_file(void)
|
|||||||
* Pretend this index' modification happend a second after the
|
* Pretend this index' modification happend a second after the
|
||||||
* file update, and rewrite the file in that same second.
|
* file update, and rewrite the file in that same second.
|
||||||
*/
|
*/
|
||||||
times[0].tv_sec = index->stamp.mtime + 2;
|
times[0].tv_sec = index->stamp.mtime.tv_sec + 2;
|
||||||
times[0].tv_usec = 0;
|
times[0].tv_usec = index->stamp.mtime.tv_nsec / 1000;
|
||||||
times[1].tv_sec = index->stamp.mtime + 2;
|
times[1].tv_sec = index->stamp.mtime.tv_sec + 2;
|
||||||
times[0].tv_usec = 0;
|
times[0].tv_usec = index->stamp.mtime.tv_nsec / 1000;
|
||||||
|
|
||||||
cl_git_pass(p_utimes(git_index_path(index), times));
|
cl_git_pass(p_utimes(git_index_path(index), times));
|
||||||
cl_git_pass(p_utimes(path.ptr, times));
|
cl_git_pass(p_utimes(path.ptr, times));
|
||||||
|
@ -163,9 +163,14 @@ static void hack_index(char *files[])
|
|||||||
cl_git_pass(p_stat(path.ptr, &statbuf));
|
cl_git_pass(p_stat(path.ptr, &statbuf));
|
||||||
|
|
||||||
entry->ctime.seconds = (git_time_t)statbuf.st_ctime;
|
entry->ctime.seconds = (git_time_t)statbuf.st_ctime;
|
||||||
entry->ctime.nanoseconds = 0;
|
|
||||||
entry->mtime.seconds = (git_time_t)statbuf.st_mtime;
|
entry->mtime.seconds = (git_time_t)statbuf.st_mtime;
|
||||||
|
#if defined(GIT_USE_NSEC)
|
||||||
|
entry->ctime.nanoseconds = statbuf.st_ctim.tv_nsec;
|
||||||
|
entry->mtime.nanoseconds = statbuf.st_mtim.tv_nsec;
|
||||||
|
#else
|
||||||
|
entry->ctime.nanoseconds = 0;
|
||||||
entry->mtime.nanoseconds = 0;
|
entry->mtime.nanoseconds = 0;
|
||||||
|
#endif
|
||||||
entry->dev = statbuf.st_dev;
|
entry->dev = statbuf.st_dev;
|
||||||
entry->ino = statbuf.st_ino;
|
entry->ino = statbuf.st_ino;
|
||||||
entry->uid = statbuf.st_uid;
|
entry->uid = statbuf.st_uid;
|
||||||
|
Loading…
Reference in New Issue
Block a user