git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Git force push fails after a rejected push (unpack failed)?

From
XHX 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.

Previous: X HNext: Johannes Sixt
Message 16 of 17 in “Git force push fails after a rejected push (unpack failed)?”
  1. X HJul 7, 2015
  2. Jeff KingJul 7, 2015
  3. Jeff KingJul 7, 2015
  4. Eric SunshineJul 7, 2015
  5. Johannes SixtJul 8, 2015
  6. Jeff KingJul 8, 2015
  7. check_and_freshen_file: fix reversed success-checkJeff King, Jul 8, 2015
  8. Junio C HamanoJul 8, 2015
  9. check_and_freshen_file: fix reversed success-checkJeff King, Jul 8, 2015
  10. Johannes SixtJul 8, 2015
  11. Johannes SixtJul 9, 2015
  12. Jeff KingJul 9, 2015
  13. X HJul 11, 2015
  14. Jeff KingJul 13, 2015
  15. X HJul 13, 2015
  16. X HJul 8, 2015
  17. Johannes SixtJul 8, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.