From: X H Date: Wed, 08 Jul 2015 20:28:51 GMT Subject: Re: Git force push fails after a rejected push (unpack failed)? Message-ID: In-Reply-To: <20150708180539.GA12353@peff.net> Le 8/07/2015 20:05, Jeff King a écrit : > On Wed, Jul 08, 2015 at 07:41:48PM +0200, Johannes Sixt wrote: > >>> Yes, but remember that git stores all of the objects for all of the >>> commits. So for some reason your push is perhaps trying to send an >>> object that the other side already has. Usually this does not happen >>> (the receiver says "I already have these commits, do not bother sending >>> their objects"), but it's possible that you have an object that is not >>> referenced by any commit, or a similar situation. It's hard to say >>> without looking at the repository. >> >> After a non-fast-forward push fails, a subsequent forced push sends the same >> set of objects, which are already present at the server side, but are >> dangling objects. >> >> Apparently, Git for Windows fails to replace the read-only files that live >> on the network file system. > > I left one bit out from my original explanation, which is that > we generally prefer existing objects to new ones. So we would generally > want to throw out the new object rather than try to write it out. I'm > not sure why unpack-objects would try to write an object we already > have. > > We also don't write objects directly, of course; we write to a temporary > file and try to link them into place. It really sounds more like the > "objects/d9" directory is where the permission problems are. But, hmm... > > The code path should be unpack-objects.c:write_object, which calls > sha1_file.cwrite_sha1_file, which then checks has_sha1_file(). These > days it uses the freshen_* functions instead of the latter, which does a > similar check. But it does report failure if we cannot call utime() on > the file, preferring to write it out instead (this is the safer choice > from a preventing-prune-corruption perspective). > > So it's possible that the sequence is: > > - unpack-objects tries to write object 1234abcd... > > - write_sha1_file calls freshen_loose_object > > - we call access("12/34abcd...", F_OK) and see that it does indeed > exist > > - we call utime("12/34abcd...") which fails (presumably due to EPERM); > we return failure and assume we must write out the object > > - write_sha1_file then writes to a temporary file, and tries to link > it into place. Now what? If we get EEXIST, we say "OK, somebody else > beat us here", and we consider that a success. But presumably we get > some other error here (which may even be a Windows-ism), fall back > to rename(), and that fails with EPERM, which we then report. > > If that's the case, then one solution is to have the > timestamp-freshening code silently report success, and skip writing out > the object. I'm not entirely comfortable with that, just because it is > loosening a safety mechanism. But perhaps we could loosen it _only_ in > the case of checking the loose object, and when we get EPERM. We know > that the next step is going to be writing out that same loose object, > which is almost certainly going to fail for the same reason. > > I dunno. The whole concept of trying to write to an object database for > which you do not have permissions seems a little bit weird. This would > definitely be a workaround. But I suspect it did work prior to v2.2.0. > > -Peff > I've made some tests: 1) Linux Mint: - ntfs share mounted (with noacl) since $ chacl -l /the/mountpoint gives chacl: cannot get access ACL on '/the/mountpoint': Operation not supported - Create a remote repository on the ntfs share - Push some test files - ls -al for files in the objects folder gives: -rw-r--r-- - with subsequent amend, push the permissions stays the same. 2) On Windows: - ntfs share mapped as drive by windows - remote repository created by git on windows - Push some test files - ls -al for files in the objects folder gives: -r--r--r-- - chmod all files to add w permission - then amend commit and push, push is successful but all files rewritten by the push are again: -r--r--r-- but all folders under objects are: drwxr-xr-x So I suppose it some issue with Windows or MSYS2. I'm not sure it's a problem related to your explanations, I will read it whit fresh mind.