Re: Git force push fails after a rejected push (unpack failed)?
- From
- X H <music_is_live_lg@hotmail.com>
- Date
- Jul 8, 2015, 20:28 UTC
- Message-ID
- <BLU436-SMTP166B786EBE483D3F47F666F6910@phx.gbl>
- In-Reply-To
- <20150708180539.GA12353@peff.net>
Le 8/07/2015 20:05, Jeff King a écrit :
Show 66 quoted lines
> 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.