{"thread":{"id":"61832","subject":"EXDEV when re-init with --separate-git-dir option","startedAt":"2024-07-24T02:47:31Z","lastAt":"2024-07-24T17:15:02Z","messageCount":3,"participants":["Jin, Di","Junio C Hamano","Eric Sunshine"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"499217","messageId":"CAKOkDnMGRfQoNygYLiAxPZB2q=VMYvw8kyu1dM=pM843-FH41Q@mail.gmail.com","threadId":"61832","inReplyTo":null,"subject":"EXDEV when re-init with --separate-git-dir option","fromName":"Jin, Di","fromEmail":"di_jin@brown.edu","sentAt":"2024-07-24T02:47:19Z","receivedAt":"2024-07-24T02:47:31Z","isPatch":false,"sender":{"key":"di_jin@brown.edu","avatar":null},"body":"Dear maintainers,\n\nWe discovered that re-init with option --separate-git-dir will throw\nan EXDEV when the target directory is not on the same file system as\nthe original directory.\n\nAn example is shown below:\n\n$ mkdir -p fs1/gitdir fs2\n$ ls\nfs1  fs2\n$ sudo mount -t tmpfs tmpfs fs2\n$ cd fs1/gitdir\n$ git init\nInitialized empty Git repository in /home/user/fs1/gitdir/.git/\n$ git init --separate-git-dir ../../fs2/surrealgitdir\nfatal: unable to move /home/user/fs1/gitdir/.git to\n/home/user/fs2/surrealgitdir: Invalid cross-device link\n\nWe tested this on version v2.45.2 and after reading the code a bit we\nbelieve the issue still exist in the master branch on github\n(https://github.com/git/git/blob/d19b6cd2dd72dc811f19df4b32c7ed223256c3ee/setup.c#L2280).\n\nBest regards,\nDi\n"},{"id":"499274","messageId":"xmqq1q3iztmi.fsf@gitster.g","threadId":"61832","inReplyTo":"CAKOkDnMGRfQoNygYLiAxPZB2q=VMYvw8kyu1dM=pM843-FH41Q@mail.gmail.com","subject":"Re: EXDEV when re-init with --separate-git-dir option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-07-24T15:39:49Z","receivedAt":"2024-07-24T15:39:52Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Jin, Di\" <di_jin@brown.edu> writes:\n\n> We discovered that re-init with option --separate-git-dir will throw\n> an EXDEV when the target directory is not on the same file system as\n> the original directory.\n\nYup, it is hitting the limitation of your filesystem.  The code\nwants to move the original .git directory together with its contents\nto a new place, and it makes a single rename() system call to do so.\nWhen the system cannot do so, you'd get the error message you are\nseeing (\"fatal: unable to move X to Y\").\n\nThe code path could probably borrow some code to recursively \"copy\"\ndirectory from the local \"git clone\" code path, and then invent a\nnew code to recursively remove the original \".git\", and trigger that\nnew code when rename() fails.\n\nBut at that point, only as a fall-back measure, it might be simpler\nand much less error prone to spawn a \"mv src dst\" as a subprocess\nusing the run_command() API.\n\nIt would make a good bite-sized #leftoverbits project for aspiring\nnew Git contributors.  Any takers?  ;-)\n\nThanks.\n\n"},{"id":"499288","messageId":"CAPig+cSJKA5+iU6TfRZev_b+ePLJ=wRm-8PLw3wKqJYEEonOVA@mail.gmail.com","threadId":"61832","inReplyTo":"xmqq1q3iztmi.fsf@gitster.g","subject":"Re: EXDEV when re-init with --separate-git-dir option","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2024-07-24T17:14:49Z","receivedAt":"2024-07-24T17:15:02Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Jul 24, 2024 at 11:40 AM Junio C Hamano <gitster@pobox.com> wrote:\n> \"Jin, Di\" <di_jin@brown.edu> writes:\n> > We discovered that re-init with option --separate-git-dir will throw\n> > an EXDEV when the target directory is not on the same file system as\n> > the original directory.\n>\n> Yup, it is hitting the limitation of your filesystem.  The code\n> wants to move the original .git directory together with its contents\n> to a new place, and it makes a single rename() system call to do so.\n> [...]\n> The code path could probably borrow some code to recursively \"copy\"\n> directory from the local \"git clone\" code path, and then invent a\n> new code to recursively remove the original \".git\", and trigger that\n> new code when rename() fails.\n\nRe-init with --separate-git-dir isn't the only problem spot. `git\nworktree move` also suffers the same problem for the same reason.\n\n> But at that point, only as a fall-back measure, it might be simpler\n> and much less error prone to spawn a \"mv src dst\" as a subprocess\n> using the run_command() API.\n\nThis wouldn't help Windows users.\n\n> It would make a good bite-sized #leftoverbits project for aspiring\n> new Git contributors.  Any takers?  ;-)\n\nIt might be a bit more than bite-sized, though, considering the above\npoints about `git worktree move` also needing such a fix, and having\nto deal with Microsoft Windows.\n"}]}