-
Notifications
You must be signed in to change notification settings - Fork 2.5k
git_index_entry__init_from_stat: set nsec fields in entry stats #3170
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
/* entry->mtime.nanoseconds = st->st_mtimensec; */ | ||
/* entry->ctime.nanoseconds = st->st_ctimensec; */ | ||
#if !defined(GIT_WIN32) && !defined(__APPLE__) | ||
/* Apple and Windows doesn't provide these struct stat fields. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do Solaris or the BSDs provide these fields? It feels like what you're really trying to look for is a recent GNU libc on Linux which should be checked for explicitly, not by assuming there are three OSs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Furthermore, shouldn't we be reading these only if GIT_USE_NSEC
is defined? I think it would turn out cleaner if we only offer the USE_NSEC
option when building under Linux and remove the OS checks inside the libgit2 code. If we add support for this in Windows, we'd add it inside the compat layer as well, so we likely wouldn't have to change the code here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, yep, you're right. The BSD's seem to support these fields (at least, FreeBSD and OpenBSD), however Solaris doesn't seem to. Perhaps we should enable the USE_NSEC option based upon some CMake feature check determining that these struct stat
members are present?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. Certainly struct __stat64
on Windows has the nanoseconds
field. It would be nice if USE_NSEC
Just Worked there.
I think with this new commit we'll behave correctly everywhere but on Windows ( |
@ethomson Glancing at the MSDN docs, it seems that |
Yes, I must have been making that up. More importantly, we don't even call the win32 I had been thinking that this was basically a matter of not So anyway, you're welcome to dig in (see |
@CmdrMoozy it seems that NTFS doesn't record nano-seconds.
Mike Kelly has a rather old blog post about it on MSDN for reference. |
Thanks, @ethomson and @whoisj! I'm thinking that the cleanest thing to do to support sub-second time resolution (looks like 100ns is the best we'll get) on Windows is to define our own This is a bit hacky, but it does keep the hackiness and OS-conditionals confined to posix.h and CMake. Unfortunately, this would mean replacing instances if Does this sound like a reasonable approach? |
I think this is reasonable and this is roughly how I would approach it. However, I wonder if we might be able to take advantage of the fact that |
Thats exactly what I did for Git for Windows (see kblees/git@1fd19e8). The only problem is that you need to re-implement |
Yep, we already have our own stat-like implementations for win32, we'd just have to add the nanoseconds to our One thing I'd be worried about implementing this on Windows is that Git for Windows does not fill these fields so if we do, we might never detect racy entries. |
INCLUDE(AddCFlagIfSupported) | ||
INCLUDE(FindPkgConfig) | ||
|
||
CHECK_STRUCT_HAS_MEMBER("struct stat" st_mtim.tv_nsec sys/stat.h | ||
HAVE_STRUCT_STAT_NSEC LANGUAGE C) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather see this check and the addition of the option after the main block, so we keep it uniform and at the beginning.
@carlosmn If msysgit can fill in the fields, then I think we're fine at detecting racily clean files. Anyway, I don't think it's bad to support it, with the caveat that if you're recompiling to change this option you ought to have some idea of what you're doing. I think these commits more or less do the job - although I don't have a Windows machine on hand to build, so I'll have to wait for AppVeyor. |
Rebased onto current master, to resolve merge conflicts. |
Is any additional work needed on this fix to get it merged? I believe this pull incorporates everything discussed so far, and is ready to go. |
The index also needs to know whether to consider the nanos in order to consider some entries racily-clean or not. Otherwise you're going to end up with many entries with zero nanos and then use that to compare against file info with filled nanos. |
This allows us to remove OS checks from source code, instead relying on CMake to detect whether or not `struct stat` has the nanoseconds members we rely on.
Sorry it took me so long to get this updated. I switched jobs, so I had to get my new employer's "ok" to continue working on this. I believe this pull is now ready to go, including the changes to account for racily clean file detection in the index code. The Travis failure seems to be due to some sort of networking problem on their OS X build servers. Let me know if more work is needed on this. Thanks! |
Sorry for the delay in reviewing this. Two questions:
These questions may be due to a misunderstanding in how git is computing differences for nsecs. My git (2.5.3, Windows) is not storing nsecs in the index. Would this not mean that my libgit2 would always see an index that git had written as dirty (mismatched nsecs)? |
As I understand these patches, the new USE_NSEC compile time option is disabled by default (as in upstream git).
Git for Windows 2.6.0 does store nsecs, but does not use them for comparisons (yet) [1].
Yes. I'm currently working on solutions for the same problem in upstream git [2]. [1] git-for-windows/git#443 |
No worries about the delay, thanks for taking the time to look at this. I'm pushed up some extra commits which resolve a merge conflict, and fix one spot where I was (incorrectly) not checking
I think the main argument for making it compile-time only is that switching the option back-and-forth at runtime makes it much more likely users will run into the various weird situations @kblees mentioned. Is there a real use-case where we would want to be able to toggle the option at runtime? I think ideally, in the future, all code interacting with Git repositories (Git itself, libgit2, and so on) will all deal with nanoseconds in some common way on all platforms, and we can get rid of this compile-time check.
The option is only available at all on platforms which support nanosecond-resolution file times, and on those platforms it is off by default. I think what we want to do (and this is what this patch does, currently) in libgit2, if the option is disabled, is:
Hopefully this addresses your questions. Let me know if I've missed anything. |
git_index_entry__init_from_stat: set nsec fields in entry stats
This is a potential fix for the bug noted in this issue.